Merge remote-tracking branch 'upstream/master' into feature/poll-fds

This commit is contained in:
Gabriel Marin 2025-08-18 19:22:16 +03:00
commit 4c03b31b52
27 changed files with 1048 additions and 125 deletions

View file

@ -103,7 +103,12 @@ jobs:
- name: 'mbedtls valgrind'
install_packages: libnghttp2-dev libidn2-dev libldap-dev valgrind
install_steps: mbedtls
configure: LDFLAGS=-Wl,-rpath,/home/runner/mbedtls/lib --with-mbedtls=/home/runner/mbedtls --enable-debug
generate: >-
-DCURL_USE_MBEDTLS=ON -DENABLE_DEBUG=ON
-DMBEDTLS_INCLUDE_DIR=/home/runner/mbedtls/include
-DMBEDTLS_LIBRARY=/home/runner/mbedtls/lib/libmbedtls.a
-DMBEDX509_LIBRARY=/home/runner/mbedtls/lib/libmbedx509.a
-DMBEDCRYPTO_LIBRARY=/home/runner/mbedtls/lib/libmbedcrypto.a
- name: 'mbedtls clang'
install_packages: libnghttp2-dev libldap-dev clang
@ -145,7 +150,7 @@ jobs:
- name: 'openssl libssh2 sync-resolver valgrind'
install_packages: zlib1g-dev libidn2-dev libssh2-1-dev libnghttp2-dev libldap-dev valgrind
configure: --with-openssl --enable-debug --disable-threaded-resolver --with-libssh2
generate: -DENABLE_DEBUG=ON -DENABLE_THREADED_RESOLVER=OFF -DCURL_USE_LIBSSH2=ON
- name: 'openssl'
install_packages: zlib1g-dev
@ -160,7 +165,8 @@ jobs:
- name: 'openssl -O3 libssh valgrind'
install_packages: zlib1g-dev libssh-dev valgrind
configure: CFLAGS=-O3 --with-openssl --enable-debug --with-libssh
CFLAGS: -O3
generate: -DENABLE_DEBUG=ON -DCURL_USE_LIBSSH=ON
- name: 'openssl clang krb5 openldap static'
install_steps: openldap-static
@ -260,12 +266,12 @@ jobs:
- name: 'rustls valgrind'
install_packages: libnghttp2-dev libldap-dev valgrind
install_steps: rust rustls
configure: --with-rustls --enable-ech --enable-debug
generate: -DCURL_USE_RUSTLS=ON -DUSE_ECH=ON -DENABLE_DEBUG=ON
- name: 'rustls'
install_packages: libnghttp2-dev libldap-dev
install_steps: rust rustls skiprun pytest
generate: -DCURL_USE_RUSTLS=ON -DUSE_ECH=ON -DENABLE_DEBUG=ON
configure: --with-rustls --enable-ech --enable-debug
- name: 'IntelC openssl'
install_packages: zlib1g-dev libssl-dev
@ -700,7 +706,7 @@ jobs:
../.github/scripts/randcurl.pl 60 ../bld/src/curl
- name: 'build examples'
if: ${{ matrix.build.make-custom-target != 'tidy' }}
if: ${{ !contains(matrix.build.install_packages, 'valgrind') && matrix.build.make-custom-target != 'tidy' }}
run: |
if [ "${MATRIX_BUILD}" = 'cmake' ]; then
${MATRIX_MAKE_PREFIX} cmake --build bld --verbose --target curl-examples-build

View file

@ -248,7 +248,7 @@ jobs:
with:
persist-credentials: false
- name: 'autotools'
uses: vmactions/omnios-vm@8eba2a9217262f275d4566751a92d6ef2f433d00 # v1
uses: vmactions/omnios-vm@c31844c7abe722cd7c97df82cab1f1fab1e5339f # v1
with:
usesh: true
# https://pkg.omnios.org/r151052/core/en/index.shtml

View file

@ -551,7 +551,7 @@ jobs:
- name: 'curl version'
timeout-minutes: 1
run: |
PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.a' \) -exec file '{}' \;
/usr/bin/find . \( -name '*.exe' -o -name '*.dll' -o -name '*.a' \) -exec file '{}' \;
PATH="$PWD/bld/lib:$PATH"
bld/src/curl.exe --disable --version
@ -821,16 +821,58 @@ jobs:
[ -f "${MINGW_PREFIX}/include/zconf.h" ] && sed -i -E 's|(# +define +Z_HAVE_UNISTD_H)|/*\1*/|g' "${MINGW_PREFIX}/include/zconf.h" # Patch MSYS2 zconf.h for MSVC
for _chkprefill in '' ${MATRIX_CHKPREFILL}; do
options=''
cflags=''
rcflags=''
ldflags=''
if [ "${MATRIX_PLAT}" = 'uwp' ]; then
options+=' -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0'
cflags='-DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP'
ldflags='-OPT:NOREF -OPT:NOICF -APPCONTAINER:NO'
cflags+=' -DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP'
ldflags+=' -OPT:NOREF -OPT:NOICF -APPCONTAINER:NO'
vsglobals=';AppxPackage=false;WindowsAppContainer=false'
fi
[ "${MATRIX_ARCH}" = 'arm64' ] && options+=' -A ARM64'
[ "${MATRIX_ARCH}" = 'x64' ] && options+=' -A x64'
[ "${MATRIX_ARCH}" = 'x86' ] && options+=' -A Win32'
[ "${TFLAGS}" = 'skiprun' ] && options+=' -D_CURL_SKIP_BUILD_CERTS=ON'
if [ "${TFLAGS}" = 'skiprun' ]; then
[ "${MATRIX_ARCH}" = 'arm64' ] && options+=' -A ARM64'
[ "${MATRIX_ARCH}" = 'x64' ] && options+=' -A x64'
[ "${MATRIX_ARCH}" = 'x86' ] && options+=' -A Win32'
options+=" -DCMAKE_VS_GLOBALS=TrackFileAccess=false${vsglobals}"
options+=' -D_CURL_SKIP_BUILD_CERTS=ON'
unset CMAKE_GENERATOR
else
# Use Ninja when running tests to avoid MSBuild heuristics picking
# up "error messages" in the test log output and making the job fail.
# Officially this requires the vcvarsall.bat MS-DOS batch file (as of
# VS2022). Since it integrates badly with CI steps and shell scripts
# scripts, reproduce the necessary build configuration manually, and
# without envs.
[[ "$(uname -s)" = *'ARM64'* ]] && MSVC_HOST='arm64' || MSVC_HOST='x64' # x86
MSVC_ROOTD="$(cygpath --mixed --short-name "$PROGRAMFILES/Microsoft Visual Studio")" # to avoid spaces in directory names
MSVC_ROOTU="$(/usr/bin/find "$(cygpath --unix "$MSVC_ROOTD/2022/Enterprise/vc/tools/msvc")" -mindepth 1 -maxdepth 1 -type d -name '*.*' | sort | tail -n 1)"
MSVC_ROOTW="$(cygpath --mixed "$MSVC_ROOTU")"
MSVC_ROOTU="$(cygpath --unix "$MSVC_ROOTW")"
MSVC_BINU="$MSVC_ROOTU/bin/Host$MSVC_HOST/$MATRIX_ARCH"
MSDK_ROOTW="$(cygpath --mixed --short-name "$(printenv 'ProgramFiles(x86)')/Windows Kits")/10"
MSDK_ROOTU="$(cygpath --unix "$MSDK_ROOTW")"
MSDK_VER="$(basename "$(/usr/bin/find "$MSDK_ROOTU/lib" -mindepth 1 -maxdepth 1 -type d -name '*.*' | sort | tail -n 1)")"
MSDK_LIBW="$MSDK_ROOTW/lib/$MSDK_VER"
MSDK_INCW="$MSDK_ROOTW/include/$MSDK_VER"
MSDK_BINU="$MSDK_ROOTU/bin/$MSDK_VER/$MSVC_HOST"
cflags+=" -external:W0"
cflags+=" -external:I$MSVC_ROOTW/include"
cflags+=" -external:I$MSDK_INCW/shared"
cflags+=" -external:I$MSDK_INCW/ucrt"
cflags+=" -external:I$MSDK_INCW/um"
cflags+=" -external:I$MSDK_INCW/km"
rcflags+=" -I$MSDK_INCW/shared"
rcflags+=" -I$MSDK_INCW/um"
ldflags+=" -libpath:$MSVC_ROOTW/lib/$MATRIX_ARCH"
ldflags+=" -libpath:$MSDK_LIBW/ucrt/$MATRIX_ARCH"
ldflags+=" -libpath:$MSDK_LIBW/um/$MATRIX_ARCH"
ldflags+=" -libpath:$MSDK_LIBW/km/$MATRIX_ARCH"
options+=" -DCMAKE_RC_COMPILER=$MSDK_BINU/rc.exe"
options+=" -DCMAKE_MT=$MSDK_BINU/mt.exe"
options+=" -DCMAKE_C_COMPILER=$MSVC_BINU/cl.exe"
export CMAKE_GENERATOR='Ninja Multi-Config' # pass it via env to avoid space issues
fi
[ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF'
if [ -n "${MATRIX_INSTALL_VCPKG}" ]; then
options+=" -DCMAKE_TOOLCHAIN_FILE=$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
@ -840,9 +882,9 @@ jobs:
fi
cmake -B "bld${_chkprefill}" ${options} \
-DCMAKE_C_FLAGS="${cflags}" \
-DCMAKE_RC_FLAGS="${rcflags}" \
-DCMAKE_EXE_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
-DCMAKE_SHARED_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
-DCMAKE_VS_GLOBALS="TrackFileAccess=false${vsglobals}" \
-DCMAKE_UNITY_BUILD=ON \
-DCURL_WERROR=ON \
-DLIBPSL_INCLUDE_DIR="${MINGW_PREFIX}/include" \
@ -871,7 +913,7 @@ jobs:
- name: 'curl version'
timeout-minutes: 1
run: |
PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' -o -name '*.pdb' \) -exec file '{}' \;
/usr/bin/find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' -o -name '*.pdb' \) -exec file '{}' \;
if [ "${MATRIX_PLAT}" != 'uwp' ]; then # Missing: ucrtbased.dll, VCRUNTIME140D.dll, VCRUNTIME140D_APP.dll
PATH="$PWD/bld/lib/${MATRIX_TYPE}:$PATH"
"bld/src/${MATRIX_TYPE}/curl.exe" --disable --version

View file

@ -3,8 +3,8 @@ curl and libcurl 8.15.1
Public curl releases: 270
Command line options: 272
curl_easy_setopt() options: 308
Public functions in libcurl: 97
Contributors: 3486
Public functions in libcurl: 98
Contributors: 3490
This release includes the following changes:
@ -15,6 +15,7 @@ This release includes the following changes:
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 mbedtls: bump minimum version required to 3.2.0 [180]
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]
@ -22,6 +23,7 @@ This release includes the following changes:
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 websocket: support CURLOPT_READFUNCTION [193]
o writeout: add %time{} [74]
This release includes the following bugfixes:
@ -50,6 +52,7 @@ This release includes the following bugfixes:
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: improve error message for invalid HTTP/3 MultiSSL configs [187]
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]
@ -62,6 +65,8 @@ This release includes the following bugfixes:
o connectdata: remove primary+secondary ip_quadruple [126]
o connection: terminate after goaway [62]
o contrithanks: fix for BSD `sed` tool [98]
o cookie: don't treat the leading slash as trailing [185]
o cookie: remove expired cookies before listing [158]
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]
@ -84,6 +89,8 @@ This release includes the following bugfixes:
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 CURLOPT_HTTP_VERSION: mention new default value [179]
o CURLOPT_SSL_CTX_*: replace the base64 with XXXX [171]
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]
@ -94,6 +101,8 @@ This release includes the following bugfixes:
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 examples: remove base64 encoded chunks from examples [189]
o examples: remove href_extractor.c [186]
o gnutls: some small cleanups [41]
o hmac: return error if init fails [2]
o hostip: do DNS cache pruning in milliseconds [132]
@ -109,6 +118,7 @@ This release includes the following bugfixes:
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 mbedtls: check for feature macros instead of version [166]
o memanalyze: fix warnings [22]
o memory: make function overrides work reliably in unity builds [93]
o multi event: remove only announced [25]
@ -119,16 +129,21 @@ This release includes the following bugfixes:
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: auto-pause on verify callback retry [167]
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: save and restore OpenSSL error queue in two functions [172]
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 processhelp.pm: fix to use the correct null device on Windows [164]
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 resolving: dns error tracing [196]
o runtests: add `--ci` option, show `Env:` only when non-empty [134]
o runtests: assume `Time::HiRes`, drop Perl Win32 dependency [163]
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]
@ -139,6 +154,7 @@ This release includes the following bugfixes:
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 sendf: getting less data than "max allowed" is okay [170]
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]
@ -163,6 +179,7 @@ This release includes the following bugfixes:
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 TODO: remove session export item [194]
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]
@ -171,6 +188,7 @@ This release includes the following bugfixes:
o tool_urlglob: polish, cleanups, improvements [141]
o unit-tests: build the unitprotos.h from here [73]
o unit2604: avoid `UNCONST()` [135]
o URL-SYNTAX.md: drop link to codepoints.net to pass linkcheck [190]
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]
@ -210,16 +228,18 @@ advice from friends like these:
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,
Dan Fandrich, Daniel Böhmer, Daniel Engberg, Daniel Stenberg, David Zhuang,
devgs on github, Dominik Tomecki, Eshan Kelkar, Google Big Sleep,
Harry Sintonen, IoannisGS on github, Jelle Raaijmakers, Jeroen Ooms,
Kai Pastor, Karthik Das, kkmuffme on github, kupavcevdenis 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)
renovate[bot], rm-rmonaghan on github, Roberto Hidalgo, Samuel Henrique,
Schrijvers Luc, Sergio Durigan Junior, Stefan Eissing, Tal Regev,
Todd Gamblin, Viktor Szakats, Waldemar Kornewald, xfangfang, yaoy6 on github,
ウさん
(53 contributors)
References to bug reports and discussions on issues:
@ -379,17 +399,35 @@ References to bug reports and discussions on issues:
[154] = https://curl.se/bug/?i=18241
[155] = https://curl.se/bug/?i=18238
[156] = https://curl.se/bug/?i=18195
[158] = https://curl.se/bug/?i=18299
[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
[163] = https://curl.se/bug/?i=18287
[164] = https://curl.se/bug/?i=18282
[165] = https://curl.se/bug/?i=18124
[166] = https://curl.se/bug/?i=18271
[167] = https://curl.se/mail/lib-2025-08/0012.html
[168] = https://curl.se/bug/?i=18170
[169] = https://curl.se/bug/?i=18171
[170] = https://curl.se/bug/?i=18283
[171] = https://curl.se/bug/?i=18261
[172] = https://curl.se/bug/?i=18190
[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
[179] = https://curl.se/bug/?i=18272
[180] = https://curl.se/bug/?i=18254
[183] = https://curl.se/bug/?i=18208
[184] = https://curl.se/bug/?i=18206
[185] = https://curl.se/bug/?i=18266
[186] = https://curl.se/bug/?i=18264
[187] = https://curl.se/bug/?i=18246
[189] = https://curl.se/bug/?i=18260
[190] = https://curl.se/bug/?i=18259
[193] = https://curl.se/bug/?i=17683
[194] = https://curl.se/bug/?i=18243
[196] = https://curl.se/bug/?i=18247

View file

@ -49,22 +49,22 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
/* replace the XXX with the actual CA certificates */
static const char mypem[] =
"-----BEGIN CERTIFICATE-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"-----END CERTIFICATE-----\n"
"-----BEGIN CERTIFICATE-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\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));

View file

@ -61,36 +61,36 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
const char *mypem =
/* replace the XXX with the actual CA certificate */
"-----BEGIN CERTIFICATE-----\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"-----BEGIN CERTIFICATE-----\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 */
const char *mykey =
"-----BEGIN RSA PRIVATE KEY-----\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"-----BEGIN RSA PRIVATE KEY-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"-----END RSA PRIVATE KEY-----\n";
(void)curl; /* avoid warnings */

View file

@ -83,15 +83,14 @@ int main(void)
{
CURL *ch;
CURLcode rv;
char *mypem = /* example CA cert PEM - shortened */
char *mypem = /* CA cert in PEM format, replace the XXXs */
"-----BEGIN CERTIFICATE-----\n"
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"
"IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"
"Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"
"GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"
"zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"-----END CERTIFICATE-----\n";
curl_global_init(CURL_GLOBAL_ALL);

View file

@ -60,7 +60,9 @@ callbacks to add additional validation code for certificates, and even to
change the actual URI of an HTTPS request.
For OpenSSL, asynchronous certificate verification via *SSL_set_retry_verify*
is supported. (Added in 8.3.0)
is supported. When *SSL_set_retry_verify* is set, the transfer is paused.
When verification should continue, call curl_easy_pause(3) to unpause
the transfer. (Added in 8.3.0, Pausing added in 8.16.0)
The CURLOPT_SSL_CTX_FUNCTION(3) callback allows the application to reach in
and modify SSL details in the connection without libcurl itself knowing
@ -134,15 +136,14 @@ int main(void)
{
CURL *ch;
CURLcode rv;
char *mypem = /* example CA cert PEM - shortened */
char *mypem = /* CA cert in PEM format, replace the XXXs */
"-----BEGIN CERTIFICATE-----\n"
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"
"IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"
"Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"
"GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"
"zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"-----END CERTIFICATE-----\n";
curl_global_init(CURL_GLOBAL_ALL);

View file

@ -655,12 +655,9 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
return result;
#ifndef CURL_DISABLE_SOCKETPAIR
if(thrdd->addr) {
/* return read fd to client for polling the DNS resolution status */
result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]);
}
else
#endif
/* return read fd to client for polling the DNS resolution status */
result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]);
#else
{
timediff_t milli;
timediff_t ms = curlx_timediff(curlx_now(), thrdd->addr->start);
@ -674,7 +671,7 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
milli = 200;
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
}
#endif
return result;
}

View file

@ -537,7 +537,8 @@ CURLcode Curl_bufq_write_pass(struct bufq *q,
if(result != CURLE_AGAIN)
/* real error, fail */
return result;
if((result == CURLE_AGAIN) && *pwritten)
/* result == CURLE_AGAIN */
if(*pwritten)
/* we did write successfully before */
result = CURLE_OK;
return result;

View file

@ -1615,6 +1615,9 @@ static struct curl_slist *cookie_list(struct Curl_easy *data)
if(!data->cookies || (data->cookies->numcookies == 0))
return NULL;
/* at first, remove expired cookies */
remove_expired(data->cookies);
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
for(n = Curl_llist_head(&data->cookies->cookielist[i]); n;
n = Curl_node_next(n)) {

View file

@ -1256,7 +1256,7 @@ out:
!Curl_conn_is_ssl(conn, SECONDARYSOCKET)) {
result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET);
}
data->conn->bits.do_more = FALSE;
conn->bits.do_more = FALSE;
Curl_pgrsTime(data, TIMER_STARTACCEPT);
Curl_expire(data, (data->set.accepttimeout > 0) ?
data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT,

View file

@ -1026,9 +1026,13 @@ CURLMcode Curl_multi_pollset(struct Curl_easy *data,
case MSTATE_CONNECTING:
case MSTATE_TUNNELING:
result = mstate_connecting_pollset(data, ps);
if(!result)
result = Curl_conn_adjust_pollset(data, data->conn, ps);
if(!Curl_xfer_recv_is_paused(data)) {
result = mstate_connecting_pollset(data, ps);
if(!result)
result = Curl_conn_adjust_pollset(data, data->conn, ps);
}
else
expect_sockets = FALSE;
break;
case MSTATE_PROTOCONNECT:
@ -2434,22 +2438,24 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case MSTATE_CONNECTING:
/* awaiting a completion of an asynch TCP connect */
DEBUGASSERT(data->conn);
result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
if(connected && !result) {
if(!data->conn->bits.reuse &&
Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
/* new connection, can multiplex, wake pending handles */
process_pending_handles(data->multi);
if(!Curl_xfer_recv_is_paused(data)) {
result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &connected);
if(connected && !result) {
if(!data->conn->bits.reuse &&
Curl_conn_is_multiplex(data->conn, FIRSTSOCKET)) {
/* new connection, can multiplex, wake pending handles */
process_pending_handles(data->multi);
}
rc = CURLM_CALL_MULTI_PERFORM;
multistate(data, MSTATE_PROTOCONNECT);
}
else if(result) {
/* failure detected */
multi_posttransfer(data);
multi_done(data, result, TRUE);
stream_error = TRUE;
break;
}
rc = CURLM_CALL_MULTI_PERFORM;
multistate(data, MSTATE_PROTOCONNECT);
}
else if(result) {
/* failure detected */
multi_posttransfer(data);
multi_done(data, result, TRUE);
stream_error = TRUE;
break;
}
break;

View file

@ -293,9 +293,9 @@ static CURLcode cw_download_write(struct Curl_easy *data,
}
if((type & CLIENTWRITE_EOS) && !data->req.no_body &&
(data->req.maxdownload > data->req.bytecount)) {
(data->req.size > data->req.bytecount)) {
failf(data, "end of response with %" FMT_OFF_T " bytes missing",
data->req.maxdownload - data->req.bytecount);
data->req.size - data->req.bytecount);
return CURLE_PARTIAL_FILE;
}
}

View file

@ -1212,7 +1212,7 @@ static CURLcode init_ngh3_conn(struct Curl_cfilter *cf,
rc = nghttp3_conn_client_new(&ctx->h3conn,
&ngh3_callbacks,
&ctx->h3settings,
nghttp3_mem_default(),
Curl_nghttp3_mem(),
cf);
if(rc) {
failf(data, "error creating nghttp3 connection instance");
@ -2475,7 +2475,7 @@ static const struct alpn_spec ALPN_SPEC_H3 = {
&ctx->connected_path,
NGTCP2_PROTO_VER_V1, &ng_callbacks,
&ctx->settings, &ctx->transport_params,
NULL, cf);
Curl_ngtcp2_mem(), cf);
if(rc)
return CURLE_QUIC_CONNECT_ERROR;

View file

@ -1106,7 +1106,7 @@ static CURLcode cf_osslq_h3conn_init(struct cf_osslq_ctx *ctx, SSL *conn,
rc = nghttp3_conn_client_new(&h3->conn,
&ngh3_callbacks,
&h3->settings,
nghttp3_mem_default(),
Curl_nghttp3_mem(),
user_data);
if(rc) {
result = CURLE_OUT_OF_MEMORY;

View file

@ -724,6 +724,62 @@ CURLcode Curl_conn_may_http3(struct Curl_easy *data,
return CURLE_OK;
}
#if defined(USE_NGTCP2) || defined(USE_NGHTTP3)
static void *Curl_ngtcp2_malloc(size_t size, void *user_data)
{
(void)user_data;
return Curl_cmalloc(size);
}
static void Curl_ngtcp2_free(void *ptr, void *user_data)
{
(void)user_data;
Curl_cfree(ptr);
}
static void *Curl_ngtcp2_calloc(size_t nmemb, size_t size, void *user_data)
{
(void)user_data;
return Curl_ccalloc(nmemb, size);
}
static void *Curl_ngtcp2_realloc(void *ptr, size_t size, void *user_data)
{
(void)user_data;
return Curl_crealloc(ptr, size);
}
#ifdef USE_NGTCP2
static struct ngtcp2_mem curl_ngtcp2_mem = {
NULL,
Curl_ngtcp2_malloc,
Curl_ngtcp2_free,
Curl_ngtcp2_calloc,
Curl_ngtcp2_realloc
};
struct ngtcp2_mem *Curl_ngtcp2_mem(void)
{
return &curl_ngtcp2_mem;
}
#endif
#ifdef USE_NGHTTP3
static struct nghttp3_mem curl_nghttp3_mem = {
NULL,
Curl_ngtcp2_malloc,
Curl_ngtcp2_free,
Curl_ngtcp2_calloc,
Curl_ngtcp2_realloc
};
struct nghttp3_mem *Curl_nghttp3_mem(void)
{
return &curl_nghttp3_mem;
}
#endif
#endif /* USE_NGTCP2 || USE_NGHTTP3 */
#else /* CURL_DISABLE_HTTP || !USE_HTTP3 */
CURLcode Curl_conn_may_http3(struct Curl_easy *data,

View file

@ -91,4 +91,13 @@ CURLcode vquic_recv_packets(struct Curl_cfilter *cf,
#endif /* !USE_HTTP3 */
#ifdef USE_NGTCP2
struct ngtcp2_mem;
struct ngtcp2_mem *Curl_ngtcp2_mem(void);
#endif
#ifdef USE_NGHTTP3
struct nghttp3_mem;
struct nghttp3_mem *Curl_nghttp3_mem(void);
#endif
#endif /* HEADER_CURL_VQUIC_QUIC_INT_H */

View file

@ -61,6 +61,7 @@
#include "../vauth/vauth.h"
#include "keylog.h"
#include "hostcheck.h"
#include "../transfer.h"
#include "../multiif.h"
#include "../curlx/strparse.h"
#include "../strdup.h"
@ -4602,7 +4603,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
#ifdef SSL_ERROR_WANT_RETRY_VERIFY
if(SSL_ERROR_WANT_RETRY_VERIFY == detail) {
CURL_TRC_CF(data, cf, "SSL_connect() -> want retry_verify");
connssl->io_need = CURL_SSL_IO_NEED_RECV;
Curl_xfer_pause_recv(data, TRUE);
return CURLE_AGAIN;
}
#endif

View file

@ -104,6 +104,7 @@ if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Cl
if(APPLE AND CMAKE_OSX_SYSROOT)
string(APPEND CURL_CPP " -isysroot ${CMAKE_OSX_SYSROOT}")
endif()
string(APPEND CURL_CPP " ${CMAKE_C_FLAGS}")
# Add header directories, like autotools builds do.
get_property(_include_dirs TARGET ${LIB_SELECTED} PROPERTY INCLUDE_DIRECTORIES)
foreach(_include_dir IN LISTS _include_dirs)

View file

@ -108,7 +108,7 @@ test718 test719 test720 test721 test722 test723 test724 test725 test726 \
test727 test728 test729 test730 test731 test732 test733 test734 test735 \
test736 test737 test738 test739 test740 test741 test742 test743 test744 \
test745 test746 test747 test748 test749 test750 test751 test752 test753 \
test754 test755 test756 test757 \
test754 test755 test756 test757 test758 \
test780 test781 test782 test783 test784 test785 test786 test787 test788 \
test789 test790 test791 test792 test793 test794 test796 test797 \
\
@ -203,11 +203,11 @@ test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \
test1524 test1525 test1526 test1527 test1528 test1529 test1530 test1531 \
test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 \
test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 \
test1548 \
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
test1566 test1567 test1568 test1569 test1570 test1571 test1572 test1573 \
test1574 test1575 test1576 test1577 test1578 test1579 test1580 test1581 \
test1548 test1549 test1550 test1551 test1552 test1553 test1554 test1555 \
test1556 test1557 test1558 test1559 test1560 test1561 test1562 test1563 \
test1564 test1565 test1566 test1567 test1568 test1569 test1570 test1571 \
test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 \
test1580 test1581 \
\
test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 \
test1598 test1599 test1600 test1601 test1602 test1603 test1604 test1605 \
@ -256,8 +256,8 @@ test2100 test2101 test2102 test2103 test2104 \
\
test2200 test2201 test2202 test2203 test2204 test2205 \
\
test2300 test2301 test2302 test2303 test2304 test2306 \
test2308 test2309 \
test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 \
test2309 \
\
test2400 test2401 test2402 test2403 test2404 test2405 test2406 \
\

59
tests/data/test1549 Normal file
View file

@ -0,0 +1,59 @@
<testcase>
<info>
<keywords>
HTTP
cookies
</keywords>
</info>
#
# Server-side
<reply>
<data crlf="yes">
HTTP/1.1 200 OK
Content-Length: 6
Content-Type: text/plain
Set-Cookie: c1=123; Path=/; Expires=Thu, 12 Feb 2000 00:00:00 GMT
Set-Cookie: c2=456; Path=/; Expires=Thu, 12 Feb 2000 00:00:00 GMT;
hello
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
http
cookies
</features>
<name>
Receive expired cookies and CURLINFO_COOKIELIST
</name>
<tool>
lib%TESTNUMBER
</tool>
<command>
http://%HOSTIP:%HTTPPORT/%TESTNUMBER
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol crlf="yes">
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
</protocol>
<stderr mode="text">
URL: http://%HOSTIP:%HTTPPORT/%TESTNUMBER
0 cookies
Test ended with result 0
</stderr>
</verify>
</testcase>

60
tests/data/test2307 Normal file
View file

@ -0,0 +1,60 @@
<testcase>
<info>
<keywords>
FTP
EPSV
RETR
Range
</keywords>
</info>
# Server-side
<reply>
<data>
0123456789abcdef
0123456789abcdef
0123456789abcdef
0123456789abcdef
</data>
<datacheck nonewline="yes">
0123456789abcdef
0123456789abcdef
0123456789abcdef
012345678
</datacheck>
<size>
64
</size>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<name>
FTP retrieve a byte-range with end larger than file
</name>
<command>
-r 4-1000 ftp://%HOSTIP:%FTPPORT/%TESTNUMBER
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<strip>
QUIT
</strip>
<protocol crlf="yes">
USER anonymous
PASS ftp@example.com
PWD
EPSV
TYPE I
SIZE %TESTNUMBER
REST 4
RETR %TESTNUMBER
ABOR
QUIT
</protocol>
</verify>
</testcase>

53
tests/data/test758 Normal file
View file

@ -0,0 +1,53 @@
<testcase>
<info>
<keywords>
multi
HTTPS
</keywords>
</info>
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6007
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
%repeat[1000 x foobar]%
</data>
</reply>
<features>
OpenSSL
</features>
# Client-side
<client>
<server>
https
</server>
<tool>
lib%TESTNUMBER
</tool>
<name>
multi_socket interface transfer with callbacks returning error
</name>
<command>
https://localhost:%HTTPSPORT/file%TESTNUMBER
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol>
</protocol>
</verify>
</testcase>

View file

@ -71,7 +71,7 @@ TESTS_C = \
lib661.c lib666.c lib667.c lib668.c \
lib670.c lib674.c lib676.c lib677.c lib678.c \
lib694.c lib695.c \
lib751.c lib753.c \
lib751.c lib753.c lib758.c \
lib757.c \
lib1156.c \
lib1301.c lib1308.c \
@ -82,7 +82,7 @@ TESTS_C = \
lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c \
lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c \
lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c \
lib1545.c lib1550.c lib1551.c \
lib1545.c lib1549.c lib1550.c lib1551.c \
lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c \
lib1559.c lib1560.c lib1564.c lib1565.c \
lib1567.c lib1568.c lib1569.c lib1571.c \

76
tests/libtest/lib1549.c Normal file
View file

@ -0,0 +1,76 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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 test_lib1549(const char *URL)
{
CURLcode res;
CURL *curl;
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");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
test_setopt(curl, CURLOPT_URL, URL);
test_setopt(curl, CURLOPT_HEADER, 1L);
test_setopt(curl, CURLOPT_COOKIEFILE, "");
res = curl_easy_perform(curl);
if(!res) {
/* extract all known cookies */
struct curl_slist *cookies = NULL;
int num = 0;
res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
if(!res && cookies) {
/* a linked list of cookies in cookie file format */
struct curl_slist *each = cookies;
while(each) {
printf("%s\n", each->data);
each = each->next;
num++;
}
/* we must free these cookies when we are done */
curl_slist_free_all(cookies);
}
fprintf(stderr, "%d cookies\n", num);
}
test_cleanup:
curl_easy_cleanup(curl);
curl_global_cleanup();
return res;
}

515
tests/libtest/lib758.c Normal file
View file

@ -0,0 +1,515 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
/*
* The purpose of this test is to make sure that if CURLMOPT_SOCKETFUNCTION or
* CURLMOPT_TIMERFUNCTION returns error, the associated transfer should be
* aborted correctly.
*/
#include "first.h"
#include "testtrace.h"
#include "memdebug.h"
#ifdef USE_OPENSSL
#include <openssl/x509.h>
#include <openssl/ssl.h>
#if ((OPENSSL_VERSION_NUMBER >= 0x30000000L) && \
!defined(LIBRESSL_VERSION_NUMBER) && \
!defined(OPENSSL_IS_BORINGSSL))
#define T578_ENABLED
#endif
#endif
#ifdef T578_ENABLED
static struct t758_ctx {
int socket_calls;
int max_socket_calls;
int timer_calls;
int max_timer_calls;
int fake_async_cert_verification_pending;
int fake_async_cert_verification_finished;
int number_of_cert_verify_callbacks;
char buf[1024];
} t758_ctx;
static const char *t758_tag(void)
{
curl_msnprintf(t758_ctx.buf, sizeof(t758_ctx.buf),
"[T758-%d-%d] [%d/%d]",
t758_ctx.max_socket_calls, t758_ctx.max_timer_calls,
t758_ctx.socket_calls, t758_ctx.timer_calls);
return t758_ctx.buf;
}
static void t758_msg(const char *msg)
{
curl_mfprintf(stderr, "%s %s\n", t758_tag(), msg);
}
struct t758_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 t758_ReadWriteSockets {
struct t758_Sockets read, write;
};
/**
* Remove a file descriptor from a sockets array.
*/
static void t758_removeFd(struct t758_Sockets *sockets, curl_socket_t fd,
int mention)
{
int i;
if(mention)
curl_mfprintf(stderr, "%s remove socket fd %" FMT_SOCKET_T "\n",
t758_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)));
--sockets->count;
}
}
}
/**
* Add a file descriptor to a sockets array.
* Return 0 on success, 1 on error.
*/
static int t758_addFd(struct t758_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, "%s add socket fd %" FMT_SOCKET_T " for %s\n",
t758_tag(), fd, what);
t758_removeFd(sockets, fd, 0);
/*
* Allocate array storage when required.
*/
if(!sockets->sockets) {
sockets->sockets = malloc(sizeof(curl_socket_t) * 20U);
if(!sockets->sockets)
return 1;
sockets->max_count = 20;
}
else if(sockets->count + 1 > sockets->max_count) {
curl_socket_t *ptr = realloc(sockets->sockets, sizeof(curl_socket_t) *
(sockets->max_count + 20));
if(!ptr)
/* cleanup in test_cleanup */
return 1;
sockets->sockets = ptr;
sockets->max_count += 20;
}
/*
* Add file descriptor to array.
*/
sockets->sockets[sockets->count] = fd;
++sockets->count;
return 0;
}
/**
* Callback invoked by curl to poll reading / writing of a socket.
*/
static int t758_curlSocketCallback(CURL *easy, curl_socket_t s, int action,
void *userp, void *socketp)
{
struct t758_ReadWriteSockets *sockets = userp;
(void)easy;
(void)socketp;
t758_ctx.socket_calls++;
t758_msg("-> CURLMOPT_SOCKETFUNCTION");
if(t758_ctx.socket_calls == t758_ctx.max_socket_calls) {
t758_msg("<- CURLMOPT_SOCKETFUNCTION returns error");
return -1;
}
if(action == CURL_POLL_IN || action == CURL_POLL_INOUT)
if(t758_addFd(&sockets->read, s, "read"))
return -1; /* bail out */
if(action == CURL_POLL_OUT || action == CURL_POLL_INOUT)
if(t758_addFd(&sockets->write, s, "write"))
return -1;
if(action == CURL_POLL_REMOVE) {
t758_removeFd(&sockets->read, s, 1);
t758_removeFd(&sockets->write, s, 0);
}
return 0;
}
/**
* Callback invoked by curl to set a timeout.
*/
static int t758_curlTimerCallback(CURLM *multi, long timeout_ms, void *userp)
{
struct curltime *timeout = userp;
(void)multi; /* unused */
t758_ctx.timer_calls++;
t758_msg("-> CURLMOPT_TIMERFUNCTION");
if(t758_ctx.timer_calls == t758_ctx.max_timer_calls) {
t758_msg("<- CURLMOPT_TIMERFUNCTION returns error");
return -1;
}
if(timeout_ms != -1) {
*timeout = curlx_now();
timeout->tv_usec += (int)timeout_ms * 1000;
}
else {
timeout->tv_sec = -1;
}
return 0;
}
static int t758_cert_verify_callback(X509_STORE_CTX *ctx, void *arg)
{
SSL * ssl;
(void)arg; /* unused */
ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx,
SSL_get_ex_data_X509_STORE_CTX_idx());
t758_ctx.number_of_cert_verify_callbacks++;
if(!t758_ctx.fake_async_cert_verification_pending) {
t758_ctx.fake_async_cert_verification_pending = 1;
t758_msg(" initial t758_cert_verify_callback");
return SSL_set_retry_verify(ssl);
}
else if(t758_ctx.fake_async_cert_verification_finished) {
t758_msg(" final t758_cert_verify_callback");
return 1; /* success */
}
else {
t758_msg(" pending t758_cert_verify_callback");
return SSL_set_retry_verify(ssl);
}
}
static CURLcode
t758_set_ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *clientp)
{
SSL_CTX *ctx = (SSL_CTX *) ssl_ctx;
(void)curl; /* unused */
SSL_CTX_set_cert_verify_callback(ctx, t758_cert_verify_callback, clientp);
return CURLE_OK;
}
/**
* Check for curl completion.
*/
static int t758_checkForCompletion(CURLM *curl, int *success)
{
int result = 0;
*success = 0;
while(1) {
int numMessages;
CURLMsg *message = curl_multi_info_read(curl, &numMessages);
if(!message)
break;
if(message->msg == CURLMSG_DONE) {
result = 1;
if(message->data.result == CURLE_OK)
*success = 1;
else
*success = 0;
}
else {
curl_mfprintf(stderr, "%s got an unexpected message from curl: %i\n",
t758_tag(), message->msg);
result = 1;
*success = 0;
}
}
return result;
}
static ssize_t t758_getMicroSecondTimeout(struct curltime *timeout)
{
struct curltime now;
ssize_t result;
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 result;
}
/**
* Update a fd_set with all of the sockets in use.
*/
static void t758_updateFdSet(struct t758_Sockets *sockets, fd_set* fdset,
curl_socket_t *maxFd)
{
int i;
for(i = 0; i < sockets->count; ++i) {
#ifdef __DJGPP__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warith-conversion"
#endif
FD_SET(sockets->sockets[i], fdset);
#ifdef __DJGPP__
#pragma GCC diagnostic pop
#endif
if(*maxFd < sockets->sockets[i] + 1) {
*maxFd = sockets->sockets[i] + 1;
}
}
}
static CURLMcode t758_saction(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, "%s Curl error on %s (%i) %s\n",
t758_tag(), info, result, curl_multi_strerror(result));
}
return result;
}
/**
* Invoke curl when a file descriptor is set.
*/
static CURLMcode t758_checkFdSet(CURLM *curl, struct t758_Sockets *sockets,
fd_set *fdset, int evBitmask,
const char *name)
{
int i;
CURLMcode result = CURLM_OK;
for(i = 0; i < sockets->count; ++i) {
if(FD_ISSET(sockets->sockets[i], fdset)) {
result = t758_saction(curl, sockets->sockets[i], evBitmask, name);
if(result)
break;
}
}
return result;
}
static CURLcode t758_one(const char *URL, int timer_fail_at,
int socket_fail_at)
{
CURLcode res = CURLE_OK;
CURL *curl = NULL; CURLM *m = NULL;
struct t758_ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}};
int success = 0;
struct curltime timeout = {0};
timeout.tv_sec = (time_t)-1;
/* set the limits */
memset(&t758_ctx, 0, sizeof(t758_ctx));
t758_ctx.max_timer_calls = timer_fail_at;
t758_ctx.max_socket_calls = socket_fail_at;
t758_msg("start");
start_test_timing();
if(curl_global_sslset(CURLSSLBACKEND_OPENSSL, NULL, NULL) != CURLSSLSET_OK) {
t758_msg("could not set OpenSSL as backend");
res = CURLE_FAILED_INIT;
return res;
}
res_global_init(CURL_GLOBAL_ALL);
if(res != CURLE_OK)
return res;
curl_global_trace("all");
easy_init(curl);
debug_config.nohex = TRUE;
debug_config.tracetime = TRUE;
test_setopt(curl, CURLOPT_DEBUGDATA, &debug_config);
easy_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* specify target */
easy_setopt(curl, CURLOPT_URL, URL);
/* go verbose */
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, t758_set_ssl_ctx_callback);
multi_init(m);
multi_setopt(m, CURLMOPT_SOCKETFUNCTION, t758_curlSocketCallback);
multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets);
multi_setopt(m, CURLMOPT_TIMERFUNCTION, t758_curlTimerCallback);
multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
multi_add_handle(m, curl);
if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) {
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
while(!t758_checkForCompletion(m, &success)) {
fd_set readSet, writeSet;
curl_socket_t maxFd = 0;
struct timeval tv = {0};
tv.tv_sec = 10;
if(t758_ctx.fake_async_cert_verification_pending &&
!t758_ctx.fake_async_cert_verification_finished) {
if(sockets.read.count || sockets.write.count) {
t758_msg("during verification there should be no sockets scheduled");
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
if(t758_ctx.number_of_cert_verify_callbacks != 1) {
t758_msg("expecting exactly one cert verify callback here");
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
t758_ctx.fake_async_cert_verification_finished = 1;
if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) {
t758_msg("spurious retry cert action");
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
curl_easy_pause(curl, CURLPAUSE_CONT);
if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) {
t758_msg("unblocking transfer after cert verification finished");
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
if(t758_ctx.number_of_cert_verify_callbacks != 2) {
t758_msg("this should have triggered the callback again, right?");
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
t758_msg("TEST: all fine?");
}
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
t758_updateFdSet(&sockets.read, &readSet, &maxFd);
t758_updateFdSet(&sockets.write, &writeSet, &maxFd);
if(timeout.tv_sec != (time_t)-1) {
int usTimeout = curlx_sztosi(t758_getMicroSecondTimeout(&timeout));
tv.tv_sec = usTimeout / 1000000;
tv.tv_usec = usTimeout % 1000000;
}
else if(maxFd <= 0) {
tv.tv_sec = 0;
tv.tv_usec = 100000;
}
select_test((int)maxFd, &readSet, &writeSet, NULL, &tv);
/* Check the sockets for reading / writing */
if(t758_checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN,
"read")) {
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
if(t758_checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT,
"write")) {
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
if(timeout.tv_sec != (time_t)-1 &&
t758_getMicroSecondTimeout(&timeout) == 0) {
/* Curl's timer has elapsed. */
if(t758_saction(m, CURL_SOCKET_TIMEOUT, 0, "timeout")) {
res = TEST_ERR_BAD_TIMEOUT;
goto test_cleanup;
}
}
abort_on_test_timeout();
}
if(success && t758_ctx.number_of_cert_verify_callbacks != 2) {
t758_msg("unexpected invocations of cert verify callback");
res = TEST_ERR_MAJOR_BAD;
goto test_cleanup;
}
if(!success) {
t758_msg("Error getting file.");
res = TEST_ERR_MAJOR_BAD;
}
test_cleanup:
/* proper cleanup sequence */
t758_msg("cleanup");
curl_multi_remove_handle(m, curl);
curl_easy_cleanup(curl);
curl_multi_cleanup(m);
curl_global_cleanup();
/* free local memory */
free(sockets.read.sockets);
free(sockets.write.sockets);
t758_msg("done");
return res;
}
static CURLcode test_lib758(const char *URL)
{
CURLcode rc;
/* rerun the same transfer multiple times and make it fail in different
callback calls */
rc = t758_one(URL, 0, 0); /* no callback fails */
if(rc)
curl_mfprintf(stderr, "%s FAILED: %d\n", t758_tag(), rc);
return rc;
}
#else /* T578_ENABLED */
static CURLcode test_lib758(const char *URL)
{
(void)URL;
return CURLE_OK;
}
#endif