diff --git a/.github/labeler.yml b/.github/labeler.yml index 31198b476..be585a690 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -7,17 +7,17 @@ # triaging, but is intended to add labels to the easy cases. If the matching # language becomes more powerful, more cases should be able to be handled. # -# Labels are added in two ways: the AnyGlobToAllFiles ones are added if all the -# files fit into the category, and the AnyGlobToAnyFile ones are added as long -# as any file matches. The first ones are for "major" categories (the PR is all -# about that one topic, like HTTP/3), while the second ones are "addendums" -# that give useful information about a PR that's really mostly something else -# (e.g. CI if the PR also touches CI jobs). +# Labels are added in two ways: the any-glob-to-all-files ones are added if all +# the files fit into the category, and the any-glob-to-any-file ones are added +# as long as any file matches. The first ones are for "major" categories (the +# PR is all about that one topic, like HTTP/3), while the second ones are +# "addendums" that give useful information about a PR that's really mostly +# something else (e.g. CI if the PR also touches CI jobs). appleOS: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '.github/workflows/macos.yml' - 'lib/config-mac.h' - 'lib/macos*' @@ -28,7 +28,7 @@ appleOS: authentication: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/mk-ca-bundle.1' - 'docs/libcurl/opts/CURLINFO_HTTPAUTH*' - 'docs/libcurl/opts/CURLINFO_PROXYAUTH*' @@ -51,7 +51,7 @@ authentication: build: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '**/CMakeLists.txt' - '**/Makefile.am' - '**/Makefile.inc' @@ -77,7 +77,7 @@ build: CI: - all: - changed-files: - - AnyGlobToAnyFile: + - any-glob-to-any-file: - '.azure-pipelines.yml' - '.circleci/**' - '.cirrus.yml' @@ -91,7 +91,7 @@ CI: cmake: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '**/CMakeLists.txt' - 'CMake/**' - 'docs/INSTALL.cmake' @@ -100,14 +100,14 @@ cmake: cmdline tool: - all: - changed-files: - - AnyGlobToAnyFile: + - any-glob-to-any-file: - 'docs/cmdline-opts/**' - 'src/**' connecting & proxies: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/CONNECTION-FILTERS.md' - 'docs/examples/ipv6.c' - 'docs/libcurl/opts/CURLINFO_CONNECT*' @@ -136,7 +136,7 @@ connecting & proxies: cookies: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/HTTP-COOKIES.md' - 'docs/cmdline-opts/cookie*' - 'docs/cmdline-opts/junk-session-cookies.d' @@ -149,7 +149,7 @@ cookies: cryptography: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/CIPHERS.md' - 'docs/RUSTLS.md' - 'docs/libcurl/opts/CURLOPT_EGDSOCKET*' @@ -163,14 +163,14 @@ cryptography: DICT: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/dict.*' - 'tests/dictserver.py' documentation: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '**/*.md' - '**/*.txt' - '**/*.1' @@ -189,7 +189,7 @@ documentation: FTP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/libcurl/opts/CURLINFO_FTP*' - 'docs/libcurl/opts/CURLOPT_FTP*' - 'docs/libcurl/opts/CURLOPT_WILDCARDMATCH*' @@ -202,13 +202,13 @@ FTP: GOPHER: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/gopher*' HTTP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/examples/hsts*' - 'docs/examples/http-*' - 'docs/examples/httpput*' @@ -244,7 +244,7 @@ HTTP: HTTP/2: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'CMake/FindNGHTTP2.cmake' - 'CMake/FindQUICHE.cmake' - 'docs/HTTP2.md' @@ -256,7 +256,7 @@ HTTP/2: HTTP/3: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '.github/workflows/ngtcp2*' - '.github/workflows/quiche*' - 'CMake/FindMSH3.cmake' @@ -271,27 +271,27 @@ HTTP/3: Hyper: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/HYPER.md' - 'lib/c-hyper.*' IMAP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/imap*' - 'docs/examples/imap*' LDAP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/*ldap*' libcurl API: - all: - changed-files: - - AnyGlobToAnyFile: + - any-glob-to-any-file: - 'docs/libcurl/ABI.md' - 'docs/libcurl/curl_*.3' - 'include/curl/**' @@ -299,7 +299,7 @@ libcurl API: logging: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/cmdline-opts/trace*' - 'docs/libcurl/curl_global_trace*' - 'lib/curl_trc*' @@ -308,7 +308,7 @@ logging: MIME: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/libcurl/curl_form*' - 'docs/libcurl/curl_mime_*' - 'docs/libcurl/opts/CURLOPT_MIME*' @@ -320,7 +320,7 @@ MIME: MQTT: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/MQTT.md' - 'lib/mqtt*' - 'tests/server/mqttd.c' @@ -328,7 +328,7 @@ MQTT: name lookup: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/examples/resolve.c' - 'docs/libcurl/opts/CURLINFO_NAMELOOKUP*' - 'docs/libcurl/opts/CURLOPT_DNS*' @@ -346,20 +346,20 @@ name lookup: POP3: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/examples/pop3*' - 'lib/pop3.*' RTMP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/curl_rtmp.*' RTSP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/libcurl/opts/CURLINFO_RTSP*' - 'docs/libcurl/opts/CURLOPT_RTSP*' - 'lib/rtsp.*' @@ -369,7 +369,7 @@ RTSP: SCP/SFTP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'CMake/FindLibSSH2.cmake' - 'docs/libcurl/opts/CURLOPT_SSH*' - 'docs/examples/sftp*' @@ -380,7 +380,7 @@ SCP/SFTP: script: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '**/*.pl' - '**/*.sh' - 'curl-config.in' @@ -392,14 +392,14 @@ script: SMB: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/smb.*' - 'tests/smbserver.py' SMTP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/examples/smtp-*' - 'docs/libcurl/opts/CURLOPT_MAIL*' - 'lib/smtp.*' @@ -407,13 +407,13 @@ SMTP: tests: - all: - changed-files: - - AnyGlobToAnyFile: + - any-glob-to-any-file: - 'tests/**' TFTP: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'lib/tftp.*' - 'tests/tftpserver.pl' - 'tests/server/tftp*' @@ -421,7 +421,7 @@ TFTP: TLS: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'CMake/FindBearSSL.cmake' - 'CMake/FindMbedTLS.cmake' - 'CMake/FindWolfSSL.cmake' @@ -453,7 +453,7 @@ TLS: URL: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/libcurl/curl_url*' - 'docs/URL-SYNTAX.md' - 'docs/examples/parseurl*' @@ -463,7 +463,7 @@ URL: WebSocket: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - 'docs/WEBSOCKET.md*' - 'docs/examples/websocket*' - 'docs/libcurl/curl_ws_*' @@ -478,7 +478,7 @@ WebSocket: Windows: - all: - changed-files: - - AnyGlobToAllFiles: + - any-glob-to-all-files: - '**/Makefile.mk' - 'appveyor.yml' - 'CMake/Platforms/WindowsCache.cmake' diff --git a/.github/scripts/codespell-ignore.txt b/.github/scripts/codespell-ignore.txt new file mode 100644 index 000000000..3832cec4d --- /dev/null +++ b/.github/scripts/codespell-ignore.txt @@ -0,0 +1,15 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl +clen +te +wont +statics +nome +wast +numer +anull +inout +msdos +ba +fo diff --git a/.github/scripts/verify-examples.pl b/.github/scripts/verify-examples.pl new file mode 100755 index 000000000..ff275569e --- /dev/null +++ b/.github/scripts/verify-examples.pl @@ -0,0 +1,93 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# 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 +# +########################################################################### + +my @files = @ARGV; +my $cfile = "test.c"; +my $check = "./scripts/checksrc.pl"; + +if($files[0] eq "-h") { + print "Usage: verify-synopsis [man pages]\n"; + exit; +} + +sub testcompile { + my $rc = system("gcc -c test.c -DCURL_DISABLE_TYPECHECK -DCURL_ALLOW_OLD_MULTI_SOCKET -DCURL_DISABLE_DEPRECATION -Wunused -Werror -Wno-unused-but-set-variable -I include") >> 8; + return $rc; +} + +sub checksrc { + my $rc = system("$check test.c") >> 8; + return $rc; +} + +sub extract { + my($f) = @_; + my $syn = 0; + my $l = 0; + my $iline = 0; + open(F, "<$f"); + open(O, ">$cfile"); + print O "#include \n"; + while() { + $iline++; + if(/^.SH EXAMPLE/) { + $syn = 1 + } + elsif($syn == 1) { + if(/^.nf/) { + $syn++; + print O "/* !checksrc! disable UNUSEDIGNORE all */\n"; + print O "/* !checksrc! disable COPYRIGHT all */\n"; + print O "/* !checksrc! disable FOPENMODE all */\n"; + printf O "#line %d \"$f\"\n", $iline+1; + } + } + elsif($syn == 2) { + if(/^.fi/) { + last; + } + # two backslashes become one + $_ =~ s/\\\\/\\/g; + print O $_; + $l++; + } + } + close(F); + close(O); + + return $l; +} + +my $error; +for my $m (@files) { + print "Verify $m\n"; + my $out = extract($m); + if($out) { + $error |= testcompile($m); + $error |= checksrc($m); + } +} +exit $error; + diff --git a/.github/scripts/verify-synopsis.pl b/.github/scripts/verify-synopsis.pl new file mode 100755 index 000000000..34f15a8e0 --- /dev/null +++ b/.github/scripts/verify-synopsis.pl @@ -0,0 +1,81 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# 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 +# +########################################################################### + +my @files = @ARGV; +my $cfile = "test.c"; + +if($files[0] eq "-h") { + print "Usage: verify-synopsis [man pages]\n"; + exit; +} + +sub testcompile { + my $rc = system("gcc -c test.c -DCURL_DISABLE_TYPECHECK -DCURL_ALLOW_OLD_MULTI_SOCKET -I include") >> 8; + return $rc; +} + + +sub extract { + my($f) = @_; + my $syn = 0; + my $l = 0; + my $iline = 0; + open(F, "<$f"); + open(O, ">$cfile"); + while() { + $iline++; + if(/^.SH SYNOPSIS/) { + $syn = 1 + } + elsif($syn == 1) { + if(/^.nf/) { + $syn++; + print O "#line $iline \"$f\"\n"; + } + } + elsif($syn == 2) { + if(/^.fi/) { + last; + } + # turn the vararg argument into vararg + $_ =~ s/, parameter\)\;/, ...);/; + print O $_; + $l++; + } + } + close(F); + close(O); + + return 0; +} + +my $error; +for my $m (@files) { + print "Verify $m\n"; + extract($m); + $error |= testcompile($m); +} +exit $error; + diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 000000000..405d63915 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,36 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +name: Codespell + +on: + push: + branches: + - master + - '*/ci' + paths: + - 'lib/**' + - 'src/**' + - 'include/**' + pull_request: + branches: + - master + - 'lib/**' + - 'src/**' + - 'include/**' + +jobs: + codespell: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: install + run: | + sudo apt-get update + sudo apt-get install codespell + + - name: spellcheck + run: codespell --skip src/tool_hugehelp.c -I .github/scripts/codespell-ignore.txt include src lib diff --git a/.github/workflows/distcheck.yml b/.github/workflows/distcheck.yml index a63091bd9..26c4da2b8 100644 --- a/.github/workflows/distcheck.yml +++ b/.github/workflows/distcheck.yml @@ -81,6 +81,27 @@ jobs: rm -rf curl-99.98.97 name: 'verify out-of-tree configure build including docs' + verify-out-of-tree-autotools-debug: + runs-on: ubuntu-latest + timeout-minutes: 30 + needs: maketgz-and-verify-in-tree + steps: + - uses: actions/download-artifact@v3 + with: + name: 'release-tgz' + + - run: | + echo "::stop-commands::$(uuidgen)" + tar xvf curl-99.98.97.tar.gz + pushd curl-99.98.97 + mkdir build + pushd build + ../configure --without-ssl --enable-debug "--prefix=${PWD}/pkg" + make -j3 + make -j3 TFLAGS=1279 test + make -j3 install + name: 'verify out-of-tree autotools debug build' + verify-out-of-tree-cmake: runs-on: ubuntu-latest timeout-minutes: 30 diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 6a157d240..df841cf88 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -21,8 +21,6 @@ jobs: pull-requests: write steps: - - uses: actions/labeler@v5.0.0-beta.1 + - uses: actions/labeler@v5 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" - # This is documented but doesn't work yet: - #dot: true diff --git a/.github/workflows/man-examples.yml b/.github/workflows/man-examples.yml new file mode 100644 index 000000000..126e989dc --- /dev/null +++ b/.github/workflows/man-examples.yml @@ -0,0 +1,30 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +name: manpage examples + +on: + push: + branches: + - master + - '*/ci' + paths: + - 'docs/libcurl/curl_*.3' + - 'docs/libcurl/opts/*.3' + pull_request: + branches: + - master + paths: + - 'docs/libcurl/curl_*.3' + - 'docs/libcurl/opts/*.3' + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: verify examples + run: ./.github/scripts/verify-examples.pl docs/libcurl/curl*.3 docs/libcurl/opts/*.3 diff --git a/.github/workflows/ngtcp2-linux.yml b/.github/workflows/ngtcp2-linux.yml index 0bc230aa4..e73eba8c1 100644 --- a/.github/workflows/ngtcp2-linux.yml +++ b/.github/workflows/ngtcp2-linux.yml @@ -46,13 +46,13 @@ permissions: {} env: MAKEFLAGS: -j 3 - quictls-version: 3.0.10+quic + quictls-version: 3.1.4+quic gnutls-version: 3.8.0 wolfssl-version: master - nghttp3-version: v0.15.0 - ngtcp2-version: v0.19.1 - nghttp2-version: v1.56.0 - mod_h2-version: v2.0.21 + nghttp3-version: v1.1.0 + ngtcp2-version: v1.1.0 + nghttp2-version: v1.58.0 + mod_h2-version: v2.0.25 jobs: autotools: @@ -66,7 +66,7 @@ jobs: - name: quictls configure: >- PKG_CONFIG_PATH="$HOME/nghttpx/lib/pkgconfig" LDFLAGS="-Wl,-rpath,$HOME/nghttpx/lib" - --with-ngtcp2=$HOME/nghttpx --enable-warnings --enable-werror --enable-debug + --with-ngtcp2=$HOME/nghttpx --enable-warnings --enable-werror --enable-debug --disable-ntlm --with-test-nghttpx="$HOME/nghttpx/bin/nghttpx" --with-openssl=$HOME/nghttpx - name: gnutls @@ -95,19 +95,19 @@ jobs: - name: cache quictls uses: actions/cache@v3 - id: cache-quictls + id: cache-quictls-no-deprecated env: - cache-name: cache-quictls + cache-name: cache-quictls-no-deprecated with: path: /home/runner/quictls key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.quictls-version }} - - if: steps.cache-quictls.outputs.cache-hit != 'true' + - if: steps.cache-quictls-no-deprecated.outputs.cache-hit != 'true' run: | cd $HOME git clone --quiet --depth=1 -b openssl-${{ env.quictls-version }} https://github.com/quictls/openssl quictls cd quictls - ./config --prefix=$HOME/nghttpx --libdir=$HOME/nghttpx/lib + ./config no-deprecated --prefix=$HOME/nghttpx --libdir=$HOME/nghttpx/lib make name: 'build quictls' diff --git a/.github/workflows/quiche-linux.yml b/.github/workflows/quiche-linux.yml index 90dec5e3a..9d43d42df 100644 --- a/.github/workflows/quiche-linux.yml +++ b/.github/workflows/quiche-linux.yml @@ -46,12 +46,12 @@ permissions: {} env: MAKEFLAGS: -j 3 - openssl-version: 3.0.10+quic - nghttp3-version: v0.15.0 - ngtcp2-version: v0.19.1 - nghttp2-version: v1.56.0 - quiche-version: 0.17.2 - mod_h2-version: v2.0.21 + openssl-version: 3.1.4+quic + nghttp3-version: v1.1.0 + ngtcp2-version: v1.1.0 + nghttp2-version: v1.58.0 + quiche-version: 0.19.0 + mod_h2-version: v2.0.25 jobs: autotools: diff --git a/.github/workflows/synopsis.yml b/.github/workflows/synopsis.yml new file mode 100644 index 000000000..948a83acb --- /dev/null +++ b/.github/workflows/synopsis.yml @@ -0,0 +1,28 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +name: SYNOPSIS + +on: + push: + branches: + - master + - '*/ci' + paths: + - 'docs/libcurl/curl_*.3' + pull_request: + branches: + - master + paths: + - 'docs/libcurl/curl_*.3' + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: verify-synopsis + run: ./.github/scripts/verify-synopsis.pl docs/libcurl/curl*.3 diff --git a/.vscode/settings.json b/.vscode/settings.json index cad7657df..05c6de630 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "cmake.configureOnOpen": false + "cmake.configureOnOpen": false, + "dotnet.defaultSolution": "disable" } \ No newline at end of file diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c index ea80ec89a..e54628626 100644 --- a/CMake/CurlTests.c +++ b/CMake/CurlTests.c @@ -23,7 +23,6 @@ ***************************************************************************/ #ifdef HAVE_FCNTL_O_NONBLOCK - /* headers for FCNTL_O_NONBLOCK test */ #include #include @@ -45,14 +44,13 @@ #error "O_NONBLOCK does not work on this platform" #endif -int -main () +int main(void) { - /* O_NONBLOCK source test */ - int flags = 0; - if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK)) - return 1; - return 0; + /* O_NONBLOCK source test */ + int flags = 0; + if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK)) + return 1; + return 0; } #endif @@ -108,36 +106,16 @@ int main(void) } #endif -#ifdef HAVE_SOCKLEN_T -#ifdef _WIN32 -#include -#else -#include -#include -#endif -int -main () -{ -if ((socklen_t *) 0) - return 0; -if (sizeof (socklen_t)) - return 0; - ; - return 0; -} -#endif #ifdef HAVE_IN_ADDR_T #include #include #include - -int -main () +int main(void) { -if ((in_addr_t *) 0) - return 0; -if (sizeof (in_addr_t)) - return 0; + if((in_addr_t *) 0) + return 0; + if(sizeof(in_addr_t)) + return 0; ; return 0; } @@ -150,11 +128,10 @@ if (sizeof (in_addr_t)) #ifdef HAVE_STDBOOL_H #include #endif -int -main () +int main(void) { -if (sizeof (bool *) ) - return 0; + if(sizeof(bool *)) + return 0; ; return 0; } @@ -165,8 +142,9 @@ if (sizeof (bool *) ) #include #include #include -int main() { return 0; } +int main(void) { return 0; } #endif + #ifdef HAVE_FILE_OFFSET_BITS #ifdef _FILE_OFFSET_BITS #undef _FILE_OFFSET_BITS @@ -181,104 +159,95 @@ int main() { return 0; } int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; -int main () { ; return 0; } +int main(void) { ; return 0; } #endif + #ifdef HAVE_IOCTLSOCKET /* includes start */ #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # endif +# include #endif - -int -main () +int main(void) { - -/* ioctlsocket source code */ - int socket; - unsigned long flags = ioctlsocket(socket, FIONBIO, &flags); - + /* ioctlsocket source code */ + int socket; + unsigned long flags = ioctlsocket(socket, FIONBIO, &flags); ; return 0; } #endif + #ifdef HAVE_IOCTLSOCKET_CAMEL /* includes start */ #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # endif +# include #endif - -int -main () +int main(void) { - -/* IoctlSocket source code */ - if(0 != IoctlSocket(0, 0, 0)) - return 1; + /* IoctlSocket source code */ + if(0 != IoctlSocket(0, 0, 0)) + return 1; ; return 0; } #endif + #ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO /* includes start */ #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # endif +# include #endif - -int -main () +int main(void) { - -/* IoctlSocket source code */ - long flags = 0; - if(0 != IoctlSocket(0, FIONBIO, &flags)) - return 1; + /* IoctlSocket source code */ + long flags = 0; + if(0 != IoctlSocket(0, FIONBIO, &flags)) + return 1; ; return 0; } #endif + #ifdef HAVE_IOCTLSOCKET_FIONBIO /* includes start */ #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # endif +# include #endif - -int -main () +int main(void) { - - int flags = 0; - if(0 != ioctlsocket(0, FIONBIO, &flags)) - return 1; - + int flags = 0; + if(0 != ioctlsocket(0, FIONBIO, &flags)) + return 1; ; return 0; } #endif + #ifdef HAVE_IOCTL_FIONBIO /* headers for FIONBIO test */ /* includes start */ @@ -297,19 +266,16 @@ main () #ifdef HAVE_STROPTS_H # include #endif - -int -main () +int main(void) { - - int flags = 0; - if(0 != ioctl(0, FIONBIO, &flags)) - return 1; - + int flags = 0; + if(0 != ioctl(0, FIONBIO, &flags)) + return 1; ; return 0; } #endif + #ifdef HAVE_IOCTL_SIOCGIFADDR /* headers for FIONBIO test */ /* includes start */ @@ -329,28 +295,26 @@ main () # include #endif #include - -int -main () +int main(void) { - struct ifreq ifr; - if(0 != ioctl(0, SIOCGIFADDR, &ifr)) - return 1; - + struct ifreq ifr; + if(0 != ioctl(0, SIOCGIFADDR, &ifr)) + return 1; ; return 0; } #endif + #ifdef HAVE_SETSOCKOPT_SO_NONBLOCK /* includes start */ #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # endif +# include #endif /* includes start */ #ifdef HAVE_SYS_TYPES_H @@ -360,30 +324,30 @@ main () # include #endif /* includes end */ - -int -main () +int main(void) { - if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0)) - return 1; + if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0)) + return 1; ; return 0; } #endif + #ifdef HAVE_GLIBC_STRERROR_R #include #include void check(char c) {} -int -main () { +int main(void) +{ char buffer[1024]; /* This will not compile if strerror_r does not return a char* */ check(strerror_r(EACCES, buffer, sizeof(buffer))[0]); return 0; } #endif + #ifdef HAVE_POSIX_STRERROR_R #include #include @@ -391,92 +355,51 @@ main () { /* float, because a pointer can't be implicitly cast to float */ void check(float f) {} -int -main () { +int main(void) +{ char buffer[1024]; /* This will not compile if strerror_r does not return an int */ check(strerror_r(EACCES, buffer, sizeof(buffer))); return 0; } #endif + #ifdef HAVE_FSETXATTR_6 #include /* header from libc, not from libattr */ -int -main() { +int main(void) +{ fsetxattr(0, 0, 0, 0, 0, 0); return 0; } #endif + #ifdef HAVE_FSETXATTR_5 #include /* header from libc, not from libattr */ -int -main() { +int main(void) +{ fsetxattr(0, 0, 0, 0, 0); return 0; } #endif + #ifdef HAVE_CLOCK_GETTIME_MONOTONIC #include -int -main() { +int main(void) +{ struct timespec ts = {0, 0}; clock_gettime(CLOCK_MONOTONIC, &ts); return 0; } #endif + #ifdef HAVE_BUILTIN_AVAILABLE -int -main() { +int main(void) +{ if(__builtin_available(macOS 10.12, *)) {} return 0; } #endif -#ifdef HAVE_VARIADIC_MACROS_C99 -#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__) -#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__) -int fun3(int arg1, int arg2, int arg3); -int fun2(int arg1, int arg2); - -int fun3(int arg1, int arg2, int arg3) { - return arg1 + arg2 + arg3; -} -int fun2(int arg1, int arg2) { - return arg1 + arg2; -} - -int -main() { - int res3 = c99_vmacro3(1, 2, 3); - int res2 = c99_vmacro2(1, 2); - (void)res3; - (void)res2; - return 0; -} -#endif -#ifdef HAVE_VARIADIC_MACROS_GCC -#define gcc_vmacro3(first, args...) fun3(first, args) -#define gcc_vmacro2(first, args...) fun2(first, args) - -int fun3(int arg1, int arg2, int arg3); -int fun2(int arg1, int arg2); - -int fun3(int arg1, int arg2, int arg3) { - return arg1 + arg2 + arg3; -} -int fun2(int arg1, int arg2) { - return arg1 + arg2; -} - -int -main() { - int res3 = gcc_vmacro3(1, 2, 3); - int res2 = gcc_vmacro2(1, 2); - (void)res3; - (void)res2; - return 0; -} -#endif #ifdef HAVE_ATOMIC /* includes start */ #ifdef HAVE_SYS_TYPES_H @@ -490,17 +413,24 @@ main() { #endif /* includes end */ -int -main() { +int main(void) +{ _Atomic int i = 1; i = 0; /* Force an atomic-write operation. */ return i; } #endif + #ifdef HAVE_WIN32_WINNT /* includes start */ -#ifdef WIN32 -# include "../lib/setup-win32.h" +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOGDI +# define NOGDI +# endif +# include #endif /* includes end */ @@ -508,8 +438,8 @@ main() { #define expand(x) enquote(x) #pragma message("_WIN32_WINNT=" expand(_WIN32_WINNT)) -int -main() { +int main(void) +{ return 0; } #endif diff --git a/CMake/FindZstd.cmake b/CMake/FindZstd.cmake index 973e6ad4a..0ea9e0c87 100644 --- a/CMake/FindZstd.cmake +++ b/CMake/FindZstd.cmake @@ -56,11 +56,18 @@ find_library(Zstd_LIBRARY NAMES zstd ${PC_Zstd_LIBRARY_DIRS} ) +if(Zstd_INCLUDE_DIR) + file(READ "${Zstd_INCLUDE_DIR}/zstd.h" _zstd_header) + string(REGEX MATCH ".*define ZSTD_VERSION_MAJOR *([0-9]+).*define ZSTD_VERSION_MINOR *([0-9]+).*define ZSTD_VERSION_RELEASE *([0-9]+)" _zstd_ver "${_zstd_header}") + set(Zstd_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") +endif() + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Zstd REQUIRED_VARS Zstd_LIBRARY Zstd_INCLUDE_DIR + VERSION_VAR Zstd_VERSION ) if(Zstd_FOUND) diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake index e12bf303f..7ad2f5c40 100644 --- a/CMake/Macros.cmake +++ b/CMake/Macros.cmake @@ -23,19 +23,6 @@ ########################################################################### #File defines convenience macros for available feature testing -# This macro checks if the symbol exists in the library and if it -# does, it prepends library to the list. It is intended to be called -# multiple times with a sequence of possibly dependent libraries in -# order of least-to-most-dependent. Some libraries depend on others -# to link correctly. -macro(check_library_exists_concat LIBRARY SYMBOL VARIABLE) - check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}" - ${VARIABLE}) - if(${VARIABLE}) - set(CURL_LIBS ${LIBRARY} ${CURL_LIBS}) - endif() -endmacro() - # Check if header file exists and add it to the list. # This macro is intended to be called multiple times with a sequence of # possibly dependent header files. Some headers depend on others to be diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake index d67a9059b..a613f6ecd 100644 --- a/CMake/OtherTests.cmake +++ b/CMake/OtherTests.cmake @@ -35,13 +35,13 @@ endmacro() set(signature_call_conv) if(HAVE_WINDOWS_H) - add_header_include(HAVE_WINSOCK2_H "winsock2.h") - add_header_include(HAVE_WINDOWS_H "windows.h") set(_source_epilogue "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif") + add_header_include(HAVE_WINSOCK2_H "winsock2.h") + add_header_include(HAVE_WINDOWS_H "windows.h") set(signature_call_conv "PASCAL") if(WIN32) - set(CMAKE_REQUIRED_LIBRARIES ws2_32) + set(CMAKE_REQUIRED_LIBRARIES "ws2_32") endif() else() add_header_include(HAVE_SYS_TYPES_H "sys/types.h") @@ -71,11 +71,11 @@ int main(void) { }" HAVE_STRUCT_TIMEVAL) if(HAVE_WINDOWS_H) - set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h) + set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h") else() set(CMAKE_EXTRA_INCLUDE_FILES) if(HAVE_SYS_SOCKET_H) - set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) + set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") endif() endif() @@ -172,7 +172,7 @@ if(NOT DEFINED HAVE_GETADDRINFO_THREADSAFE) }" HAVE_H_ERRNO) if(NOT HAVE_H_ERRNO) - check_c_source_runs("${_source_epilogue} + check_c_source_compiles("${_source_epilogue} int main(void) { h_errno = 2; @@ -201,7 +201,7 @@ if(NOT DEFINED HAVE_GETADDRINFO_THREADSAFE) set(_source_epilogue "${_save_epilogue}") endif() -if(NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW) +if(NOT WIN32 AND NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW) set(_save_epilogue "${_source_epilogue}") set(_source_epilogue "#undef inline") diff --git a/CMake/PickyWarnings.cmake b/CMake/PickyWarnings.cmake index 1310cb4fb..5a0d15604 100644 --- a/CMake/PickyWarnings.cmake +++ b/CMake/PickyWarnings.cmake @@ -52,8 +52,8 @@ if(PICKY_COMPILER) # Assume these options always exist with both clang and gcc. # Require clang 3.0 / gcc 2.95 or later. list(APPEND WPICKY_ENABLE - -Wbad-function-cast # clang 3.0 gcc 2.95 - -Wconversion # clang 3.0 gcc 2.95 + -Wbad-function-cast # clang 2.7 gcc 2.95 + -Wconversion # clang 2.7 gcc 2.95 -Winline # clang 1.0 gcc 1.0 -Wmissing-declarations # clang 1.0 gcc 2.7 -Wmissing-prototypes # clang 1.0 gcc 1.0 @@ -70,23 +70,37 @@ if(PICKY_COMPILER) # Always enable with clang, version dependent with gcc set(WPICKY_COMMON_OLD + -Waddress # clang 2.7 gcc 4.3 + -Wattributes # clang 2.7 gcc 4.1 -Wcast-align # clang 1.0 gcc 4.2 -Wdeclaration-after-statement # clang 1.0 gcc 3.4 - -Wempty-body # clang 3.0 gcc 4.3 + -Wdiv-by-zero # clang 2.7 gcc 4.1 + -Wempty-body # clang 2.7 gcc 4.3 -Wendif-labels # clang 1.0 gcc 3.3 -Wfloat-equal # clang 1.0 gcc 2.96 (3.0) - -Wignored-qualifiers # clang 3.0 gcc 4.3 + -Wformat-security # clang 2.7 gcc 4.1 + -Wignored-qualifiers # clang 2.8 gcc 4.3 + -Wmissing-field-initializers # clang 2.7 gcc 4.1 + -Wmissing-noreturn # clang 2.7 gcc 4.1 -Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) - -Wno-sign-conversion # clang 3.0 gcc 4.3 + -Wno-sign-conversion # clang 2.9 gcc 4.3 -Wno-system-headers # clang 1.0 gcc 3.0 + # -Wpadded # clang 2.9 gcc 4.1 # Not used because we cannot change public structs + -Wredundant-decls # clang 2.7 gcc 4.1 + -Wold-style-definition # clang 2.7 gcc 3.4 -Wstrict-prototypes # clang 1.0 gcc 3.3 - -Wtype-limits # clang 3.0 gcc 4.3 + # -Wswitch-enum # clang 2.7 gcc 4.1 # Not used because this basically disallows default case + -Wtype-limits # clang 2.7 gcc 4.3 + -Wunreachable-code # clang 2.7 gcc 4.1 + # -Wunused-macros # clang 2.7 gcc 4.1 # Not practical + -Wunused-parameter # clang 2.7 gcc 4.1 -Wvla # clang 2.8 gcc 4.3 ) set(WPICKY_COMMON -Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3 -Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0 + -Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0 -Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1 ) @@ -95,12 +109,16 @@ if(PICKY_COMPILER) ${WPICKY_COMMON_OLD} -Wshift-sign-overflow # clang 2.9 -Wshorten-64-to-32 # clang 1.0 + -Wlanguage-extension-token # clang 3.0 ) # Enable based on compiler version if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3)) list(APPEND WPICKY_ENABLE ${WPICKY_COMMON} + -Wunreachable-code-break # clang 3.5 appleclang 6.0 + -Wheader-guard # clang 3.4 appleclang 5.1 + -Wsometimes-uninitialized # clang 3.2 appleclang 4.6 ) endif() if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR @@ -125,6 +143,7 @@ if(PICKY_COMPILER) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3) list(APPEND WPICKY_ENABLE ${WPICKY_COMMON_OLD} + -Wclobbered # gcc 4.3 -Wmissing-parameter-type # gcc 4.3 -Wold-style-declaration # gcc 4.3 -Wstrict-aliasing=3 # gcc 4.0 @@ -159,7 +178,7 @@ if(PICKY_COMPILER) -Walloc-zero # gcc 7.0 -Wduplicated-branches # gcc 7.0 -Wformat-overflow=2 # gcc 7.0 - -Wformat-truncation=1 # gcc 7.0 + -Wformat-truncation=2 # gcc 7.0 -Wrestrict # gcc 7.0 ) endif() @@ -174,11 +193,11 @@ if(PICKY_COMPILER) unset(WPICKY) - foreach(_CCOPT ${WPICKY_ENABLE}) + foreach(_CCOPT IN LISTS WPICKY_ENABLE) set(WPICKY "${WPICKY} ${_CCOPT}") endforeach() - foreach(_CCOPT ${WPICKY_DETECT}) + foreach(_CCOPT IN LISTS WPICKY_DETECT) # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new # test result in. string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname) diff --git a/CMake/Platforms/WindowsCache.cmake b/CMake/Platforms/WindowsCache.cmake index 5daec0e1e..ec09fd4bd 100644 --- a/CMake/Platforms/WindowsCache.cmake +++ b/CMake/Platforms/WindowsCache.cmake @@ -21,113 +21,167 @@ # SPDX-License-Identifier: curl # ########################################################################### -if(NOT UNIX) - if(WIN32) +if(NOT WIN32) + message(FATAL_ERROR "This file should be included on Windows platform only") +endif() - set(HAVE_WINDOWS_H 1) - set(HAVE_WS2TCPIP_H 1) - set(HAVE_WINSOCK2_H 1) +set(HAVE_LOCALE_H 1) - if(MINGW) - set(HAVE_SNPRINTF 1) - set(HAVE_UNISTD_H 1) - set(HAVE_INTTYPES_H 1) +if(MINGW) + set(HAVE_SNPRINTF 1) + set(HAVE_UNISTD_H 1) + set(HAVE_LIBGEN_H 1) + set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size() + set(HAVE_STDBOOL_H 1) + set(HAVE_BOOL_T "${HAVE_STDBOOL_H}") + set(HAVE_STRTOLL 1) + set(HAVE_BASENAME 1) + set(HAVE_STRCASECMP 1) + set(HAVE_FTRUNCATE 1) + set(HAVE_SYS_PARAM_H 1) + set(HAVE_SYS_TIME_H 1) + set(HAVE_GETTIMEOFDAY 1) +else() + set(HAVE_LIBGEN_H 0) + set(HAVE_STRCASECMP 0) + set(HAVE_FTRUNCATE 0) + set(HAVE_SYS_PARAM_H 0) + set(HAVE_SYS_TIME_H 0) + set(HAVE_GETTIMEOFDAY 0) + if(MSVC) + set(HAVE_UNISTD_H 0) + set(HAVE_LOCALE_H 1) + set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size() + set(HAVE_STDATOMIC_H 0) + if(NOT MSVC_VERSION LESS 1800) + set(HAVE_STDBOOL_H 1) set(HAVE_STRTOLL 1) - set(HAVE_BASENAME 1) - elseif(MSVC) - if(NOT MSVC_VERSION LESS 1800) - set(HAVE_INTTYPES_H 1) - set(HAVE_STRTOLL 1) - else() - set(HAVE_INTTYPES_H 0) - set(HAVE_STRTOLL 0) - endif() - if(NOT MSVC_VERSION LESS 1900) - set(HAVE_SNPRINTF 1) - else() - set(HAVE_SNPRINTF 0) - endif() - set(HAVE_BASENAME 0) + else() + set(HAVE_STDBOOL_H 0) + set(HAVE_STRTOLL 0) endif() + set(HAVE_BOOL_T "${HAVE_STDBOOL_H}") + if(NOT MSVC_VERSION LESS 1900) + set(HAVE_SNPRINTF 1) + else() + set(HAVE_SNPRINTF 0) + endif() + set(HAVE_BASENAME 0) + set(HAVE_STRTOK_R 0) + set(HAVE_FILE_OFFSET_BITS 0) + set(HAVE_ATOMIC 0) + endif() +endif() - set(HAVE_LIBSOCKET 0) - set(HAVE_GETHOSTNAME 1) - set(HAVE_LIBZ 0) +# Available in Windows XP and newer +set(HAVE_GETADDRINFO 1) +set(HAVE_FREEADDRINFO 1) - set(HAVE_ARC4RANDOM 0) - set(HAVE_FNMATCH 0) - set(HAVE_SCHED_YIELD 0) - set(HAVE_ARPA_INET_H 0) - set(HAVE_FCNTL_H 1) - set(HAVE_IFADDRS_H 0) - set(HAVE_IO_H 1) - set(HAVE_NETDB_H 0) - set(HAVE_NETINET_IN_H 0) - set(HAVE_NETINET_TCP_H 0) - set(HAVE_NETINET_UDP_H 0) - set(HAVE_NET_IF_H 0) - set(HAVE_IOCTL_SIOCGIFADDR 0) - set(HAVE_POLL_H 0) - set(HAVE_POLL_FINE 0) - set(HAVE_PWD_H 0) - set(HAVE_STRINGS_H 0) - set(HAVE_SYS_FILIO_H 0) - set(HAVE_SYS_WAIT_H 0) - set(HAVE_SYS_IOCTL_H 0) - set(HAVE_SYS_PARAM_H 0) - set(HAVE_SYS_POLL_H 0) - set(HAVE_SYS_RESOURCE_H 0) - set(HAVE_SYS_SELECT_H 0) - set(HAVE_SYS_SOCKET_H 0) - set(HAVE_SYS_SOCKIO_H 0) - set(HAVE_SYS_STAT_H 1) - set(HAVE_SYS_TIME_H 0) - set(HAVE_SYS_TYPES_H 1) - set(HAVE_SYS_UN_H 0) - set(HAVE_SYS_UTIME_H 1) - set(HAVE_TERMIOS_H 0) - set(HAVE_TERMIO_H 0) - set(HAVE_UTIME_H 0) +set(HAVE_FCHMOD 0) +set(HAVE_SOCKETPAIR 0) +set(HAVE_SENDMSG 0) +set(HAVE_ALARM 0) +set(HAVE_FCNTL 0) +set(HAVE_GETPPID 0) +set(HAVE_UTIMES 0) +set(HAVE_GETPWUID_R 0) +set(HAVE_STRERROR_R 0) +set(HAVE_SIGINTERRUPT 0) +set(HAVE_PIPE 0) +set(HAVE_IF_NAMETOINDEX 0) +set(HAVE_GETRLIMIT 0) +set(HAVE_SETRLIMIT 0) +set(HAVE_FSETXATTR 0) +set(HAVE_LIBSOCKET 0) +set(HAVE_SETLOCALE 1) +set(HAVE_SETMODE 1) +set(HAVE_GETPEERNAME 1) +set(HAVE_GETSOCKNAME 1) +set(HAVE_GETHOSTNAME 1) +set(HAVE_LIBZ 0) - set(HAVE_FSEEKO 0) - set(HAVE__FSEEKI64 1) - set(HAVE_SOCKET 1) - set(HAVE_SELECT 1) - set(HAVE_STRDUP 1) - set(HAVE_STRICMP 1) - set(HAVE_STRCMPI 1) - set(HAVE_MEMRCHR 0) - set(HAVE_GETTIMEOFDAY 0) - set(HAVE_CLOSESOCKET 1) - set(HAVE_SIGSETJMP 0) - set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1) - set(HAVE_GETPASS_R 0) - set(HAVE_GETPWUID 0) - set(HAVE_GETEUID 0) - set(HAVE_UTIME 1) - set(HAVE_GMTIME_R 0) - set(HAVE_CLOCK_GETTIME_MONOTONIC_RAW 0) - set(HAVE_GETHOSTBYNAME_R 0) - set(HAVE_SIGNAL 1) - set(HAVE_LINUX_TCP_H 0) - set(HAVE_GLIBC_STRERROR_R 0) - set(HAVE_MACH_ABSOLUTE_TIME 0) - set(HAVE_GETIFADDRS 0) +set(HAVE_RECV 1) +set(HAVE_SEND 1) +set(HAVE_STROPTS_H 0) +set(HAVE_SYS_XATTR_H 0) +set(HAVE_ARC4RANDOM 0) +set(HAVE_FNMATCH 0) +set(HAVE_SCHED_YIELD 0) +set(HAVE_ARPA_INET_H 0) +set(HAVE_FCNTL_H 1) +set(HAVE_IFADDRS_H 0) +set(HAVE_IO_H 1) +set(HAVE_NETDB_H 0) +set(HAVE_NETINET_IN_H 0) +set(HAVE_NETINET_TCP_H 0) +set(HAVE_NETINET_UDP_H 0) +set(HAVE_NET_IF_H 0) +set(HAVE_IOCTL_SIOCGIFADDR 0) +set(HAVE_POLL_H 0) +set(HAVE_POLL_FINE 0) +set(HAVE_PWD_H 0) +set(HAVE_STRINGS_H 0) # mingw-w64 has it (wrapper to string.h) +set(HAVE_SYS_FILIO_H 0) +set(HAVE_SYS_WAIT_H 0) +set(HAVE_SYS_IOCTL_H 0) +set(HAVE_SYS_POLL_H 0) +set(HAVE_SYS_RESOURCE_H 0) +set(HAVE_SYS_SELECT_H 0) +set(HAVE_SYS_SOCKET_H 0) +set(HAVE_SYS_SOCKIO_H 0) +set(HAVE_SYS_STAT_H 1) +set(HAVE_SYS_TYPES_H 1) +set(HAVE_SYS_UN_H 0) +set(HAVE_SYS_UTIME_H 1) +set(HAVE_TERMIOS_H 0) +set(HAVE_TERMIO_H 0) +set(HAVE_UTIME_H 0) # mingw-w64 has it (wrapper to sys/utime.h) - set(HAVE_GETHOSTBYNAME_R_3 0) - set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0) - set(HAVE_GETHOSTBYNAME_R_5 0) - set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0) - set(HAVE_GETHOSTBYNAME_R_6 0) - set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0) +set(HAVE_FSEEKO 0) +set(HAVE__FSEEKI64 1) +set(HAVE_SOCKET 1) +set(HAVE_SELECT 1) +set(HAVE_STRDUP 1) +set(HAVE_STRICMP 1) +set(HAVE_STRCMPI 1) +set(HAVE_MEMRCHR 0) +set(HAVE_CLOSESOCKET 1) +set(HAVE_SIGSETJMP 0) +set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1) +set(HAVE_GETPASS_R 0) +set(HAVE_GETPWUID 0) +set(HAVE_GETEUID 0) +set(HAVE_UTIME 1) +set(HAVE_GMTIME_R 0) +set(HAVE_GETHOSTBYNAME_R 0) +set(HAVE_SIGNAL 1) +set(HAVE_SIGACTION 0) +set(HAVE_LINUX_TCP_H 0) +set(HAVE_GLIBC_STRERROR_R 0) +set(HAVE_MACH_ABSOLUTE_TIME 0) +set(HAVE_GETIFADDRS 0) +set(HAVE_FCNTL_O_NONBLOCK 0) +set(HAVE_IOCTLSOCKET 1) +set(HAVE_IOCTLSOCKET_CAMEL 0) +set(HAVE_IOCTLSOCKET_CAMEL_FIONBIO 0) +set(HAVE_IOCTLSOCKET_FIONBIO 1) +set(HAVE_IOCTL_FIONBIO 0) +set(HAVE_SETSOCKOPT_SO_NONBLOCK 0) +set(HAVE_POSIX_STRERROR_R 0) +set(HAVE_BUILTIN_AVAILABLE 0) +set(HAVE_MSG_NOSIGNAL 0) +set(HAVE_STRUCT_TIMEVAL 1) - set(HAVE_O_NONBLOCK 0) - set(HAVE_IN_ADDR_T 0) - set(STDC_HEADERS 1) +set(HAVE_GETHOSTBYNAME_R_3 0) +set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0) +set(HAVE_GETHOSTBYNAME_R_5 0) +set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0) +set(HAVE_GETHOSTBYNAME_R_6 0) +set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0) - set(HAVE_SIGACTION 0) - set(HAVE_MACRO_SIGSETJMP 0) - else() - message("This file should be included on Windows platform only") - endif() -endif() +set(HAVE_O_NONBLOCK 0) +set(HAVE_IN_ADDR_T 0) +set(STDC_HEADERS 1) + +set(HAVE_SIZEOF_SUSECONDS_T 0) +set(HAVE_SIZEOF_SA_FAMILY_T 0) diff --git a/CMake/curl-config.cmake.in b/CMake/curl-config.cmake.in index 056907c4f..9adb96e0a 100644 --- a/CMake/curl-config.cmake.in +++ b/CMake/curl-config.cmake.in @@ -35,4 +35,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") check_required_components("@PROJECT_NAME@") # Alias for either shared or static library -add_library(@PROJECT_NAME@::libcurl ALIAS @PROJECT_NAME@::@LIB_SELECTED@) +if(NOT TARGET @PROJECT_NAME@::libcurl) + add_library(@PROJECT_NAME@::libcurl ALIAS @PROJECT_NAME@::@LIB_SELECTED@) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b19c681d..a54c2fff9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,13 +54,13 @@ # HAVE_GNUTLS_SRP: `gnutls_srp_verifier` present in GnuTLS # HAVE_SSL_CTX_SET_QUIC_METHOD: `SSL_CTX_set_quic_method` present in OpenSSL/wolfSSL # HAVE_QUICHE_CONN_SET_QLOG_FD: `quiche_conn_set_qlog_fd` present in QUICHE -# HAVE_ZSTD_CREATEDSTREAM: `ZSTD_createDStream` present in Zstd # # For each of the above variables, if the variable is DEFINED (either # to ON or OFF), the symbol detection will be skipped. If the # variable is NOT DEFINED, the symbol detection will be performed. cmake_minimum_required(VERSION 3.7...3.16 FATAL_ERROR) +message(STATUS "Using CMake version ${CMAKE_VERSION}") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") include(Utilities) @@ -105,6 +105,8 @@ option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(BUILD_STATIC_LIBS "Build static libraries" OFF) option(BUILD_STATIC_CURL "Build curl executable with static libcurl" OFF) option(ENABLE_ARES "Set to ON to enable c-ares support" OFF) +option(CURL_DISABLE_INSTALL "Set to ON to disable instalation targets" OFF) + if(WIN32) option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF) option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF) @@ -220,6 +222,8 @@ option(CURL_DISABLE_GETOPTIONS "disables curl_easy_options API for existing opti mark_as_advanced(CURL_DISABLE_GETOPTIONS) option(CURL_DISABLE_GOPHER "disables Gopher" OFF) mark_as_advanced(CURL_DISABLE_GOPHER) +option(CURL_DISABLE_HEADERS_API "disables headers-api support" OFF) +mark_as_advanced(CURL_DISABLE_HEADERS_API) option(CURL_DISABLE_HSTS "disables HSTS support" OFF) mark_as_advanced(CURL_DISABLE_HSTS) option(CURL_DISABLE_HTTP "disables HTTP" OFF) @@ -237,6 +241,8 @@ mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION) option(CURL_DISABLE_MIME "disables MIME support" OFF) mark_as_advanced(CURL_DISABLE_MIME) option(CURL_DISABLE_MQTT "disables MQTT" OFF) +mark_as_advanced(CURL_DISABLE_BINDLOCAL) +option(CURL_DISABLE_BINDLOCAL "disables local binding support" OFF) mark_as_advanced(CURL_DISABLE_MQTT) option(CURL_DISABLE_NETRC "disables netrc parser" OFF) mark_as_advanced(CURL_DISABLE_NETRC) @@ -362,28 +368,33 @@ include(CheckCSourceCompiles) # On windows preload settings if(WIN32) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WINSOCKAPI_=) + set(HAVE_WINDOWS_H 1) + set(HAVE_WS2TCPIP_H 1) + set(HAVE_WINSOCK2_H 1) include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake) endif() if(ENABLE_THREADED_RESOLVER) - find_package(Threads REQUIRED) if(WIN32) set(USE_THREADS_WIN32 ON) else() + find_package(Threads REQUIRED) set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT}) set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT}) + set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() - set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) endif() # Check for all needed libraries -check_library_exists_concat("socket" connect HAVE_LIBSOCKET) +check_library_exists("socket" "connect" "" HAVE_LIBSOCKET) +if(HAVE_LIBSOCKET) + set(CURL_LIBS "socket;${CURL_LIBS}") +endif() check_function_exists(gethostname HAVE_GETHOSTNAME) if(WIN32) - list(APPEND CURL_LIBS "ws2_32") + list(APPEND CURL_LIBS "ws2_32" "bcrypt") if(USE_LIBRTMP) list(APPEND CURL_LIBS "winmm") endif() @@ -413,7 +424,7 @@ set(openssl_default ON) if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_WOLFSSL) set(openssl_default OFF) endif() -cmake_dependent_option(CURL_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default} CURL_ENABLE_SSL OFF) +cmake_dependent_option(CURL_USE_OPENSSL "Enable OpenSSL for SSL/TLS" ${openssl_default} CURL_ENABLE_SSL OFF) option(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG "Disable automatic loading of OpenSSL configuration" OFF) count_true(enabled_ssl_options_count @@ -487,11 +498,6 @@ if(CURL_USE_OPENSSL) include_directories(${OPENSSL_INCLUDE_DIR}) endif() - if(WIN32) - list(APPEND CURL_LIBS "ws2_32") - list(APPEND CURL_LIBS "bcrypt") # for OpenSSL/LibreSSL - endif() - if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "openssl") set(valid_default_ssl_backend TRUE) endif() @@ -604,17 +610,12 @@ option(CURL_ZSTD "Set to ON to enable building curl with zstd support." OFF) set(HAVE_ZSTD OFF) if(CURL_ZSTD) find_package(Zstd REQUIRED) - if(NOT DEFINED HAVE_ZSTD_CREATEDSTREAM) - cmake_push_check_state() - set(CMAKE_REQUIRED_INCLUDES ${Zstd_INCLUDE_DIRS}) - set(CMAKE_REQUIRED_LIBRARIES ${Zstd_LIBRARIES}) - check_symbol_exists(ZSTD_createDStream "zstd.h" HAVE_ZSTD_CREATEDSTREAM) - cmake_pop_check_state() - endif() - if(Zstd_FOUND AND HAVE_ZSTD_CREATEDSTREAM) + if(Zstd_FOUND AND NOT Zstd_VERSION VERSION_LESS "1.0.0") set(HAVE_ZSTD ON) list(APPEND CURL_LIBS ${Zstd_LIBRARIES}) include_directories(${Zstd_INCLUDE_DIRS}) + else() + message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.") endif() endif() @@ -647,6 +648,20 @@ macro(openssl_check_symbol_exists SYMBOL FILES VARIABLE) cmake_pop_check_state() endmacro() +# Ensure that the OpenSSL fork actually supports QUIC. +macro(openssl_check_quic) + if(NOT DEFINED HAVE_SSL_CTX_SET_QUIC_METHOD) + if(USE_OPENSSL) + openssl_check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD) + elseif(USE_WOLFSSL) + openssl_check_symbol_exists(wolfSSL_set_quic_method "wolfssl/options.h;wolfssl/openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD) + endif() + endif() + if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD) + message(FATAL_ERROR "QUIC support is missing in OpenSSL fork. Try setting -DOPENSSL_ROOT_DIR") + endif() +endmacro() + if(USE_OPENSSL OR USE_WOLFSSL) if(NOT DEFINED HAVE_SSL_SET0_WBIO) openssl_check_symbol_exists(SSL_set0_wbio "openssl/ssl.h" HAVE_SSL_SET0_WBIO) @@ -673,18 +688,7 @@ if(USE_NGTCP2) else() find_package(NGTCP2 REQUIRED quictls) endif() - - # Be sure that the OpenSSL/wolfSSL library actually supports QUIC. - if(NOT DEFINED HAVE_SSL_CTX_SET_QUIC_METHOD) - if(USE_OPENSSL) - openssl_check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD) - elseif(USE_WOLFSSL) - openssl_check_symbol_exists(wolfSSL_set_quic_method "wolfssl/options.h;wolfssl/openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD) - endif() - endif() - if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD) - message(FATAL_ERROR "QUIC support is missing in OpenSSL/LibreSSL/BoringSSL/wolfSSL. Try setting -DOPENSSL_ROOT_DIR") - endif() + openssl_check_quic() elseif(USE_GNUTLS) find_package(NGTCP2 REQUIRED GnuTLS) else() @@ -706,7 +710,10 @@ if(USE_QUICHE) message(FATAL_ERROR "Only one HTTP/3 backend can be selected!") endif() find_package(QUICHE REQUIRED) - CheckQuicSupportInOpenSSL() + if(NOT HAVE_BORINGSSL) + message(FATAL_ERROR "quiche requires BoringSSL") + endif() + openssl_check_quic() set(USE_QUICHE ON) include_directories(${QUICHE_INCLUDE_DIRS}) list(APPEND CURL_LIBS ${QUICHE_LIBRARIES}) @@ -751,8 +758,12 @@ if(NOT CURL_DISABLE_LDAP) if(NOT USE_WIN32_LDAP) # Check for LDAP set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) - check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP) - check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER) + check_library_exists("${CMAKE_LDAP_LIB}" "ldap_init" "" HAVE_LIBLDAP) + if(HAVE_LIBLDAP) + check_library_exists("${CMAKE_LDAP_LIB};${CMAKE_LBER_LIB}" "ber_init" "" HAVE_LIBLBER) + else() + check_library_exists("${CMAKE_LBER_LIB}" "ber_init" "" HAVE_LIBLBER) + endif() set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES}) set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory") @@ -791,8 +802,10 @@ if(NOT CURL_DISABLE_LDAP) list(APPEND CMAKE_REQUIRED_DEFINITIONS -DLDAP_DEPRECATED=1) list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB}) + set(CURL_LIBS "${CMAKE_LDAP_LIB};${CURL_LIBS}") if(HAVE_LIBLBER) list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB}) + set(CURL_LIBS "${CMAKE_LBER_LIB};${CURL_LIBS}") endif() check_c_source_compiles(" @@ -839,7 +852,11 @@ endif() # Check for idn2 option(USE_LIBIDN2 "Use libidn2 for IDN support" ON) if(USE_LIBIDN2) - check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2) + check_library_exists("idn2" "idn2_lookup_ul" "" HAVE_LIBIDN2) + if(HAVE_LIBIDN2) + set(CURL_LIBS "idn2;${CURL_LIBS}") + check_include_file_concat("idn2.h" HAVE_IDN2_H) + endif() else() set(HAVE_LIBIDN2 OFF) endif() @@ -1052,13 +1069,46 @@ if(CURL_CA_PATH_SET AND endif() # Check for header files -if(NOT UNIX) - check_include_file_concat("windows.h" HAVE_WINDOWS_H) - check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H) +if(WIN32) check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H) + check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H) + check_include_file_concat("windows.h" HAVE_WINDOWS_H) +endif() + +if(WIN32) + # detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT + curl_internal_test(HAVE_WIN32_WINNT) + if(HAVE_WIN32_WINNT) + string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" OUTPUT "${OUTPUT}") + string(REGEX REPLACE ".*_WIN32_WINNT=" "" OUTPUT "${OUTPUT}") + string(REGEX REPLACE "0x([0-9a-f][0-9a-f][0-9a-f])$" "0x0\\1" OUTPUT "${OUTPUT}") # pad to 4 digits + string(TOLOWER "${OUTPUT}" HAVE_WIN32_WINNT) + message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}") + endif() + # avoid storing HAVE_WIN32_WINNT in CMake cache + unset(HAVE_WIN32_WINNT CACHE) + + if(HAVE_WIN32_WINNT) + if(HAVE_WIN32_WINNT STRLESS "0x0501") + # Windows XP is required for freeaddrinfo, getaddrinfo + message(FATAL_ERROR "Building for Windows XP or newer is required.") + endif() + + # pre-fill detection results based on target OS version + if(MINGW OR MSVC) + if(HAVE_WIN32_WINNT STRLESS "0x0600") + set(HAVE_INET_NTOP 0) + set(HAVE_INET_PTON 0) + else() # Windows Vista or newer + set(HAVE_INET_NTOP 1) + set(HAVE_INET_PTON 1) + endif() + unset(HAVE_INET_NTOP CACHE) + unset(HAVE_INET_PTON CACHE) + endif() + endif() endif() -check_include_file_concat("inttypes.h" HAVE_INTTYPES_H) check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H) check_include_file_concat("sys/wait.h" HAVE_SYS_WAIT_H) check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H) @@ -1076,7 +1126,6 @@ check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H) check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H) check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H) check_include_file_concat("fcntl.h" HAVE_FCNTL_H) -check_include_file_concat("idn2.h" HAVE_IDN2_H) check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H) check_include_file_concat("io.h" HAVE_IO_H) check_include_file_concat("libgen.h" HAVE_LIBGEN_H) @@ -1092,7 +1141,6 @@ check_include_file_concat("poll.h" HAVE_POLL_H) check_include_file_concat("pwd.h" HAVE_PWD_H) check_include_file_concat("stdatomic.h" HAVE_STDATOMIC_H) check_include_file_concat("stdbool.h" HAVE_STDBOOL_H) -check_include_file_concat("stdint.h" HAVE_STDINT_H) check_include_file_concat("strings.h" HAVE_STRINGS_H) check_include_file_concat("stropts.h" HAVE_STROPTS_H) check_include_file_concat("termio.h" HAVE_TERMIO_H) @@ -1137,7 +1185,6 @@ elseif(HAVE_LIBSOCKET) set(CMAKE_REQUIRED_LIBRARIES socket) endif() -check_symbol_exists(fchmod "${CURL_INCLUDES}" HAVE_FCHMOD) check_symbol_exists(fnmatch "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH) check_symbol_exists(basename "${CURL_INCLUDES};string.h" HAVE_BASENAME) check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET) @@ -1174,6 +1221,7 @@ check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R) check_symbol_exists(signal "${CURL_INCLUDES};signal.h" HAVE_SIGNAL) check_symbol_exists(strtoll "${CURL_INCLUDES};stdlib.h" HAVE_STRTOLL) check_symbol_exists(strerror_r "${CURL_INCLUDES};stdlib.h;string.h" HAVE_STRERROR_R) +check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) check_symbol_exists(siginterrupt "${CURL_INCLUDES};signal.h" HAVE_SIGINTERRUPT) check_symbol_exists(getaddrinfo "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO) check_symbol_exists(getifaddrs "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS) @@ -1190,6 +1238,10 @@ check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE) check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE) check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT) +if(HAVE_FSEEKO) + set(HAVE_DECL_FSEEKO 1) +endif() + if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900)) # earlier MSVC compilers had faulty snprintf implementations check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) @@ -1213,20 +1265,11 @@ check_type_size("sa_family_t" SIZEOF_SA_FAMILY_T) set(HAVE_SA_FAMILY_T ${HAVE_SIZEOF_SA_FAMILY_T}) set(CMAKE_EXTRA_INCLUDE_FILES "") -set(CMAKE_EXTRA_INCLUDE_FILES "ws2def.h") -check_type_size("ADDRESS_FAMILY" SIZEOF_ADDRESS_FAMILY) -set(HAVE_ADDRESS_FAMILY ${HAVE_SIZEOF_ADDRESS_FAMILY}) -set(CMAKE_EXTRA_INCLUDE_FILES "") - -# sigaction and sigsetjmp are special. Use special mechanism for -# detecting those, but only if previous attempt failed. -check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) - -if(NOT HAVE_SIGSETJMP) - check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP) - if(HAVE_MACRO_SIGSETJMP) - set(HAVE_SIGSETJMP 1) - endif() +if(WIN32) + set(CMAKE_EXTRA_INCLUDE_FILES "ws2def.h") + check_type_size("ADDRESS_FAMILY" SIZEOF_ADDRESS_FAMILY) + set(HAVE_ADDRESS_FAMILY ${HAVE_SIZEOF_ADDRESS_FAMILY}) + set(CMAKE_EXTRA_INCLUDE_FILES "") endif() # Do curl specific tests @@ -1250,8 +1293,6 @@ foreach(CURL_TEST HAVE_BOOL_T STDC_HEADERS HAVE_FILE_OFFSET_BITS - HAVE_VARIADIC_MACROS_C99 - HAVE_VARIADIC_MACROS_GCC HAVE_ATOMIC ) curl_internal_test(${CURL_TEST}) @@ -1271,18 +1312,6 @@ set(CMAKE_EXTRA_INCLUDE_FILES "curl/curl.h") check_type_size("curl_socket_t" SIZEOF_CURL_SOCKET_T) set(CMAKE_EXTRA_INCLUDE_FILES "") -if(WIN32) - # detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT - curl_internal_test(HAVE_WIN32_WINNT) - if(HAVE_WIN32_WINNT) - string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" OUTPUT "${OUTPUT}") - string(REGEX REPLACE ".*_WIN32_WINNT=" "" HAVE_WIN32_WINNT "${OUTPUT}") - message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}") - endif() - # avoid storing HAVE_WIN32_WINNT in CMake cache - unset(HAVE_WIN32_WINNT CACHE) -endif() - if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING) # on not-Windows and not-crosscompiling, check for writable argv[] include(CheckCSourceRuns) @@ -1338,8 +1367,10 @@ if(NEED_REENTRANT) endforeach() endif() -# Check clock_gettime(CLOCK_MONOTONIC, x) support -curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC) +if(NOT WIN32) + # Check clock_gettime(CLOCK_MONOTONIC, x) support + curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC) +endif() # Check compiler support of __builtin_available() curl_internal_test(HAVE_BUILTIN_AVAILABLE) @@ -1404,8 +1435,6 @@ if(WIN32) if(USE_WIN32_CRYPTO OR USE_SCHANNEL) list(APPEND CURL_LIBS "advapi32" "crypt32") endif() - - list(APPEND CURL_LIBS "bcrypt") endif() if(MSVC) @@ -1492,258 +1521,262 @@ if(BUILD_TESTING) add_subdirectory(tests) endif() -# Helper to populate a list (_items) with a label when conditions (the remaining -# args) are satisfied -macro(_add_if label) - # needs to be a macro to allow this indirection - if(${ARGN}) - set(_items ${_items} "${label}") +if(NOT CURL_DISABLE_INSTALL) + + # Helper to populate a list (_items) with a label when conditions (the remaining + # args) are satisfied + macro(_add_if label) + # needs to be a macro to allow this indirection + if(${ARGN}) + set(_items ${_items} "${label}") + endif() + endmacro() + + # NTLM support requires crypto function adaptions from various SSL libs + # TODO alternative SSL libs tests for SSP1, GnuTLS, NSS + if(NOT (CURL_DISABLE_NTLM) AND + (USE_OPENSSL OR USE_MBEDTLS OR USE_DARWINSSL OR USE_WIN32_CRYPTO OR USE_GNUTLS)) + set(use_curl_ntlm_core ON) endif() -endmacro() -# NTLM support requires crypto function adaptions from various SSL libs -# TODO alternative SSL libs tests for SSP1, GnuTLS, NSS -if(NOT (CURL_DISABLE_NTLM) AND - (USE_OPENSSL OR USE_MBEDTLS OR USE_DARWINSSL OR USE_WIN32_CRYPTO OR USE_GNUTLS)) - set(use_curl_ntlm_core ON) -endif() - -# Clear list and try to detect available features -set(_items) -_add_if("SSL" SSL_ENABLED) -_add_if("IPv6" ENABLE_IPV6) -_add_if("unixsockets" USE_UNIX_SOCKETS) -_add_if("libz" HAVE_LIBZ) -_add_if("brotli" HAVE_BROTLI) -_add_if("zstd" HAVE_ZSTD) -_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) -_add_if("IDN" HAVE_LIBIDN2 OR USE_WIN32_IDN) -_add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND - ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) -# TODO SSP1 (Schannel) check is missing -_add_if("SSPI" USE_WINDOWS_SSPI) -_add_if("GSS-API" HAVE_GSSAPI) -_add_if("alt-svc" NOT CURL_DISABLE_ALTSVC) -_add_if("HSTS" NOT CURL_DISABLE_HSTS) -# TODO SSP1 missing for SPNEGO -_add_if("SPNEGO" NOT CURL_DISABLE_NEGOTIATE_AUTH AND - (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) -_add_if("Kerberos" NOT CURL_DISABLE_KERBEROS_AUTH AND - (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) -# NTLM support requires crypto function adaptions from various SSL libs -# TODO alternative SSL libs tests for SSP1, GnuTLS, NSS -_add_if("NTLM" NOT (CURL_DISABLE_NTLM) AND - (use_curl_ntlm_core OR USE_WINDOWS_SSPI)) -# TODO missing option (autoconf: --enable-ntlm-wb) -_add_if("NTLM_WB" NOT (CURL_DISABLE_NTLM) AND - (use_curl_ntlm_core OR USE_WINDOWS_SSPI) AND - NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED) -_add_if("TLS-SRP" USE_TLS_SRP) -# TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header -_add_if("HTTP2" USE_NGHTTP2) -_add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE) -_add_if("MultiSSL" CURL_WITH_MULTI_SSL) -# TODO wolfSSL only support this from v5.0.0 onwards -_add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS - OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR - USE_MBEDTLS OR USE_SECTRANSP)) -_add_if("unicode" ENABLE_UNICODE) -_add_if("threadsafe" HAVE_ATOMIC OR (WIN32 AND - HAVE_WIN32_WINNT GREATER_EQUAL 0x600)) -_add_if("PSL" USE_LIBPSL) -string(REPLACE ";" " " SUPPORT_FEATURES "${_items}") -message(STATUS "Enabled features: ${SUPPORT_FEATURES}") - -# Clear list and try to detect available protocols -set(_items) -_add_if("HTTP" NOT CURL_DISABLE_HTTP) -_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED) -_add_if("FTP" NOT CURL_DISABLE_FTP) -_add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED) -_add_if("FILE" NOT CURL_DISABLE_FILE) -_add_if("TELNET" NOT CURL_DISABLE_TELNET) -_add_if("LDAP" NOT CURL_DISABLE_LDAP) -# CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS -_add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND - ((USE_OPENLDAP AND SSL_ENABLED) OR - (NOT USE_OPENLDAP AND HAVE_LDAP_SSL))) -_add_if("DICT" NOT CURL_DISABLE_DICT) -_add_if("TFTP" NOT CURL_DISABLE_TFTP) -_add_if("GOPHER" NOT CURL_DISABLE_GOPHER) -_add_if("GOPHERS" NOT CURL_DISABLE_GOPHER AND SSL_ENABLED) -_add_if("POP3" NOT CURL_DISABLE_POP3) -_add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED) -_add_if("IMAP" NOT CURL_DISABLE_IMAP) -_add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED) -_add_if("SMB" NOT CURL_DISABLE_SMB AND - use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) -_add_if("SMBS" NOT CURL_DISABLE_SMB AND SSL_ENABLED AND - use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) -_add_if("SMTP" NOT CURL_DISABLE_SMTP) -_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED) -_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH) -_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH) -_add_if("RTSP" NOT CURL_DISABLE_RTSP) -_add_if("RTMP" USE_LIBRTMP) -_add_if("MQTT" NOT CURL_DISABLE_MQTT) -_add_if("WS" USE_WEBSOCKETS) -_add_if("WSS" USE_WEBSOCKETS) -if(_items) - list(SORT _items) -endif() -string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}") -message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}") - -# Clear list and collect SSL backends -set(_items) -_add_if("Schannel" SSL_ENABLED AND USE_SCHANNEL) -_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL) -_add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP) -_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS) -_add_if("BearSSL" SSL_ENABLED AND USE_BEARSSL) -_add_if("wolfSSL" SSL_ENABLED AND USE_WOLFSSL) -_add_if("GnuTLS" SSL_ENABLED AND USE_GNUTLS) - -if(_items) - list(SORT _items) -endif() -string(REPLACE ";" " " SSL_BACKENDS "${_items}") -message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}") -if(CURL_DEFAULT_SSL_BACKEND) - message(STATUS "Default SSL backend: ${CURL_DEFAULT_SSL_BACKEND}") -endif() - -# curl-config needs the following options to be set. -set(CC "${CMAKE_C_COMPILER}") -# TODO probably put a -D... options here? -set(CONFIGURE_OPTIONS "") -set(CURLVERSION "${CURL_VERSION}") -set(exec_prefix "\${prefix}") -set(includedir "\${prefix}/include") -set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}") -set(LIBCURL_LIBS "") -set(libdir "${CMAKE_INSTALL_PREFIX}/lib") -foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS}) - if(TARGET "${_lib}") - set(_libname "${_lib}") - get_target_property(_imported "${_libname}" IMPORTED) - if(NOT _imported) - # Reading the LOCATION property on non-imported target will error out. - # Assume the user won't need this information in the .pc file. - continue() + # Clear list and try to detect available features + set(_items) + _add_if("SSL" SSL_ENABLED) + _add_if("IPv6" ENABLE_IPV6) + _add_if("UnixSockets" USE_UNIX_SOCKETS) + _add_if("libz" HAVE_LIBZ) + _add_if("brotli" HAVE_BROTLI) + _add_if("zstd" HAVE_ZSTD) + _add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) + _add_if("IDN" HAVE_LIBIDN2 OR USE_WIN32_IDN) + _add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND + ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES)) + # TODO SSP1 (Schannel) check is missing + _add_if("SSPI" USE_WINDOWS_SSPI) + _add_if("GSS-API" HAVE_GSSAPI) + _add_if("alt-svc" NOT CURL_DISABLE_ALTSVC) + _add_if("HSTS" NOT CURL_DISABLE_HSTS) + # TODO SSP1 missing for SPNEGO + _add_if("SPNEGO" NOT CURL_DISABLE_NEGOTIATE_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) + _add_if("Kerberos" NOT CURL_DISABLE_KERBEROS_AUTH AND + (HAVE_GSSAPI OR USE_WINDOWS_SSPI)) + # NTLM support requires crypto function adaptions from various SSL libs + # TODO alternative SSL libs tests for SSP1, GnuTLS, NSS + _add_if("NTLM" NOT (CURL_DISABLE_NTLM) AND + (use_curl_ntlm_core OR USE_WINDOWS_SSPI)) + # TODO missing option (autoconf: --enable-ntlm-wb) + _add_if("NTLM_WB" NOT (CURL_DISABLE_NTLM) AND + (use_curl_ntlm_core OR USE_WINDOWS_SSPI) AND + NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED) + _add_if("TLS-SRP" USE_TLS_SRP) + # TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header + _add_if("HTTP2" USE_NGHTTP2) + _add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE) + _add_if("MultiSSL" CURL_WITH_MULTI_SSL) + # TODO wolfSSL only support this from v5.0.0 onwards + _add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS + OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR + USE_MBEDTLS OR USE_SECTRANSP)) + _add_if("unicode" ENABLE_UNICODE) + _add_if("threadsafe" HAVE_ATOMIC OR + (USE_THREADS_POSIX AND HAVE_PTHREAD_H) OR + (WIN32 AND HAVE_WIN32_WINNT GREATER_EQUAL 0x600)) + _add_if("PSL" USE_LIBPSL) + string(REPLACE ";" " " SUPPORT_FEATURES "${_items}") + message(STATUS "Enabled features: ${SUPPORT_FEATURES}") + + # Clear list and try to detect available protocols + set(_items) + _add_if("HTTP" NOT CURL_DISABLE_HTTP) + _add_if("HTTPS" NOT CURL_DISABLE_HTTP AND SSL_ENABLED) + _add_if("FTP" NOT CURL_DISABLE_FTP) + _add_if("FTPS" NOT CURL_DISABLE_FTP AND SSL_ENABLED) + _add_if("FILE" NOT CURL_DISABLE_FILE) + _add_if("TELNET" NOT CURL_DISABLE_TELNET) + _add_if("LDAP" NOT CURL_DISABLE_LDAP) + # CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS + _add_if("LDAPS" NOT CURL_DISABLE_LDAPS AND + ((USE_OPENLDAP AND SSL_ENABLED) OR + (NOT USE_OPENLDAP AND HAVE_LDAP_SSL))) + _add_if("DICT" NOT CURL_DISABLE_DICT) + _add_if("TFTP" NOT CURL_DISABLE_TFTP) + _add_if("GOPHER" NOT CURL_DISABLE_GOPHER) + _add_if("GOPHERS" NOT CURL_DISABLE_GOPHER AND SSL_ENABLED) + _add_if("POP3" NOT CURL_DISABLE_POP3) + _add_if("POP3S" NOT CURL_DISABLE_POP3 AND SSL_ENABLED) + _add_if("IMAP" NOT CURL_DISABLE_IMAP) + _add_if("IMAPS" NOT CURL_DISABLE_IMAP AND SSL_ENABLED) + _add_if("SMB" NOT CURL_DISABLE_SMB AND + use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) + _add_if("SMBS" NOT CURL_DISABLE_SMB AND SSL_ENABLED AND + use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4)) + _add_if("SMTP" NOT CURL_DISABLE_SMTP) + _add_if("SMTPS" NOT CURL_DISABLE_SMTP AND SSL_ENABLED) + _add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH) + _add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH) + _add_if("RTSP" NOT CURL_DISABLE_RTSP) + _add_if("RTMP" USE_LIBRTMP) + _add_if("MQTT" NOT CURL_DISABLE_MQTT) + _add_if("WS" USE_WEBSOCKETS) + _add_if("WSS" USE_WEBSOCKETS) + if(_items) + list(SORT _items) + endif() + string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}") + message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}") + + # Clear list and collect SSL backends + set(_items) + _add_if("Schannel" SSL_ENABLED AND USE_SCHANNEL) + _add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL) + _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP) + _add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS) + _add_if("BearSSL" SSL_ENABLED AND USE_BEARSSL) + _add_if("wolfSSL" SSL_ENABLED AND USE_WOLFSSL) + _add_if("GnuTLS" SSL_ENABLED AND USE_GNUTLS) + + if(_items) + list(SORT _items) + endif() + string(REPLACE ";" " " SSL_BACKENDS "${_items}") + message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}") + if(CURL_DEFAULT_SSL_BACKEND) + message(STATUS "Default SSL backend: ${CURL_DEFAULT_SSL_BACKEND}") + endif() + + # curl-config needs the following options to be set. + set(CC "${CMAKE_C_COMPILER}") + # TODO probably put a -D... options here? + set(CONFIGURE_OPTIONS "") + set(CURLVERSION "${CURL_VERSION}") + set(exec_prefix "\${prefix}") + set(includedir "\${prefix}/include") + set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}") + set(LIBCURL_LIBS "") + set(libdir "${CMAKE_INSTALL_PREFIX}/lib") + foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS}) + if(TARGET "${_lib}") + set(_libname "${_lib}") + get_target_property(_imported "${_libname}" IMPORTED) + if(NOT _imported) + # Reading the LOCATION property on non-imported target will error out. + # Assume the user won't need this information in the .pc file. + continue() + endif() + get_target_property(_lib "${_libname}" LOCATION) + if(NOT _lib) + message(WARNING "Bad lib in library list: ${_libname}") + continue() + endif() endif() - get_target_property(_lib "${_libname}" LOCATION) - if(NOT _lib) - message(WARNING "Bad lib in library list: ${_libname}") - continue() + if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-") + set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}") + else() + set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}") endif() + endforeach() + if(BUILD_SHARED_LIBS) + set(ENABLE_SHARED "yes") + set(LIBCURL_NO_SHARED "") + set(CPPFLAG_CURL_STATICLIB "") + else() + set(ENABLE_SHARED "no") + set(LIBCURL_NO_SHARED "${LIBCURL_LIBS}") + set(CPPFLAG_CURL_STATICLIB "-DCURL_STATICLIB") endif() - if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-") - set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}") + if(BUILD_STATIC_LIBS) + set(ENABLE_STATIC "yes") else() - set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}") + set(ENABLE_STATIC "no") endif() -endforeach() -if(BUILD_SHARED_LIBS) - set(ENABLE_SHARED "yes") - set(LIBCURL_NO_SHARED "") - set(CPPFLAG_CURL_STATICLIB "") -else() - set(ENABLE_SHARED "no") - set(LIBCURL_NO_SHARED "${LIBCURL_LIBS}") - set(CPPFLAG_CURL_STATICLIB "-DCURL_STATICLIB") -endif() -if(BUILD_STATIC_LIBS) - set(ENABLE_STATIC "yes") -else() - set(ENABLE_STATIC "no") -endif() -# "a" (Linux) or "lib" (Windows) -string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}") -set(prefix "${CMAKE_INSTALL_PREFIX}") -# Set this to "yes" to append all libraries on which -lcurl is dependent -set(REQUIRE_LIB_DEPS "no") -# SUPPORT_FEATURES -# SUPPORT_PROTOCOLS -set(VERSIONNUM "${CURL_VERSION_NUM}") - -# Finally generate a "curl-config" matching this config -# Use: -# * ENABLE_SHARED -# * ENABLE_STATIC -configure_file("${CURL_SOURCE_DIR}/curl-config.in" - "${CURL_BINARY_DIR}/curl-config" @ONLY) -install(FILES "${CURL_BINARY_DIR}/curl-config" - DESTINATION ${CMAKE_INSTALL_BINDIR} - PERMISSIONS - OWNER_READ OWNER_WRITE OWNER_EXECUTE - GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE) - -# Finally generate a pkg-config file matching this config -configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in" - "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) -install(FILES "${CURL_BINARY_DIR}/libcurl.pc" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) - -# install headers -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl" - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING PATTERN "*.h") - -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - "${version_config}" - VERSION ${CURL_VERSION} - COMPATIBILITY SameMajorVersion -) -file(READ "${version_config}" generated_version_config) -file(WRITE "${version_config}" -"if(NOT PACKAGE_FIND_VERSION_RANGE AND PACKAGE_FIND_VERSION_MAJOR STREQUAL \"7\") - # Version 8 satisfies version 7... requirements - set(PACKAGE_FIND_VERSION_MAJOR 8) - set(PACKAGE_FIND_VERSION_COUNT 1) -endif() -${generated_version_config}" -) + # "a" (Linux) or "lib" (Windows) + string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(prefix "${CMAKE_INSTALL_PREFIX}") + # Set this to "yes" to append all libraries on which -lcurl is dependent + set(REQUIRE_LIB_DEPS "no") + # SUPPORT_FEATURES + # SUPPORT_PROTOCOLS + set(VERSIONNUM "${CURL_VERSION_NUM}") + + # Finally generate a "curl-config" matching this config + # Use: + # * ENABLE_SHARED + # * ENABLE_STATIC + configure_file("${CURL_SOURCE_DIR}/curl-config.in" + "${CURL_BINARY_DIR}/curl-config" @ONLY) + install(FILES "${CURL_BINARY_DIR}/curl-config" + DESTINATION ${CMAKE_INSTALL_BINDIR} + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + + # Finally generate a pkg-config file matching this config + configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in" + "${CURL_BINARY_DIR}/libcurl.pc" @ONLY) + install(FILES "${CURL_BINARY_DIR}/libcurl.pc" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + + # install headers + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h") + + include(CMakePackageConfigHelpers) + write_basic_package_version_file( + "${version_config}" + VERSION ${CURL_VERSION} + COMPATIBILITY SameMajorVersion + ) + file(READ "${version_config}" generated_version_config) + file(WRITE "${version_config}" + "if(NOT PACKAGE_FIND_VERSION_RANGE AND PACKAGE_FIND_VERSION_MAJOR STREQUAL \"7\") + # Version 8 satisfies version 7... requirements + set(PACKAGE_FIND_VERSION_MAJOR 8) + set(PACKAGE_FIND_VERSION_COUNT 1) + endif() + ${generated_version_config}" + ) -# Use: -# * TARGETS_EXPORT_NAME -# * PROJECT_NAME -configure_package_config_file(CMake/curl-config.cmake.in - "${project_config}" - INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR} -) + # Use: + # * TARGETS_EXPORT_NAME + # * PROJECT_NAME + configure_package_config_file(CMake/curl-config.cmake.in + "${project_config}" + INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR} + ) + + if(CURL_ENABLE_EXPORT_TARGET) + install( + EXPORT "${TARGETS_EXPORT_NAME}" + NAMESPACE "${PROJECT_NAME}::" + DESTINATION ${CURL_INSTALL_CMAKE_DIR} + ) + endif() -if(CURL_ENABLE_EXPORT_TARGET) install( - EXPORT "${TARGETS_EXPORT_NAME}" - NAMESPACE "${PROJECT_NAME}::" + FILES ${version_config} ${project_config} DESTINATION ${CURL_INSTALL_CMAKE_DIR} ) -endif() - -install( - FILES ${version_config} ${project_config} - DESTINATION ${CURL_INSTALL_CMAKE_DIR} -) -# Workaround for MSVS10 to avoid the Dialog Hell -# FIXME: This could be removed with future version of CMake. -if(MSVC_VERSION EQUAL 1600) - set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln") - if(EXISTS "${CURL_SLN_FILENAME}") - file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n") + # Workaround for MSVS10 to avoid the Dialog Hell + # FIXME: This could be removed with future version of CMake. + if(MSVC_VERSION EQUAL 1600) + set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln") + if(EXISTS "${CURL_SLN_FILENAME}") + file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n") + endif() endif() -endif() -if(NOT TARGET curl_uninstall) - configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake - IMMEDIATE @ONLY) + if(NOT TARGET curl_uninstall) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake + IMMEDIATE @ONLY) - add_custom_target(curl_uninstall - COMMAND ${CMAKE_COMMAND} -P - ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake) + add_custom_target(curl_uninstall + COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake) + endif() endif() diff --git a/Makefile.am b/Makefile.am index 6c780a849..c8afcb505 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,27 +53,6 @@ CMAKE_DIST = \ CMake/Utilities.cmake \ CMakeLists.txt -VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl -VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist -VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc -VC10_SRCTMPL = projects/Windows/VC10/src/curl.tmpl -VC10_SRCVCXPROJ = projects/Windows/VC10/src/curl.vcxproj.dist -VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc - -VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl -VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist -VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc -VC11_SRCTMPL = projects/Windows/VC11/src/curl.tmpl -VC11_SRCVCXPROJ = projects/Windows/VC11/src/curl.vcxproj.dist -VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc - -VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl -VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist -VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc -VC12_SRCTMPL = projects/Windows/VC12/src/curl.tmpl -VC12_SRCVCXPROJ = projects/Windows/VC12/src/curl.vcxproj.dist -VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc - VC14_LIBTMPL = projects/Windows/VC14/lib/libcurl.tmpl VC14_LIBVCXPROJ = projects/Windows/VC14/lib/libcurl.vcxproj.dist VC14_LIBVCXPROJ_DEPS = $(VC14_LIBTMPL) Makefile.am lib/Makefile.inc @@ -88,6 +67,13 @@ VC14_10_SRCTMPL = projects/Windows/VC14.10/src/curl.tmpl VC14_10_SRCVCXPROJ = projects/Windows/VC14.10/src/curl.vcxproj.dist VC14_10_SRCVCXPROJ_DEPS = $(VC14_10_SRCTMPL) Makefile.am src/Makefile.inc +VC14_20_LIBTMPL = projects/Windows/VC14.20/lib/libcurl.tmpl +VC14_20_LIBVCXPROJ = projects/Windows/VC14.20/lib/libcurl.vcxproj.dist +VC14_20_LIBVCXPROJ_DEPS = $(VC14_20_LIBTMPL) Makefile.am lib/Makefile.inc +VC14_20_SRCTMPL = projects/Windows/VC14.20/src/curl.tmpl +VC14_20_SRCVCXPROJ = projects/Windows/VC14.20/src/curl.vcxproj.dist +VC14_20_SRCVCXPROJ_DEPS = $(VC14_20_SRCTMPL) Makefile.am src/Makefile.inc + VC14_30_LIBTMPL = projects/Windows/VC14.30/lib/libcurl.tmpl VC14_30_LIBVCXPROJ = projects/Windows/VC14.30/lib/libcurl.vcxproj.dist VC14_30_LIBVCXPROJ_DEPS = $(VC14_30_LIBTMPL) Makefile.am lib/Makefile.inc @@ -99,21 +85,6 @@ VC_DIST = projects/README.md \ projects/build-openssl.bat \ projects/build-wolfssl.bat \ projects/checksrc.bat \ - projects/Windows/VC10/curl-all.sln \ - projects/Windows/VC10/lib/libcurl.sln \ - projects/Windows/VC10/lib/libcurl.vcxproj.filters \ - projects/Windows/VC10/src/curl.sln \ - projects/Windows/VC10/src/curl.vcxproj.filters \ - projects/Windows/VC11/curl-all.sln \ - projects/Windows/VC11/lib/libcurl.sln \ - projects/Windows/VC11/lib/libcurl.vcxproj.filters \ - projects/Windows/VC11/src/curl.sln \ - projects/Windows/VC11/src/curl.vcxproj.filters \ - projects/Windows/VC12/curl-all.sln \ - projects/Windows/VC12/lib/libcurl.sln \ - projects/Windows/VC12/lib/libcurl.vcxproj.filters \ - projects/Windows/VC12/src/curl.sln \ - projects/Windows/VC12/src/curl.vcxproj.filters \ projects/Windows/VC14/curl-all.sln \ projects/Windows/VC14/lib/libcurl.sln \ projects/Windows/VC14/lib/libcurl.vcxproj.filters \ @@ -124,6 +95,11 @@ VC_DIST = projects/README.md \ projects/Windows/VC14.10/lib/libcurl.vcxproj.filters \ projects/Windows/VC14.10/src/curl.sln \ projects/Windows/VC14.10/src/curl.vcxproj.filters \ + projects/Windows/VC14.20/curl-all.sln \ + projects/Windows/VC14.20/lib/libcurl.sln \ + projects/Windows/VC14.20/lib/libcurl.vcxproj.filters \ + projects/Windows/VC14.20/src/curl.sln \ + projects/Windows/VC14.20/src/curl.vcxproj.filters \ projects/Windows/VC14.30/curl-all.sln \ projects/Windows/VC14.30/lib/libcurl.sln \ projects/Windows/VC14.30/lib/libcurl.vcxproj.filters \ @@ -151,8 +127,7 @@ EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \ $(VC_DIST) $(WINBUILD_DIST) $(PLAN9_DIST) lib/libcurl.vers.in buildconf.bat \ libcurl.def -CLEANFILES = $(VC10_LIBVCXPROJ) $(VC10_SRCVCXPROJ) $(VC11_LIBVCXPROJ) \ - $(VC11_SRCVCXPROJ) $(VC12_LIBVCXPROJ) $(VC12_SRCVCXPROJ) $(VC14_LIBVCXPROJ) \ +CLEANFILES = $(VC14_LIBVCXPROJ) \ $(VC14_SRCVCXPROJ) $(VC14_10_LIBVCXPROJ) $(VC14_10_SRCVCXPROJ) \ $(VC14_30_LIBVCXPROJ) $(VC14_30_SRCVCXPROJ) @@ -300,10 +275,9 @@ checksrc: .PHONY: vc-ide -vc-ide: $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_DEPS) \ - $(VC11_LIBVCXPROJ_DEPS) $(VC11_SRCVCXPROJ_DEPS) $(VC12_LIBVCXPROJ_DEPS) \ - $(VC12_SRCVCXPROJ_DEPS) $(VC14_LIBVCXPROJ_DEPS) $(VC14_SRCVCXPROJ_DEPS) \ - $(VC14_10_LIBVCXPROJ_DEPS) $(VC14_10_SRCVCXPROJ_DEPS) \ +vc-ide: $(VC14_LIBVCXPROJ_DEPS) $(VC14_SRCVCXPROJ_DEPS) \ + $(VC14_10_LIBVCXPROJ_DEPS) $(VC14_10_SRCVCXPROJ_DEPS) \ + $(VC14_20_LIBVCXPROJ_DEPS) $(VC14_20_SRCVCXPROJ_DEPS) \ $(VC14_30_LIBVCXPROJ_DEPS) $(VC14_30_SRCVCXPROJ_DEPS) @(win32_lib_srcs='$(LIB_CFILES)'; \ win32_lib_hdrs='$(LIB_HFILES) config-win32.h'; \ @@ -465,55 +439,7 @@ function gen_element(type, dir, file)\ printf("%s\r\n", $$0);\ }';\ \ - echo "generating '$(VC10_LIBVCXPROJ)'"; \ - awk -v proj_type=vcxproj \ - -v lib_srcs="$$sorted_lib_srcs" \ - -v lib_hdrs="$$sorted_lib_hdrs" \ - -v lib_rc="$$win32_lib_rc" \ - -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ - -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ - -v lib_vquic_srcs="$$sorted_lib_vquic_srcs" \ - -v lib_vquic_hdrs="$$sorted_lib_vquic_hdrs" \ - -v lib_vssh_srcs="$$sorted_lib_vssh_srcs" \ - -v lib_vssh_hdrs="$$sorted_lib_vssh_hdrs" \ - -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ - -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ - "$$awk_code" $(srcdir)/$(VC10_LIBTMPL) > $(VC10_LIBVCXPROJ) || { exit 1; }; \ - \ - echo "generating '$(VC10_SRCVCXPROJ)'"; \ - awk -v proj_type=vcxproj \ - -v src_srcs="$$sorted_src_srcs" \ - -v src_hdrs="$$sorted_src_hdrs" \ - -v src_rc="$$win32_src_rc" \ - -v src_x_srcs="$$sorted_src_x_srcs" \ - -v src_x_hdrs="$$sorted_src_x_hdrs" \ - "$$awk_code" $(srcdir)/$(VC10_SRCTMPL) > $(VC10_SRCVCXPROJ) || { exit 1; }; \ - \ - echo "generating '$(VC11_LIBVCXPROJ)'"; \ - awk -v proj_type=vcxproj \ - -v lib_srcs="$$sorted_lib_srcs" \ - -v lib_hdrs="$$sorted_lib_hdrs" \ - -v lib_rc="$$win32_lib_rc" \ - -v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \ - -v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \ - -v lib_vquic_srcs="$$sorted_lib_vquic_srcs" \ - -v lib_vquic_hdrs="$$sorted_lib_vquic_hdrs" \ - -v lib_vssh_srcs="$$sorted_lib_vssh_srcs" \ - -v lib_vssh_hdrs="$$sorted_lib_vssh_hdrs" \ - -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ - -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ - "$$awk_code" $(srcdir)/$(VC11_LIBTMPL) > $(VC11_LIBVCXPROJ) || { exit 1; }; \ - \ - echo "generating '$(VC11_SRCVCXPROJ)'"; \ - awk -v proj_type=vcxproj \ - -v src_srcs="$$sorted_src_srcs" \ - -v src_hdrs="$$sorted_src_hdrs" \ - -v src_rc="$$win32_src_rc" \ - -v src_x_srcs="$$sorted_src_x_srcs" \ - -v src_x_hdrs="$$sorted_src_x_hdrs" \ - "$$awk_code" $(srcdir)/$(VC11_SRCTMPL) > $(VC11_SRCVCXPROJ) || { exit 1; }; \ - \ - echo "generating '$(VC12_LIBVCXPROJ)'"; \ + echo "generating '$(VC14_LIBVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v lib_srcs="$$sorted_lib_srcs" \ -v lib_hdrs="$$sorted_lib_hdrs" \ @@ -526,18 +452,18 @@ function gen_element(type, dir, file)\ -v lib_vssh_hdrs="$$sorted_lib_vssh_hdrs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ - "$$awk_code" $(srcdir)/$(VC12_LIBTMPL) > $(VC12_LIBVCXPROJ) || { exit 1; }; \ + "$$awk_code" $(srcdir)/$(VC14_LIBTMPL) > $(VC14_LIBVCXPROJ) || { exit 1; }; \ \ - echo "generating '$(VC12_SRCVCXPROJ)'"; \ + echo "generating '$(VC14_SRCVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v src_srcs="$$sorted_src_srcs" \ -v src_hdrs="$$sorted_src_hdrs" \ -v src_rc="$$win32_src_rc" \ -v src_x_srcs="$$sorted_src_x_srcs" \ -v src_x_hdrs="$$sorted_src_x_hdrs" \ - "$$awk_code" $(srcdir)/$(VC12_SRCTMPL) > $(VC12_SRCVCXPROJ) || { exit 1; }; \ + "$$awk_code" $(srcdir)/$(VC14_SRCTMPL) > $(VC14_SRCVCXPROJ) || { exit 1; }; \ \ - echo "generating '$(VC14_LIBVCXPROJ)'"; \ + echo "generating '$(VC14_10_LIBVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v lib_srcs="$$sorted_lib_srcs" \ -v lib_hdrs="$$sorted_lib_hdrs" \ @@ -550,18 +476,18 @@ function gen_element(type, dir, file)\ -v lib_vssh_hdrs="$$sorted_lib_vssh_hdrs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ - "$$awk_code" $(srcdir)/$(VC14_LIBTMPL) > $(VC14_LIBVCXPROJ) || { exit 1; }; \ + "$$awk_code" $(srcdir)/$(VC14_10_LIBTMPL) > $(VC14_10_LIBVCXPROJ) || { exit 1; }; \ \ - echo "generating '$(VC14_SRCVCXPROJ)'"; \ + echo "generating '$(VC14_10_SRCVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v src_srcs="$$sorted_src_srcs" \ -v src_hdrs="$$sorted_src_hdrs" \ -v src_rc="$$win32_src_rc" \ -v src_x_srcs="$$sorted_src_x_srcs" \ -v src_x_hdrs="$$sorted_src_x_hdrs" \ - "$$awk_code" $(srcdir)/$(VC14_SRCTMPL) > $(VC14_SRCVCXPROJ) || { exit 1; }; \ + "$$awk_code" $(srcdir)/$(VC14_10_SRCTMPL) > $(VC14_10_SRCVCXPROJ) || { exit 1; }; \ \ - echo "generating '$(VC14_10_LIBVCXPROJ)'"; \ + echo "generating '$(VC14_20_LIBVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v lib_srcs="$$sorted_lib_srcs" \ -v lib_hdrs="$$sorted_lib_hdrs" \ @@ -574,17 +500,16 @@ function gen_element(type, dir, file)\ -v lib_vssh_hdrs="$$sorted_lib_vssh_hdrs" \ -v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \ -v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \ - "$$awk_code" $(srcdir)/$(VC14_10_LIBTMPL) > $(VC14_10_LIBVCXPROJ) || { exit 1; }; \ + "$$awk_code" $(srcdir)/$(VC14_20_LIBTMPL) > $(VC14_20_LIBVCXPROJ) || { exit 1; }; \ \ - echo "generating '$(VC14_10_SRCVCXPROJ)'"; \ + echo "generating '$(VC14_20_SRCVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v src_srcs="$$sorted_src_srcs" \ -v src_hdrs="$$sorted_src_hdrs" \ -v src_rc="$$win32_src_rc" \ -v src_x_srcs="$$sorted_src_x_srcs" \ -v src_x_hdrs="$$sorted_src_x_hdrs" \ - "$$awk_code" $(srcdir)/$(VC14_10_SRCTMPL) > $(VC14_10_SRCVCXPROJ) || { exit 1; }; \ - \ + "$$awk_code" $(srcdir)/$(VC14_20_SRCTMPL) > $(VC14_20_SRCVCXPROJ) || { exit 1; };) \ echo "generating '$(VC14_30_LIBVCXPROJ)'"; \ awk -v proj_type=vcxproj \ -v lib_srcs="$$sorted_lib_srcs" \ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 0b331a484..3f7dc99f6 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,155 +1,206 @@ -curl and libcurl 8.4.0 +curl and libcurl 8.5.0 - Public curl releases: 252 + Public curl releases: 253 Command line options: 258 curl_easy_setopt() options: 303 Public functions in libcurl: 93 - Contributors: 2995 + Contributors: 3039 This release includes the following changes: - o curl: add support for the IPFS protocols via HTTP gateway [46] - o curl_multi_get_handles: get easy handles from a multi handle [20] - o mingw: delete support for legacy mingw.org toolchain [45] + o gnutls: support CURLSSLOPT_NATIVE_CA [31] + o HTTP3: ngtcp2 builds are no longer experimental [77] This release includes the following bugfixes: - o acinclude.m4: Document proper system truststore on FreeBSD [83] - o appveyor: fix yamlint issues, indent [67] - o appveyor: rewrite batch in PowerShell + CI improvements [109] - o autotools: adjust `CURL_CA_PATH` value to CMake [53] - o autotools: restore `HAVE_IOCTL_*` detections [111] - o base64: also build for curl [78] - o bufq: remove Curl_bufq_skip_and_shift (unused) [47] - o build: delete checks for C89 standard headers [65] - o build: do not publish `HAVE_BORINGSSL`, `HAVE_AWSLC` macros [114] - o cf-socket: simulate slow/blocked receives in debug [120] - o cmake, configure: also link with CoreServices [32] - o cmake: add check for suseconds_t [91] - o cmake: add feature checks for `memrchr` and `getifaddrs` [57] - o cmake: add missing checks [86] - o cmake: delete old `HAVE_LDAP_URL_PARSE` logic [105] - o cmake: detect `HAVE_CLOCK_GETTIME_MONOTONIC_RAW` [75] - o cmake: detect `HAVE_GETADDRINFO_THREADSAFE` [76] - o cmake: detect `sys/wait.h` and `netinet/udp.h` [61] - o cmake: detect TLS-SRP in OpenSSL/wolfSSL/GnuTLS [93] - o cmake: disable unity mode with Windows Unicode + TrackMemory [108] - o cmake: fix `HAVE_LDAP_SSL`, `HAVE_LDAP_URL_PARSE` on non-Windows [110] - o cmake: fix `HAVE_WRITABLE_ARGV` detection [77] - o cmake: fix duplicate symbols when linking tests [73] - o cmake: fix missing `zlib.h` when compiling `libcurltool` [72] - o cmake: fix stderr initialization in unity builds [71] - o cmake: fix the help text to the static build option in CMakeLists.txt [10] - o cmake: fix unity builds for more build combinations [96] - o cmake: fix unity symbol collisions in h2 builds [48] - o cmake: fix unity with Windows Unicode + TrackMemory [107] - o cmake: improve OpenLDAP builds [92] - o cmake: lib `CURL_STATICLIB` fixes (Windows) [74] - o cmake: move global headers to specific checks [58] - o cmake: pre-cache `HAVE_BASENAME` for mingw-w64 and MSVC [85] - o cmake: pre-cache `HAVE_POLL_FINE` on Windows [36] - o cmake: tidy-up `NOT_NEED_LBER_H` detection - o cmake: validate `CURL_DEFAULT_SSL_BACKEND` config value [50] - o configure: check for the capath by default [63] - o configure: remove unused checks [87] - o configure: replace adhoc domain with `localhost` in tests [79] - o configure: sort AC_CHECK_FUNCS - o connect: expire the timeout when trying next [54] - o connect: only start the happy eyeballs timer when needed [95] - o cookie: do not store the expire or max-age strings [16] - o cookie: remove unnecessary struct fields [17] - o cookie: set ->running in cookie_init even if data is NULL [5] - o create-dirs.d: clarify it also uses --output-dirs [66] - o curl.h: mark CURLSSLBACKEND_NSS as deprecated since 8.3.0 [18] - o curl_easy_pause.3: mention h2/h3 buffering [113] - o curl_easy_pause.3: mention it works within callbacks [112] - o curl_easy_pause: set "in callback" true on exit if true [100] - o CURLOPT_DEBUGFUNCTION.3: warn about internal handles [122] - o docs/libcurl/opts/Makefile.inc: add missing manpage files - o docs: adapt SEE ALSO sections to new requirements [52] - o docs: explain how PINNEDPUBLICKEY is independent of VERIFYPEER [68] - o docs: replace made up domains with example.com [82] - o docs: update curl man page references [89] - o docs: use CURLSSLBACKEND_NONE [19] - o doh: inherit DEBUGFUNCTION/DATA [12] - o escape: replace Curl_isunreserved with ISUNRESERVED [2] - o FAQ: How do I upgrade curl.exe in Windows? [84] - o GHA/linux: run singleuse to detect single-use global functions [35] - o GHA: add workflow to compare configure vs cmake outputs [102] - o h2-proxy: remove left-over mistake in drain_tunnel() [7] - o h2: testcase and fix for pausing h2 streams [49] - o h3: add support for ngtcp2 with AWS-LC builds [103] - o http2: refused stream handling for retry [121] - o http: fix CURL_DISABLE_BEARER_AUTH breakage [28] - o http: h1/h2 proxy unification [21] - o http: remove wrong comment for http_should_fail [55] - o http: use per-request counter to check too large headers [6] - o http_aws_sigv4: fix sorting with empty parts [13] - o idn: fix WinIDN null ptr deref on bad host [90] - o idn: if idn2_check_version returns NULL, return error [27] - o inet_ntop: add typecast to silence Coverity [51] - o lib: disambiguate Curl_client_write flag semantics [24] - o lib: enable hmac for digest as well [26] - o lib: failf/infof compiler warnings [8] - o lib: let the max filesize option stop too big transfers too [44] - o lib: move handling of `data->req.writer_stack` into Curl_client_write() [97] - o lib: provide and use Curl_hexencode [62] - o lib: remove TIME_WITH_SYS_TIME [88] - o lib: use wrapper for curl_mime_data fseek callback [30] - o libssh2: fix error message on failed pubkey-from-file [22] - o libssh: cap SFTP packet size sent [14] - o Makefile.mk: always set `CURL_STATICLIB` for lib (Windows) [42] - o MANUAL.md: change domain to example.com [11] - o misc: better random strings [15] - o MQTT: improve receive of ACKs [125] - o multi: do CURLM_CALL_MULTI_PERFORM at two more places [99] - o multi: fix small timeouts [70] - o multi: remove Curl_multi_dump [37] - o multi: round the timeout up to prevent early wakeups [98] - o multi: set CURLM_CALL_MULTI_PERFORM after switch to DOING_MORE [115] - o openssl: improve ssl shutdown handling [69] - o openssl: use X509_ALGOR_get0 instead of reaching into X509_ALGOR [104] - o pytest: exclude test_03_goaway in CI runs due to timing dependency [23] - o quic: set ciphers/curves the same way regular TLS does [43] - o quiche: fix build error with --with-ca-fallback [1] - o RELEASE-PROCEDURE.md: updated coming release dates - o runtests: display the test status if tests appear hung [81] - o runtests: eliminate a warning on old perl versions - o socks: return error if hostname too long for remote resolve [118] - o src/mkhelp: make generated code pass `checksrc` [59] - o test1056: disable on Windows - o test1474: disable test on NetBSD, OpenBSD and Solaris 10 [31] - o test1592: greatly increase the maximum test timeout - o test1903: actually verify the cookies after the test [116] - o test1906: set a lower timeout since it's hit on Windows [117] - o test2600: remove special case handling for USE_ALARM_TIMEOUT [3] - o test650: fix an end tag typo - o test661: return from test early in case of curl error - o test: add missing s - o tests: close the shell used to start sshd [41] - o tests: fix a race condition in ftp server disconnect [101] - o tests: fix compiler warnings [38] - o tests: Fix zombie processes left behind by FTP tests. [80] - o tests: improve SLOWDOWN test reliability by reducing sent data - o tests: increase lib571 timeout from 3s to 30s [106] - o tests: log the test result code after each libtest - o tests: propagate errors in libtests - o tests: set --expect100-timeout to improve test reliability - o tests: show which curl tool `runtests.pl` is using [60] - o tests: stop overriding the lock timeout - o tftpd: always use curl's own tftp.h [25] - o tool: use our own stderr variable [94] - o tool_cb_wrt: fix debug assertion [4] - o tool_getparam: accept variable expansion on file names too [123] - o tool_setopt: remove unused function tool_setopt_flags [56] - o upload-file.d: describe the file name slash/backslash handling [9] - o url: fall back to http/https proxy env-variable if ws/wss not set [119] - o url: fix netrc info message [39] - o warnless: remove unused functions [33] - o wolfssh: do cleanup in Curl_ssh_cleanup [40] - o wolfssl: allow capath with CURLOPT_CAINFO_BLOB [29] - o wolfssl: if CURLOPT_CAINFO_BLOB is set, ignore the CA files [34] - o wolfssl: ignore errors in CA path [64] + o appveyor: make VS2008-built curl tool runnable [93] + o asyn-thread: use pipe instead of socketpair for IPC when available [4] + o autotools: accept linker flags via `CURL_LDFLAGS_{LIB,BIN}` [128] + o autotools: avoid passing `LDFLAGS` twice to libcurl [127] + o autotools: delete LCC compiler support bits [137] + o autotools: fix/improve gcc and Apple clang version detection [136] + o autotools: stop setting `-std=gnu89` with `--enable-warnings` [135] + o autotools: update references to deleted `crypt-auth` option [46] + o BINDINGS: add V binding [54] + o build: add `src/.checksrc` to source tarball [1] + o build: add more picky warnings and fix them [172] + o build: always revert `#pragma GCC diagnostic` after use [143] + o build: delete `HAVE_STDINT_H` and `HAVE_INTTYPES_H` [107] + o build: delete support bits for obsolete Windows compilers [106] + o build: fix 'threadsafe' feature detection for older gcc [19] + o build: fix builds that disable protocols but not digest auth [174] + o build: fix compiler warning with auths disabled [85] + o build: fix libssh2 + `CURL_DISABLE_DIGEST_AUTH` + `CURL_DISABLE_AWS` [120] + o build: picky warning updates [125] + o build: require Windows XP or newer [86] + o cfilter: provide call to tell connection to forget a socket [65] + o checksrc.pl: support #line instructions + o CI: add autotools, out-of-tree, debug build to distro check job [14] + o CI: ignore test 286 on Appveyor gcc 9 build [6] + o cmake: add `CURL_DISABLE_BINDLOCAL` option [146] + o cmake: add test for `DISABLE` options, add `CURL_DISABLE_HEADERS_API` [138] + o cmake: dedupe Windows system libs [114] + o cmake: fix `HAVE_H_ERRNO_ASSIGNABLE` detection [2] + o cmake: fix CURL_DISABLE_GETOPTIONS [12] + o cmake: fix multiple include of CURL package [96] + o cmake: fix OpenSSL quic detection in quiche builds [56] + o cmake: option to disable install & drop `curlu` target when unused [72] + o cmake: pre-fill rest of detection values for Windows [50] + o cmake: replace `check_library_exists_concat()` [23] + o cmake: speed up threads setup for Windows [68] + o cmake: speed up zstd detection [69] + o config-win32: set `HAVE_SNPRINTF` for mingw-w64 [123] + o configure: better --disable-http [80] + o configure: check for the fseeko declaration too [55] + o conncache: use the closure handle when disconnecting surplus connections [173] + o content_encoding: make Curl_all_content_encodings allocless [101] + o cookie: lowercase the domain names before PSL checks [160] + o curl.h: delete Symbian OS references [162] + o curl.h: on FreeBSD include sys/param.h instead of osreldate.h [21] + o curl.rc: switch out the copyright symbol for plain ASCII [167] + o curl: improved IPFS and IPNS URL support [87] + o curl_easy_duphandle.3: clarify how HSTS and alt-svc are duped [99] + o Curl_http_body: cleanup properly when Curl_getformdata errors [152] + o curl_setup: disallow Windows IPv6 builds missing getaddrinfo [57] + o curl_sspi: support more revocation error names in error messages [95] + o CURLINFO_PRETRANSFER_TIME_T.3: fix time explanation [181] + o CURLMOPT_MAX_CONCURRENT_STREAMS: make sure the set value is within range [165] + o CURLOPT_CAINFO_BLOB.3: explain what CURL_BLOB_COPY does [113] + o CURLOPT_WRITEFUNCTION.3: clarify libcurl returns for CURL_WRITEFUNC_ERROR [45] + o CURPOST_POSTFIELDS.3: add CURLOPT_COPYPOSTFIELDS in SEE ALSO + o docs/example/keepalive.c: show TCP keep-alive options [73] + o docs/example/localport.c: show off CURLOPT_LOCALPORT [83] + o docs/examples/interface.c: show CURLOPT_INTERFACE use [84] + o docs/libcurl: fix three minor man page format mistakes [26] + o docs/libcurl: SYNSOPSIS cleanup [150] + o docs: add supported version for the json write-out [92] + o docs: clarify that curl passes on input unfiltered [47] + o docs: fix function typo in curl_easy_option_next.3 [36] + o docs: KNOWN_BUGS cleanup + o docs: make all examples in all libcurl man pages compile [175] + o docs: preserve the modification date when copying the prebuilt man page [89] + o docs: remove bold from some man page SYNOPSIS sections [90] + o docs: use SOURCE_DATE_EPOCH for generated manpages [16] + o doh: provide better return code for responses w/o addresses [133] + o doh: use PIPEWAIT when HTTP/2 is attempted [63] + o duphandle: also free 'outcurl->cookies' in error path [122] + o duphandle: make dupset() not return with pointers to old alloced data [109] + o duphandle: use strdup to clone *COPYPOSTFIELDS if size is not set [132] + o easy: in duphandle, init the cookies for the new handle [131] + o easy: remove duplicate wolfSSH init call [37] + o easy_lock: add a pthread_mutex_t fallback [13] + o examples/rtsp-options.c: add [157] + o fopen: create new file using old file's mode [153] + o fopen: create short(er) temporary file name [155] + o getenv: PlayStation doesn't have getenv() [41] + o GHA: move mod_h2 version in CI to v2.0.25 [43] + o hostip: show the list of IPs when resolving is done [35] + o hostip: silence compiler warning `-Wparentheses-equality` [62] + o hsts: skip single-dot hostname [67] + o HTTP/2, HTTP/3: handle detach of onoing transfers [134] + o http2: header conversion tightening [33] + o http2: provide an error callback and failf the message [53] + o http2: safer invocation of populate_binsettings [8] + o http: allow longer HTTP/2 request method names [112] + o http: avoid Expect: 100-continue if Upgrade: is used [15] + o http: consider resume with CURLOPT_FAILONERRROR and 416 to be fine [81] + o http: fix `-Wunused-parameter` with no auth and no proxy [149] + o http: fix `-Wunused-variable` compiler warning [115] + o http: fix empty-body warning [76] + o http_aws_sigv4: canonicalise valueless query params [88] + o hyper: temporarily remove HTTP/2 support [139] + o INSTALL: update list of ports and CPU archs + o IPFS: fix IPFS_PATH and file parsing [119] + o keylog: disable if unused [145] + o lib: add and use Curl_strndup() [97] + o lib: apache style infof and trace macros/functions [71] + o lib: fix gcc warning in printf call [7] + o libcurl-errors.3: sync with current public headers [156] + o libcurl-thread.3: simplify the TLS section [79] + o Makefile.am: drop vc10, vc11 and vc12 projects from dist [103] + o Makefile.mk: fix `-rtmp` option for non-Windows + o mime: store "form escape" as a single bit [170] + o misc: fix -Walloc-size warnings [118] + o msh3: error when built with CURL_DISABLE_SOCKETPAIR set [61] + o multi: during ratelimit multi_getsock should return no sockets [182] + o multi: use pipe instead of socketpair to *wakeup() [18] + o ngtcp2: fix races in stream handling [178] + o ngtcp2: ignore errors on unknown streams [158] + o ntlm_wb: use pipe instead of socketpair when possible [44] + o openldap: move the alloc of ldapconninfo to *connect() [29] + o openldap: set the callback argument in oldap_do [30] + o openssl: avoid BN_num_bits() NULL pointer derefs [9] + o openssl: fix building with v3 `no-deprecated` + add CI test [161] + o openssl: fix infof() to avoid compiler warning for %s with null [70] + o openssl: identify the "quictls" backend correctly [82] + o openssl: include SIG and KEM algorithms in verbose [52] + o openssl: make CURLSSLOPT_NATIVE_CA import Windows intermediate CAs [58] + o openssl: two multi pointer checks should probably rather be asserts [91] + o openssl: when a session-ID is reused, skip OCSP stapling [142] + o page-footer: clarify exit code 25 [51] + o projects: add VC14.20 project files [104] + o pytest: use lower count in repeat tests [98] + o quic: make eyeballers connect retries stop at weird replies [140] + o quic: manage connection idle timeouts [5] + o quiche: use quiche_conn_peer_transport_params() [116] + o rand: fix build error with autotools + LibreSSL [111] + o resolve.d: drop a multi use-sentence [100] + o RTSP: improved RTP parser [32] + o rustls: implement connect_blocking [154] + o sasl: fix `-Wunused-function` compiler warning [124] + o schannel: add CA cache support for files and memory blobs [121] + o setopt: check CURLOPT_TFTP_BLKSIZE range on set [171] + o setopt: remove outdated cookie comment [64] + o setopt: remove superfluous use of ternary expressions [169] + o socks: better buffer size checks for socks4a user and hostname [20] + o socks: make SOCKS5 use the CURLOPT_IPRESOLVE choice [38] + o symbols-in-versions: the CLOSEPOLICY options are deprecated + o test1683: remove commented-out check alternatives + o test3103: add missing quotes around a test tag attribute + o test613: stop showing an error on missing output file + o tests/README: SOCKS tests are not using OpenSSH, it has its own server [48] + o tests/server: add more SOCKS5 handshake error checking [27] + o tests: Fix Windows test helper tool search & use it for handle64 [17] + o tidy-up: casing typos, delete unused Windows version aliases [144] + o tool: fix --capath when proxy support is disabled [28] + o tool: support bold headers in Windows [117] + o tool_cb_hdr: add an additional parsing check [129] + o tool_cb_prg: make the carriage return fit for wide progress bars [159] + o tool_cb_wrt: fix write output for very old Windows versions [24] + o tool_getparam: limit --rate to be smaller than number of ms [3] + o tool_operate: do not mix memory models [108] + o tool_operate: fix links in ipfs errors [22] + o tool_parsecfg: make warning output propose double-quoting [164] + o tool_urlglob: fix build for old gcc versions [25] + o tool_urlglob: make multiply() bail out on negative values [11] + o tool_writeout_json: fix JSON encoding of non-ascii bytes [179] + o transfer: abort pause send when connection is marked for closing [183] + o transfer: avoid calling the read callback again after EOF [130] + o transfer: only reset the FTP wildcard engine in CLEAR state [42] + o url: don't touch the multi handle when closing internal handles [40] + o url: find scheme with a "perfect hash" [141] + o url: fix `-Wzero-length-array` with no protocols [147] + o url: fix builds with `CURL_DISABLE_HTTP` [148] + o url: protocol handler lookup tidy-up [66] + o url: proxy ssl connection reuse fix [94] + o urlapi: avoid null deref if setting blank host to url encode [75] + o urlapi: skip appending NULL pointer query [74] + o urlapi: when URL encoding the fragment, pass in the right length [59] + o urldata: make maxconnects a 32 bit value [166] + o urldata: move async resolver state from easy handle to connectdata [34] + o urldata: move cookielist from UserDefined to UrlState [126] + o urldata: move hstslist from 'set' to 'state' [105] + o urldata: move the 'internal' boolean to the state struct [39] + o vssh: remove the #ifdef for Curl_ssh_init, use empty macro + o vtls: cleanup SSL config management [78] + o vtls: consistently use typedef names for OpenSSL structs [176] + o vtls: late clone of connection ssl config [60] + o vtls: use ALPN "http/1.1" for HTTP/1.x, including HTTP/1.0 [102] + o VULN-DISCLOSURE-POLICY: escape sequences are not a security flaw [110] + o windows: use built-in `_WIN32` macro to detect Windows [163] + o wolfssh: remove redundant static prototypes [168] + o wolfssl: add default case for wolfssl_connect_step1 switch [49] + o wolfssl: require WOLFSSL_SYS_CA_CERTS for loading system CA [10] This release includes the following known bugs: @@ -164,143 +215,204 @@ Planned upcoming removals include: This release would not have looked like this without help, code, reports and advice from friends like these: - Aleksander Mazur, black-desk on github, calvin2021y on github, - Christian Schmitz, Christian Weisgerber, claudiusaiz on github, - consulion on github, Craig Andrews, Dan Fandrich, Daniel Stenberg, - David Benjamin, Douglas R. Reno, Eduard Strehlau, Elliot Killick, - Gisle Vanem, Hakan Sunay Halil, Harry Sintonen, Jakub Jelen, John Haugabook, - Joshix-1 on github, Juliusz Sosinowicz, Junho Choi, - Karthikdasari0423 on github, Lars Francke, Loïc Yhuel, Marc Hörsken, - Mark Gaiser, Mathias Fuchs, Maxim Dzhura, Michael Osipov, Natanael Copa, - Patrick Monnerat, PBudmark on github, Peter Wang, Philip Heiduck, Ray Satiro, - Robert Simpson, Ryan Schmidt, s0urc3_ on hackerone, Samuel Henrique, - Stefan Eissing, Ted Lyngmo, Viktor Szakats, vvb2060, w0x42 on hackerone, - 南宫雪珊 - (46 contributors) + 12932 on github, Alex Bozarth, Alexey Larikov, Alex Klyubin, Ammar Faizi, + Andrew Kurushin, Anubhav Rai, boilingoden, calvin2021y on github, + Carlos Henrique Lima Melara, Casey Bodley, Charlie C, Dan Fandrich, + Daniel Jeliński, Daniel Stenberg, David Benjamin, David Suter, Dmitry Karpov, + eeverettrbx on github, Emanuele Torre, Enno Boland, enWILLYado on github, + Faraz Fallahi, Gisle Vanem, Goro FUJI, Graham Campbell, Harry Mallon, + Harry Sintonen, iconoclasthero, icy17 on github, Jacob Hoffman-Andrews, + Jan Alexander Steffens, Jeroen Ooms, Jiehong on github, Jiri Hruska, + Junho Choi, Kai Pastor, Kareem, Kartatz on Github, kirbyn17 on hackerone, + Lau, lkordos on github, Loïc Yhuel, LoRd_MuldeR, lRoccoon on github, + Maksymilian Arciemowicz, Manfred Schwarb, Marcel Raad, Marcin Rataj, + Mark Gaiser, Martin Schmatz, Michael Kaufmann, Michał Antoniak, Nico Rieck, + Niracler Li, ohyeaah on github, Ophir Lojkine, Paweł Wegner, Philip Heiduck, + Ray Satiro, rilysh, Robert Southee, Romain Geissler, Sam James, + Samuel Henrique, sd0 on hackerone, Smackd0wn, Sohom Datta, Stefan Eissing, + Steven Allen, Tim Hill, Torben Dury, Turiiya, Viktor Szakats, + yushicheng7788 on github, z2_, zhengqwe on github, 積丹尼 Dan Jacobson + (78 contributors) References to bug reports and discussions on issues: - [1] = https://curl.se/bug/?i=11850 - [2] = https://curl.se/bug/?i=11846 - [3] = https://curl.se/bug/?i=11767 - [4] = https://github.com/curl/curl/commit/af3f4e41#r127212213 - [5] = https://curl.se/bug/?i=11875 - [6] = https://curl.se/bug/?i=11871 - [7] = https://curl.se/bug/?i=11877 - [8] = https://curl.se/bug/?i=11874 - [9] = https://curl.se/bug/?i=11911 - [10] = https://curl.se/bug/?i=11843 - [11] = https://curl.se/bug/?i=11866 - [12] = https://curl.se/bug/?i=11864 - [13] = https://curl.se/bug/?i=11855 - [14] = https://curl.se/bug/?i=11804 - [15] = https://curl.se/bug/?i=11838 - [16] = https://curl.se/bug/?i=11862 - [17] = https://curl.se/bug/?i=11862 - [18] = https://curl.se/bug/?i=11905 - [19] = https://curl.se/bug/?i=11909 - [20] = https://curl.se/bug/?i=11750 - [21] = https://curl.se/bug/?i=11808 - [22] = https://curl.se/bug/?i=11837 - [23] = https://curl.se/bug/?i=11860 - [24] = https://curl.se/bug/?i=11885 - [25] = https://curl.se/bug/?i=11897 - [26] = https://curl.se/bug/?i=11890 - [27] = https://curl.se/bug/?i=11898 - [28] = https://curl.se/bug/?i=11892 - [29] = https://curl.se/bug/?i=11886 - [30] = https://curl.se/bug/?i=11882 - [31] = https://curl.se/bug/?i=11888 - [32] = https://curl.se/bug/?i=11893 - [33] = https://curl.se/bug/?i=11932 - [34] = https://curl.se/bug/?i=11884 - [35] = https://curl.se/bug/?i=11932 - [36] = https://curl.se/bug/?i=12003 - [37] = https://curl.se/bug/?i=11931 - [38] = https://curl.se/bug/?i=11925 - [39] = https://curl.se/bug/?i=11904 - [40] = https://curl.se/bug/?i=11921 - [41] = https://curl.se/bug/?i=12032 - [42] = https://curl.se/bug/?i=11924 - [43] = https://curl.se/bug/?i=11796 - [44] = https://curl.se/bug/?i=11810 - [45] = https://curl.se/bug/?i=11625 - [46] = https://curl.se/bug/?i=8805 - [47] = https://curl.se/bug/?i=11915 - [48] = https://curl.se/bug/?i=11912 - [49] = https://curl.se/bug/?i=11982 - [50] = https://curl.se/bug/?i=11998 - [51] = https://curl.se/bug/?i=11960 - [52] = https://curl.se/bug/?i=11957 - [53] = https://curl.se/bug/?i=11997 - [54] = https://curl.se/bug/?i=11920 - [55] = https://curl.se/bug/?i=11941 - [56] = https://curl.se/bug/?i=11943 - [57] = https://curl.se/bug/?i=11954 - [58] = https://curl.se/bug/?i=11951 - [59] = https://curl.se/bug/?i=11955 - [60] = https://curl.se/bug/?i=11953 - [61] = https://curl.se/bug/?i=11996 - [62] = https://curl.se/bug/?i=11990 - [63] = https://curl.se/bug/?i=11987 - [64] = https://curl.se/bug/?i=11987 - [65] = https://curl.se/bug/?i=11940 - [66] = https://curl.se/bug/?i=11991 - [67] = https://curl.se/bug/?i=11994 - [68] = https://curl.se/bug/?i=2935 - [69] = https://curl.se/bug/?i=11858 - [70] = https://curl.se/bug/?i=11937 - [71] = https://curl.se/bug/?i=11929 - [72] = https://curl.se/bug/?i=11927 - [73] = https://curl.se/bug/?i=11926 - [74] = https://curl.se/bug/?i=11914 - [75] = https://curl.se/bug/?i=11981 - [76] = https://curl.se/bug/?i=11979 - [77] = https://curl.se/bug/?i=11978 - [78] = https://curl.se/bug/?i=12010 - [79] = https://curl.se/bug/?i=11988 - [80] = https://curl.se/bug/?i=12018 - [81] = https://curl.se/bug/?i=11980 - [82] = https://curl.se/bug/?i=11986 - [83] = https://curl.se/bug/?i=11985 - [84] = https://curl.se/bug/?i=11984 - [85] = https://curl.se/bug/?i=11974 - [86] = https://curl.se/bug/?i=11973 - [87] = https://curl.se/bug/?i=11973 - [88] = https://curl.se/bug/?i=11975 - [89] = https://curl.se/bug/?i=11963 - [90] = https://curl.se/bug/?i=11983 - [91] = https://curl.se/bug/?i=11977 - [92] = https://curl.se/bug/?i=12024 - [93] = https://curl.se/bug/?i=11967 - [94] = https://curl.se/bug/?i=11958 - [95] = https://curl.se/bug/?i=11939 - [96] = https://curl.se/bug/?i=12027 - [97] = https://curl.se/bug/?i=11908 - [98] = https://curl.se/bug/?i=11938 - [99] = https://curl.se/bug/?i=12033 - [100] = https://curl.se/bug/?i=12059 - [101] = https://curl.se/bug/?i=12002 - [102] = https://curl.se/bug/?i=11964 - [103] = https://curl.se/bug/?i=12066 - [104] = https://curl.se/bug/?i=12038 - [105] = https://curl.se/bug/?i=12015 - [106] = https://curl.se/bug/?i=12013 - [107] = https://curl.se/bug/?i=11928 - [108] = https://curl.se/bug/?i=12005 - [109] = https://curl.se/bug/?i=11999 - [110] = https://curl.se/bug/?i=12006 - [111] = https://curl.se/bug/?i=12008 - [112] = https://curl.se/mail/lib-2023-10/0010.html - [113] = https://curl.se/bug/?i=12045 - [114] = https://curl.se/bug/?i=12065 - [115] = https://curl.se/bug/?i=12042 - [116] = https://curl.se/bug/?i=12041 - [117] = https://curl.se/bug/?i=12036 - [118] = https://curl.se/docs/CVE-2023-38545.html - [119] = https://curl.se/bug/?i=12031 - [120] = https://curl.se/bug/?i=12035 - [121] = https://curl.se/bug/?i=12054 - [122] = https://curl.se/bug/?i=12034 - [123] = https://curl.se/bug/?i=12048 - [125] = https://curl.se/bug/?i=12071 + [1] = https://curl.se/bug/?i=12084 + [2] = https://curl.se/bug/?i=12093 + [3] = https://curl.se/bug/?i=12116 + [4] = https://curl.se/bug/?i=12146 + [5] = https://curl.se/bug/?i=12064 + [6] = https://curl.se/bug/?i=12040 + [7] = https://curl.se/bug/?i=12082 + [8] = https://curl.se/bug/?i=12101 + [9] = https://curl.se/bug/?i=12099 + [10] = https://curl.se/bug/?i=12108 + [11] = https://curl.se/bug/?i=12102 + [12] = https://curl.se/bug/?i=12091 + [13] = https://curl.se/bug/?i=12090 + [14] = https://curl.se/bug/?i=12088 + [15] = https://curl.se/bug/?i=12022 + [16] = https://curl.se/bug/?i=12092 + [17] = https://curl.se/bug/?i=12115 + [18] = https://curl.se/bug/?i=12142 + [19] = https://curl.se/bug/?i=12125 + [20] = https://curl.se/bug/?i=12139 + [21] = https://curl.se/bug/?i=12107 + [22] = https://curl.se/bug/?i=12133 + [23] = https://curl.se/bug/?i=11285 + [24] = https://curl.se/bug/?i=12131 + [25] = https://curl.se/bug/?i=12124 + [26] = https://curl.se/bug/?i=12126 + [27] = https://curl.se/bug/?i=12117 + [28] = https://curl.se/bug/?i=12089 + [29] = https://curl.se/bug/?i=12166 + [30] = https://curl.se/bug/?i=12166 + [31] = https://curl.se/bug/?i=12137 + [32] = https://curl.se/bug/?i=12052 + [33] = https://curl.se/bug/?i=12097 + [34] = https://curl.se/bug/?i=12198 + [35] = https://curl.se/bug/?i=12145 + [36] = https://curl.se/bug/?i=12170 + [37] = https://curl.se/bug/?i=12168 + [38] = https://curl.se/bug/?i=11949 + [39] = https://curl.se/bug/?i=12165 + [40] = https://curl.se/bug/?i=12165 + [41] = https://curl.se/bug/?i=12140 + [42] = https://curl.se/bug/?i=11775 + [43] = https://curl.se/bug/?i=12157 + [44] = https://curl.se/bug/?i=12149 + [45] = https://curl.se/bug/?i=12201 + [46] = https://curl.se/bug/?i=12194 + [47] = https://curl.se/bug/?i=12249 + [48] = https://curl.se/bug/?i=12195 + [49] = https://curl.se/bug/?i=12218 + [50] = https://curl.se/bug/?i=12044 + [51] = https://curl.se/bug/?i=12189 + [52] = https://curl.se/bug/?i=12030 + [53] = https://curl.se/bug/?i=12179 + [54] = https://curl.se/bug/?i=12182 + [55] = https://curl.se/bug/?i=12086 + [56] = https://curl.se/bug/?i=12160 + [57] = https://curl.se/bug/?i=12221 + [58] = https://curl.se/bug/?i=12155 + [59] = https://curl.se/bug/?i=12250 + [60] = https://curl.se/bug/?i=12237 + [61] = https://curl.se/bug/?i=12213 + [62] = https://curl.se/bug/?i=12215 + [63] = https://curl.se/bug/?i=12214 + [64] = https://curl.se/bug/?i=12206 + [65] = https://curl.se/bug/?i=12207 + [66] = https://curl.se/bug/?i=12216 + [67] = https://curl.se/bug/?i=12247 + [68] = https://curl.se/bug/?i=12202 + [69] = https://curl.se/bug/?i=12200 + [70] = https://curl.se/bug/?i=12196 + [71] = https://curl.se/bug/?i=12083 + [72] = https://curl.se/bug/?i=12287 + [73] = https://curl.se/bug/?i=12242 + [74] = https://curl.se/bug/?i=12240 + [75] = https://curl.se/bug/?i=12240 + [76] = https://curl.se/bug/?i=12262 + [77] = https://curl.se/bug/?i=12235 + [78] = https://curl.se/bug/?i=12204 + [79] = https://curl.se/bug/?i=12233 + [80] = https://curl.se/bug/?i=12223 + [81] = https://curl.se/bug/?i=10521 + [82] = https://curl.se/bug/?i=12270 + [83] = https://curl.se/bug/?i=12230 + [84] = https://curl.se/bug/?i=12229 + [85] = https://curl.se/bug/?i=12227 + [86] = https://curl.se/bug/?i=12225 + [87] = https://curl.se/bug/?i=12148 + [88] = https://curl.se/bug/?i=8107 + [89] = https://curl.se/bug/?i=12199 + [90] = https://curl.se/bug/?i=12267 + [91] = https://curl.se/bug/?i=12264 + [92] = https://curl.se/bug/?i=12266 + [93] = https://curl.se/bug/?i=12263 + [94] = https://curl.se/bug/?i=12255 + [95] = https://curl.se/bug/?i=12239 + [96] = https://curl.se/bug/?i=11913 + [97] = https://curl.se/bug/?i=12251 + [98] = https://curl.se/bug/?i=12248 + [99] = https://curl.se/bug/?i=12315 + [100] = https://curl.se/bug/?i=12294 + [101] = https://curl.se/bug/?i=12289 + [102] = https://curl.se/bug/?i=12259 + [103] = https://curl.se/bug/?i=12288 + [104] = https://curl.se/bug/?i=12282 + [105] = https://curl.se/bug/?i=12315 + [106] = https://curl.se/bug/?i=12222 + [107] = https://curl.se/bug/?i=12275 + [108] = https://curl.se/bug/?i=12280 + [109] = https://curl.se/bug/?i=12337 + [110] = https://curl.se/bug/?i=12278 + [111] = https://curl.se/bug/?i=12257 + [112] = https://curl.se/bug/?i=12311 + [113] = https://curl.se/bug/?i=12277 + [114] = https://curl.se/bug/?i=12307 + [115] = https://curl.se/bug/?i=12228 + [116] = https://curl.se/bug/?i=12180 + [117] = https://curl.se/bug/?i=12321 + [118] = https://curl.se/bug/?i=12292 + [119] = https://curl.se/bug/?i=12152 + [120] = https://curl.se/bug/?i=12273 + [121] = https://curl.se/bug/?i=12261 + [122] = https://curl.se/bug/?i=12329 + [123] = https://curl.se/bug/?i=12325 + [124] = https://curl.se/bug/?i=12326 + [125] = https://curl.se/bug/?i=12324 + [126] = https://curl.se/bug/?i=12323 + [127] = https://curl.se/bug/?i=12310 + [128] = https://curl.se/bug/?i=12312 + [129] = https://curl.se/bug/?i=12320 + [130] = https://curl.se/mail/lib-2023-11/0017.html + [131] = https://curl.se/bug/?i=12318 + [132] = https://curl.se/bug/?i=12317 + [133] = https://curl.se/bug/?i=12365 + [134] = https://curl.se/bug/?i=12356 + [135] = https://curl.se/bug/?i=12346 + [136] = https://curl.se/bug/?i=12362 + [137] = https://curl.se/bug/?i=12357 + [138] = https://curl.se/bug/?i=12353 + [139] = https://curl.se/bug/?i=12191 + [140] = https://curl.se/bug/?i=12400 + [141] = https://curl.se/bug/?i=12347 + [142] = https://curl.se/bug/?i=12399 + [143] = https://curl.se/bug/?i=12352 + [144] = https://curl.se/bug/?i=12351 + [145] = https://curl.se/bug/?i=12350 + [146] = https://curl.se/bug/?i=12345 + [147] = https://curl.se/bug/?i=12344 + [148] = https://curl.se/bug/?i=12343 + [149] = https://curl.se/bug/?i=12338 + [150] = https://curl.se/bug/?i=12402 + [152] = https://curl.se/bug/?i=12410 + [153] = https://curl.se/bug/?i=12299 + [154] = https://curl.se/bug/?i=11647 + [155] = https://curl.se/bug/?i=12388 + [156] = https://curl.se/bug/?i=12424 + [157] = https://curl.se/bug/?i=12452 + [158] = https://curl.se/bug/?i=12449 + [159] = https://curl.se/bug/?i=12407 + [160] = https://curl.se/bug/?i=12387 + [161] = https://curl.se/bug/?i=12384 + [162] = https://curl.se/bug/?i=12378 + [163] = https://curl.se/bug/?i=12376 + [164] = https://curl.se/bug/?i=12409 + [165] = https://curl.se/bug/?i=12382 + [166] = https://curl.se/bug/?i=12375 + [167] = https://curl.se/bug/?i=12403 + [168] = https://curl.se/bug/?i=12381 + [169] = https://curl.se/bug/?i=12374 + [170] = https://curl.se/bug/?i=12374 + [171] = https://curl.se/bug/?i=12374 + [172] = https://curl.se/bug/?i=12331 + [173] = https://curl.se/bug/?i=12367 + [174] = https://curl.se/bug/?i=12440 + [175] = https://curl.se/bug/?i=12448 + [176] = https://curl.se/bug/?i=12439 + [178] = https://curl.se/bug/?i=12435 + [179] = https://curl.se/bug/?i=12434 + [181] = https://curl.se/bug/?i=12431 + [182] = https://curl.se/bug/?i=12430 + [183] = https://curl.se/bug/?i=12428 diff --git a/acinclude.m4 b/acinclude.m4 index 5fdd51e52..ac026e39d 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -705,10 +705,10 @@ AC_DEFUN([TYPE_SOCKADDR_STORAGE], #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #else #ifdef HAVE_SYS_TYPES_H #include @@ -743,10 +743,10 @@ AC_DEFUN([CURL_CHECK_FUNC_RECV], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #else $curl_includes_bsdsocket #ifdef HAVE_SYS_TYPES_H @@ -794,10 +794,10 @@ AC_DEFUN([CURL_CHECK_FUNC_SEND], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #else $curl_includes_bsdsocket #ifdef HAVE_SYS_TYPES_H @@ -841,10 +841,10 @@ AC_DEFUN([CURL_CHECK_MSG_NOSIGNAL], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #else #ifdef HAVE_SYS_TYPES_H #include @@ -886,10 +886,10 @@ AC_DEFUN([CURL_CHECK_STRUCT_TIMEVAL], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #endif #ifdef HAVE_SYS_TYPES_H #include @@ -941,10 +941,10 @@ AC_DEFUN([TYPE_IN_ADDR_T], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #else #ifdef HAVE_SYS_TYPES_H #include @@ -983,10 +983,10 @@ AC_DEFUN([TYPE_IN_ADDR_T], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #else #ifdef HAVE_SYS_TYPES_H #include @@ -1298,10 +1298,10 @@ AC_DEFUN([CURL_CHECK_FUNC_SELECT], [ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #endif #ifdef HAVE_SYS_TYPES_H #include @@ -1374,70 +1374,6 @@ int main() ]) -dnl CURL_CHECK_VARIADIC_MACROS -dnl ------------------------------------------------- -dnl Check compiler support of variadic macros - -AC_DEFUN([CURL_CHECK_VARIADIC_MACROS], [ - AC_CACHE_CHECK([for compiler support of C99 variadic macro style], - [curl_cv_variadic_macros_c99], [ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__) -#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__) - int fun3(int arg1, int arg2, int arg3); - int fun2(int arg1, int arg2); - int fun3(int arg1, int arg2, int arg3) - { return arg1 + arg2 + arg3; } - int fun2(int arg1, int arg2) - { return arg1 + arg2; } - ]],[[ - int res3 = c99_vmacro3(1, 2, 3); - int res2 = c99_vmacro2(1, 2); - ]]) - ],[ - curl_cv_variadic_macros_c99="yes" - ],[ - curl_cv_variadic_macros_c99="no" - ]) - ]) - case "$curl_cv_variadic_macros_c99" in - yes) - AC_DEFINE_UNQUOTED(HAVE_VARIADIC_MACROS_C99, 1, - [Define to 1 if compiler supports C99 variadic macro style.]) - ;; - esac - AC_CACHE_CHECK([for compiler support of old gcc variadic macro style], - [curl_cv_variadic_macros_gcc], [ - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#define gcc_vmacro3(first, args...) fun3(first, args) -#define gcc_vmacro2(first, args...) fun2(first, args) - int fun3(int arg1, int arg2, int arg3); - int fun2(int arg1, int arg2); - int fun3(int arg1, int arg2, int arg3) - { return arg1 + arg2 + arg3; } - int fun2(int arg1, int arg2) - { return arg1 + arg2; } - ]],[[ - int res3 = gcc_vmacro3(1, 2, 3); - int res2 = gcc_vmacro2(1, 2); - ]]) - ],[ - curl_cv_variadic_macros_gcc="yes" - ],[ - curl_cv_variadic_macros_gcc="no" - ]) - ]) - case "$curl_cv_variadic_macros_gcc" in - yes) - AC_DEFINE_UNQUOTED(HAVE_VARIADIC_MACROS_GCC, 1, - [Define to 1 if compiler supports old gcc variadic macro style.]) - ;; - esac -]) - - dnl CURL_CHECK_CA_BUNDLE dnl ------------------------------------------------- dnl Check if a default ca-bundle should be used diff --git a/configure.ac b/configure.ac index 2d71c838f..d9b396376 100644 --- a/configure.ac +++ b/configure.ac @@ -174,7 +174,7 @@ curl_headers_msg="enabled (--disable-headers-api)" curl_ws_msg="no (--enable-websockets)" ssl_backends= curl_h1_msg="enabled (internal)" - curl_h2_msg="no (--with-nghttp2, --with-hyper)" + curl_h2_msg="no (--with-nghttp2)" curl_h3_msg="no (--with-ngtcp2 --with-nghttp3, --with-quiche, --with-msh3)" enable_altsvc="yes" @@ -803,7 +803,6 @@ if test X"$want_hyper" != Xno; then experimental="$experimental Hyper" AC_MSG_NOTICE([Hyper support is experimental]) curl_h1_msg="enabled (Hyper)" - curl_h2_msg=$curl_h1_msg HYPER_ENABLED=1 AC_DEFINE(USE_HYPER, 1, [if hyper is in use]) AC_SUBST(USE_HYPER, [1]) @@ -1145,10 +1144,10 @@ then #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include #ifdef HAVE_WINSOCK2_H #include #endif +#include #endif ]],[[ gethostbyname("localhost"); @@ -3099,7 +3098,6 @@ if test X"$want_nghttp3" != Xno; then CURL_LIBRARY_PATH="$CURL_LIBRARY_PATH:$DIR_NGHTTP3" export CURL_LIBRARY_PATH AC_MSG_NOTICE([Added $DIR_NGHTTP3 to CURL_LIBRARY_PATH]) - experimental="$experimental HTTP3" ) ], dnl not found, revert back to clean variables @@ -3418,7 +3416,6 @@ dnl default includes dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST -CURL_CHECK_VARIADIC_MACROS AC_TYPE_SIZE_T CURL_CHECK_STRUCT_TIMEVAL @@ -3581,11 +3578,9 @@ AC_CHECK_DECLS([getpwuid_r], [], [AC_DEFINE(HAVE_DECL_GETPWUID_R_MISSING, 1, "Se [[#include #include ]]) - AC_CHECK_FUNCS([\ _fseeki64 \ arc4random \ - fchmod \ fnmatch \ fseeko \ geteuid \ @@ -3628,6 +3623,15 @@ AC_CHECK_FUNCS([\ fi ]) +dnl On Android, the only way to know if fseeko can be used is to see if it is +dnl declared or not (for this API level), as the symbol always exists in the +dnl lib. +AC_CHECK_DECL([fseeko], + [AC_DEFINE([HAVE_DECL_FSEEKO], [1], + [Define to 1 if you have the fseeko declaration])], + [], + [[#include ]]) + CURL_CHECK_NONBLOCKING_SOCKET dnl ************************************************************ @@ -4570,7 +4574,7 @@ if test "x$USE_TLS_SRP" = "x1"; then SUPPORT_FEATURES="$SUPPORT_FEATURES TLS-SRP" fi -if test "x$USE_NGHTTP2" = "x1" -o "x$USE_HYPER" = "x1"; then +if test "x$USE_NGHTTP2" = "x1"; then SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2" fi @@ -4583,20 +4587,31 @@ if test "x$CURL_WITH_MULTI_SSL" = "x1"; then SUPPORT_FEATURES="$SUPPORT_FEATURES MultiSSL" fi +AC_MSG_CHECKING([if this build supports HTTPS-proxy]) dnl if not explicitly turned off, HTTPS-proxy comes with some TLS backends -if test "x$https_proxy" != "xno"; then - if test "x$OPENSSL_ENABLED" = "x1" \ - -o "x$GNUTLS_ENABLED" = "x1" \ - -o "x$SECURETRANSPORT_ENABLED" = "x1" \ - -o "x$RUSTLS_ENABLED" = "x1" \ - -o "x$BEARSSL_ENABLED" = "x1" \ - -o "x$SCHANNEL_ENABLED" = "x1" \ - -o "x$GNUTLS_ENABLED" = "x1" \ - -o "x$MBEDTLS_ENABLED" = "x1"; then - SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" - elif test "x$WOLFSSL_ENABLED" = "x1" -a "x$WOLFSSL_FULL_BIO" = "x1"; then - SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" +if test "x$CURL_DISABLE_HTTP" != "x1"; then + if test "x$https_proxy" != "xno"; then + if test "x$OPENSSL_ENABLED" = "x1" \ + -o "x$GNUTLS_ENABLED" = "x1" \ + -o "x$SECURETRANSPORT_ENABLED" = "x1" \ + -o "x$RUSTLS_ENABLED" = "x1" \ + -o "x$BEARSSL_ENABLED" = "x1" \ + -o "x$SCHANNEL_ENABLED" = "x1" \ + -o "x$GNUTLS_ENABLED" = "x1" \ + -o "x$MBEDTLS_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" + AC_MSG_RESULT([yes]) + elif test "x$WOLFSSL_ENABLED" = "x1" -a "x$WOLFSSL_FULL_BIO" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + else + AC_MSG_RESULT([no]) fi +else + AC_MSG_RESULT([no]) fi if test "x$ECH_ENABLED" = "x1"; then @@ -4612,6 +4627,9 @@ fi if test "$tst_atomic" = "yes"; then SUPPORT_FEATURES="$SUPPORT_FEATURES threadsafe" +elif test "x$USE_THREADS_POSIX" = "x1" -a \ + "x$ac_cv_header_pthread_h" = "xyes"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES threadsafe" else AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ diff --git a/docs/BINDINGS.md b/docs/BINDINGS.md index 57f87a5f8..7f5da4219 100644 --- a/docs/BINDINGS.md +++ b/docs/BINDINGS.md @@ -125,6 +125,8 @@ Ruby: [curb](https://github.com/taf2/curb) written by Ross Bamford, [Tcl](https://web.archive.org/web/20160826011806/mirror.yellow5.com/tclcurl/) Tclcurl by Andrés García +[Vibe](https://github.com/ttytm/vibe) HTTP requests through libcurl in V + [Visual Basic](https://sourceforge.net/projects/libcurl-vb/) libcurl-vb by Jeffrey Phillips [Visual Foxpro](https://web.archive.org/web/20130730181523/www.ctl32.com.ar/libcurl.asp) by Carlos Alloatti diff --git a/docs/DEPRECATE.md b/docs/DEPRECATE.md index c932fadbc..4cd5a22ce 100644 --- a/docs/DEPRECATE.md +++ b/docs/DEPRECATE.md @@ -6,6 +6,17 @@ email the as soon as possible and explain to us why this is a problem for you and how your use case cannot be satisfied properly using a workaround. +## NTLM_WB auth + +This NTLM authentication method is powered by a separate tool, +`ntlm_auth`. Barely anyone uses this method. It was always a quirky +implementation (including fork + exec), it has limited portability and we +don't test it in the test suite and CI. + +We keep the native NTLM implementation. + +curl will remove the support for NTLM_WB auth in June 2024. + ## space-separated `NOPROXY` patterns When specifying patterns/domain names for curl that should *not* go through a diff --git a/docs/EXPERIMENTAL.md b/docs/EXPERIMENTAL.md index 6b7145df6..de694013d 100644 --- a/docs/EXPERIMENTAL.md +++ b/docs/EXPERIMENTAL.md @@ -19,6 +19,6 @@ Experimental support in curl means: ## Experimental features right now - The Hyper HTTP backend - - HTTP/3 support and options + - HTTP/3 support (using the quiche or msh3 backends) - The rustls backend - WebSocket diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 9f763d3a7..05364aaf3 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -12,7 +12,7 @@ ## libcurl - - full URL syntax with no length limit + - URL RFC 3986 syntax - custom maximum download time - custom least download speed acceptable - custom output result after completion diff --git a/docs/HTTP3.md b/docs/HTTP3.md index 41d757f05..7f2f08ada 100644 --- a/docs/HTTP3.md +++ b/docs/HTTP3.md @@ -9,18 +9,19 @@ book describing the protocols involved. ## QUIC libraries -QUIC libraries we are experimenting with: +QUIC libraries we are using: [ngtcp2](https://github.com/ngtcp2/ngtcp2) -[quiche](https://github.com/cloudflare/quiche) +[quiche](https://github.com/cloudflare/quiche) - **EXPERIMENTAL** -[msh3](https://github.com/nibanks/msh3) (with [msquic](https://github.com/microsoft/msquic)) +[msh3](https://github.com/nibanks/msh3) (with [msquic](https://github.com/microsoft/msquic)) - **EXPERIMENTAL** ## Experimental -HTTP/3 and QUIC support in curl is considered **EXPERIMENTAL** until further -notice. It needs to be enabled at build-time. +HTTP/3 support in curl is considered **EXPERIMENTAL** until further notice +when built to use *quiche* or *msh3*. Only the *ngtcp2* backend is not +experimental. Further development and tweaking of the HTTP/3 support in curl will happen in the master branch using pull-requests, just like ordinary changes. @@ -34,16 +35,17 @@ To fix before we remove the experimental label: Building curl with ngtcp2 involves 3 components: `ngtcp2` itself, `nghttp3` and a QUIC supporting TLS library. The supported TLS libraries are covered below. -For now, `ngtcp2` and `nghttp3` are still *experimental* which means their evolution bring breaking changes. Therefore, the proper version of both libraries need to be used when building curl. These are + * `ngtcp2`: v1.1.0 + * `nghttp3`: v1.1.0 - * `ngtcp2`: v0.19.1 - * `nghttp3`: v0.15.0 +## Build with quictls -## Build with OpenSSL +OpenSSL does not offer the required APIs for building a QUIC client. You need +to use a TLS library that has such APIs and that works with *ngtcp2*. -Build (patched) OpenSSL +Build quictls - % git clone --depth 1 -b openssl-3.0.10+quic https://github.com/quictls/openssl + % git clone --depth 1 -b openssl-3.1.4+quic https://github.com/quictls/openssl % cd openssl % ./config enable-tls1_3 --prefix= % make @@ -52,7 +54,7 @@ Build (patched) OpenSSL Build nghttp3 % cd .. - % git clone -b v0.15.0 https://github.com/ngtcp2/nghttp3 + % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 % cd nghttp3 % autoreconf -fi % ./configure --prefix= --enable-lib-only @@ -62,7 +64,7 @@ Build nghttp3 Build ngtcp2 % cd .. - % git clone -b v0.19.1 https://github.com/ngtcp2/ngtcp2 + % git clone -b v1.1.0 https://github.com/ngtcp2/ngtcp2 % cd ngtcp2 % autoreconf -fi % ./configure PKG_CONFIG_PATH=/lib/pkgconfig:/lib/pkgconfig LDFLAGS="-Wl,-rpath,/lib" --prefix= --enable-lib-only @@ -95,7 +97,7 @@ Build GnuTLS Build nghttp3 % cd .. - % git clone -b v0.15.0 https://github.com/ngtcp2/nghttp3 + % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 % cd nghttp3 % autoreconf -fi % ./configure --prefix= --enable-lib-only @@ -105,7 +107,7 @@ Build nghttp3 Build ngtcp2 % cd .. - % git clone -b v0.19.1 https://github.com/ngtcp2/ngtcp2 + % git clone -b v1.1.0 https://github.com/ngtcp2/ngtcp2 % cd ngtcp2 % autoreconf -fi % ./configure PKG_CONFIG_PATH=/lib/pkgconfig:/lib/pkgconfig LDFLAGS="-Wl,-rpath,/lib" --prefix= --enable-lib-only --with-gnutls @@ -136,7 +138,7 @@ Build wolfSSL Build nghttp3 % cd .. - % git clone -b v0.15.0 https://github.com/ngtcp2/nghttp3 + % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 % cd nghttp3 % autoreconf -fi % ./configure --prefix= --enable-lib-only @@ -146,7 +148,7 @@ Build nghttp3 Build ngtcp2 % cd .. - % git clone -b v0.19.1 https://github.com/ngtcp2/ngtcp2 + % git clone -b v1.1.0 https://github.com/ngtcp2/ngtcp2 % cd ngtcp2 % autoreconf -fi % ./configure PKG_CONFIG_PATH=/lib/pkgconfig:/lib/pkgconfig LDFLAGS="-Wl,-rpath,/lib" --prefix= --enable-lib-only --with-wolfssl @@ -165,6 +167,8 @@ Build curl # quiche version +quiche support is **EXPERIMENTAL** + Since the quiche build manages its dependencies, curl can be built against the latest version. You are *probably* able to build against their main branch, but in case of problems, we recommend their latest release tag. ## build @@ -195,6 +199,8 @@ Build curl: one as of September 2023. Feel free to help us test it and improve it, but there is no point in filing bugs about it just yet. +msh3 support is **EXPERIMENTAL** + ## Build Linux (with quictls fork of OpenSSL) Build msh3: diff --git a/docs/HYPER.md b/docs/HYPER.md index 1c3b0dded..9932c1bbf 100644 --- a/docs/HYPER.md +++ b/docs/HYPER.md @@ -57,6 +57,10 @@ The hyper backend does not support - leading whitespace in first HTTP/1 response header - HTTP/0.9 - HTTP/2 upgrade using HTTP:// URLs. Aka 'h2c' +- HTTP/2 in general. Hyper has support for HTTP/2 but the curl side + needs changes so that a `hyper_clientconn` can last for the duration + of a connection. Probably this means turning the Hyper HTTP/2 backend + into a connection filter. ## Remaining issues diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 7e3a2698d..a6780b45d 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -162,6 +162,8 @@ library check. # Windows +Building for Windows XP is required as a minimum. + ## Building Windows DLLs and C runtime (CRT) linkage issues As a general rule, building a DLL with static CRT linkage is highly @@ -524,7 +526,12 @@ disabling support for some feature: - `--disable-alt-svc` (HTTP Alt-Svc) - `--disable-ares` (the C-ARES DNS library) - `--disable-cookies` (HTTP cookies) - - `--disable-crypto-auth` (cryptographic authentication) + - `--disable-basic-auth` (cryptographic authentication) + - `--disable-bearer-auth` (cryptographic authentication) + - `--disable-digest-auth` (cryptographic authentication) + - `--disable-kerberos-auth` (cryptographic authentication) + - `--disable-negotiate-auth` (cryptographic authentication) + - `--disable-aws` (cryptographic authentication) - `--disable-dateparse` (date parsing for time conditionals) - `--disable-dnsshuffle` (internal server load spreading) - `--disable-doh` (DNS-over-HTTP) @@ -589,29 +596,29 @@ that are not automatically detected: - `--disable-libcurl-option` !`--libcurl` - `--disable-verbose` !verbose\ logs -# PORTS +# Ports This is a probably incomplete list of known CPU architectures and operating systems that curl has been compiled for. If you know a system curl compiles and runs on, that is not listed, please let us know! -## 92 Operating Systems +## 101 Operating Systems - AIX, AmigaOS, Android, Aros, BeOS, Blackberry 10, Blackberry Tablet OS, - Cell OS, Chrome OS, Cisco IOS, Cygwin, DG/UX, Dragonfly BSD, DR DOS, eCOS, - FreeBSD, FreeDOS, FreeRTOS, Fuchsia, Garmin OS, Genode, Haiku, HardenedBSD, - HP-UX, Hurd, Illumos, Integrity, iOS, ipadOS, IRIX, Linux, Lua RTOS, - Mac OS 9, macOS, Mbed, Micrium, MINIX, MorphOS, MPE/iX, MS-DOS, NCR MP-RAS, - NetBSD, Netware, Nintendo Switch, NonStop OS, NuttX, Omni OS, OpenBSD, - OpenStep, Orbis OS, OS/2, OS/400, OS21, Plan 9, PlayStation Portable, QNX, - Qubes OS, ReactOS, Redox, RICS OS, RTEMS, Sailfish OS, SCO Unix, Serenity, - SINIX-Z, Solaris, SunOS, Syllable OS, Symbian, Tizen, TPF, Tru64, tvOS, - ucLinux, Ultrix, UNICOS, UnixWare, VMS, vxWorks, watchOS, WebOS, - Wii system software, Windows, Windows CE, Xbox System, Xenix, Zephyr, - z/OS, z/TPF, z/VM, z/VSE + AIX, AmigaOS, Android, ArcoOS, Aros, Atari FreeMiNT, BeOS, Blackberry 10, + Blackberry Tablet OS, Cell OS, CheriBSD, Chrome OS, Cisco IOS, DG/UX, + Dragonfly BSD, DR DOS, eCOS, FreeBSD, FreeDOS, FreeRTOS, Fuchsia, Garmin OS, + Genode, Haiku, HardenedBSD, HP-UX, Hurd, Illumos, Integrity, iOS, ipadOS, IRIX, + Linux, Lua RTOS, Mac OS 9, macOS, Mbed, Meego, Micrium, MINIX, Moblin, MorphOS, + MPE/iX, MS-DOS, NCR MP-RAS, NetBSD, Netware, NextStep, Nintendo Switch, + NonStop OS, NuttX, OpenBSD, OpenStep, Orbis OS, OS/2, OS/400, OS21, Plan 9, + PlayStation Portable, QNX, Qubes OS, ReactOS, Redox, RICS OS, ROS, RTEMS, + Sailfish OS, SCO Unix, Serenity, SINIX-Z, SkyOS, Solaris, Sortix, SunOS, + Syllable OS, Symbian, Tizen, TPF, Tru64, tvOS, ucLinux, Ultrix, UNICOS, + UnixWare, VMS, vxWorks, watchOS, Wear OS, WebOS, Wii system software, Wii U, + Windows, Windows CE, Xbox System, Xenix, Zephyr, z/OS, z/TPF, z/VM, z/VSE -## 26 CPU Architectures +## 28 CPU Architectures - Alpha, ARC, ARM, AVR32, CompactRISC, Elbrus, ETRAX, HP-PA, Itanium, + Alpha, ARC, ARM, AVR32, C-SKY, CompactRISC, Elbrus, ETRAX, HP-PA, Itanium, LoongArch, m68k, m88k, MicroBlaze, MIPS, Nios, OpenRISC, POWER, PowerPC, - RISC-V, s390, SH4, SPARC, Tilera, VAX, x86, Xtensa + RISC-V, s390, SH4, SPARC, Tilera, VAX, x86, Xtensa, z/arch diff --git a/docs/IPFS.md b/docs/IPFS.md index be8c597d9..24bba8b75 100644 --- a/docs/IPFS.md +++ b/docs/IPFS.md @@ -69,7 +69,7 @@ If you trust this behavior from your gateway of choice then passing the `-L` opt Depending on the arguments, cURL could present the user with an error. ### Gateway file and environment variable -cURL tried to look for the file: `~/.ipfs/gateway` but couldn't find it. It also tried to look for the `IPFS_GATEWAY` environment variable but couldn't find that either. This happens when no extra arguments are passed to cURL and letting it try to figure it out [automatically](#Automatic-gateway-detection). +cURL tried to look for the file: `~/.ipfs/gateway` but couldn't find it. It also tried to look for the `IPFS_GATEWAY` environment variable but couldn't find that either. This happens when no extra arguments are passed to cURL and letting it try to figure it out [automatically](#automatic-gateway-detection). Any IPFS implementation that has gateway support should expose it's URL in `~/.ipfs/gateway`. If you are already running a gateway, make sure it exposes the file where cURL expects to find it. @@ -78,5 +78,5 @@ Alternatively you could set the `IPFS_GATEWAY` environment variable or pass the ### Malformed gateway URL The command executed evaluates in an invalid URL. This could be anywhere in the URL, but a likely point is a wrong gateway URL. -Inspect your URL. -Alternatively opt to go for the [automatic](#Automatic-gateway-detection) gateway detection. +Inspect the URL set via the `IPFS_GATEWAY` environment variable or passed with the `--ipfs-gateway` flag. +Alternatively opt to go for the [automatic](#automatic-gateway-detection) gateway detection. diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS index 395426b4d..e52774a15 100644 --- a/docs/KNOWN_BUGS +++ b/docs/KNOWN_BUGS @@ -12,7 +12,6 @@ check the changelog of the current development status, as one or more of these problems may have been fixed or changed somewhat since this was written. 1. HTTP - 1.1 hyper memory-leaks 1.2 hyper is slow 1.5 Expect-100 meets 417 @@ -102,10 +101,6 @@ problems may have been fixed or changed somewhat since this was written. 16. aws-sigv4 16.1 aws-sigv4 does not sign requests with * correctly - 16.2 aws-sigv4 does not sign requests with valueless queries correctly - 16.3 aws-sigv4 is missing the amz-content-sha256 header - 16.4 aws-sigv4 does not sort query string parameters before signing - 16.5 aws-sigv4 does not sign requests with empty URL query correctly 16.6 aws-sigv4 does not behave well with AWS VPC Lattice 17. HTTP/2 @@ -579,22 +574,6 @@ problems may have been fixed or changed somewhat since this was written. https://github.com/curl/curl/issues/7559 -16.2 aws-sigv4 does not sign requests with valueless queries correctly - - https://github.com/curl/curl/issues/8107 - -16.3 aws-sigv4 is missing the amz-content-sha256 header - - https://github.com/curl/curl/issues/8810 - -16.4 aws-sigv4 does not sort query string parameters before signing - - https://github.com/curl/curl/issues/9717 - -16.5 aws-sigv4 does not sign requests with empty URL query correctly - - https://github.com/curl/curl/issues/10129 - 16.6 aws-sigv4 does not behave well with AWS VPC Lattice https://github.com/curl/curl/issues/11007 diff --git a/docs/Makefile.am b/docs/Makefile.am index 5454e8330..9190b4411 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -111,7 +111,8 @@ SUFFIXES = .1 .html .pdf # have changed. $(abs_builddir)/curl.1: if test "$(top_builddir)x" != "$(top_srcdir)x" -a -e "$(srcdir)/curl.1"; then \ - $(INSTALL_DATA) "$(srcdir)/curl.1" $@; fi + $(INSTALL_DATA) "$(srcdir)/curl.1" $@ \ + && touch -r "$(srcdir)/curl.1" $@; fi cd cmdline-opts && $(MAKE) html: $(HTMLPAGES) diff --git a/docs/THANKS b/docs/THANKS index 0bf9474a4..88d924f63 100644 --- a/docs/THANKS +++ b/docs/THANKS @@ -71,6 +71,7 @@ Alessandro Vesely Alex aka WindEagle Alex Baines Alex Bligh +Alex Bozarth Alex Chan Alex Crichton Alex Fishman @@ -78,6 +79,7 @@ Alex Gaynor Alex Grebenschikov Alex Gruz Alex Kiernan +Alex Klyubin Alex Konev Alex Malinovich Alex Mayorga @@ -111,6 +113,7 @@ Alexandre Ferrieux Alexandre Pion Alexey Borzov Alexey Eremikhin +Alexey Larikov Alexey Melnichuk Alexey Pesternikov Alexey Savchuk @@ -130,6 +133,7 @@ Alona Rossen Amaury Denoyelle amishmm on github Amit Katyal +Ammar Faizi Amol Pattekar Amr Shahin Anatol Belski @@ -227,6 +231,7 @@ Antoni Villalonga Antonio Larrosa Antony74 on github Antti Hätälä +Anubhav Rai apparentorder on github April King arainchik on github @@ -349,6 +354,7 @@ Bob Schader bobmitchell1956 on github Bodo Bergmann Bogdan Nicula +boilingoden Boris Kuschel Boris Okunskiy Boris Rasin @@ -422,6 +428,7 @@ Carlo Cannas Carlo Marcelo Arenas Belón Carlo Teubner Carlo Wood +Carlos Henrique Lima Melara Carlos ORyan Carsten Lange Casey Bodley @@ -437,6 +444,7 @@ Chandrakant Bagul Charles Cazabon Charles Kerr Charles Romestant +Charlie C Chen Prog Cherish98 on github Chester Liu @@ -649,6 +657,7 @@ David Sanderson David Schweikert David Shaw David Strauss +David Suter David Tarendash David Thiel David Walser @@ -780,6 +789,7 @@ Edward Sheldrake Edward Thomson Eelco Dolstra Eetu Ojanen +eeverettrbx on github Egon Eckert Egor Pugin Ehren Bendler @@ -806,8 +816,10 @@ Emiliano Ida Emilio Cobos Álvarez Emilio López Emmanuel Tychon +Enno Boland Enrico Scholz Enrik Berkhan +enWILLYado on github eppesuig Eramoto Masaya Eric Cooper @@ -868,6 +880,7 @@ Fabrice Fontaine Fabrizio Ammollo Fahim Chandurwala Faizur Rahman +Faraz Fallahi Farzin on github Fata Nugraha Fawad Mirza @@ -1048,6 +1061,7 @@ Hao Wu Hardeep Singh Haris Okanovic Harold Stuart +Harry Mallon Harry Sarson Harry Sintonen Harshal Pradhan @@ -1103,6 +1117,8 @@ Ian Lynagh Ian Spence Ian Turner Ian Wilkes +iconoclasthero +icy17 on github Ignacio Vazquez-Abrams Igor Franchuk Igor Khristophorov @@ -1279,6 +1295,7 @@ Jesse Tan jethrogb on github jhoyla on github Jie He +Jiehong on github Jilayne Lovejoy Jim Beveridge Jim Drash @@ -1467,10 +1484,12 @@ Kane York Kang Lin Kang-Jin Lee Kantanat Wannapaka +Kareem Kari Pahula Karl Chen Karl Moerder Karol Pietrzak +Kartatz on Github Karthikdasari0423 Karthikdasari0423 on github Kartik Mahajan @@ -1512,6 +1531,7 @@ Kim Minjoong Kim Rinnewitz Kim Vandry Kimmo Kinnunen +kirbyn17 on hackerone Kirill Efimov Kirill Marchuk Kjell Ericson @@ -1570,6 +1590,7 @@ Lars J. Aas Lars Johannesen Lars Nilsson Lars Torben Wilson +Lau Laurent Bonnans Laurent Dufresne Laurent Rabret @@ -1615,15 +1636,18 @@ Litter White Liviu Chircu Liza Alenchery lizhuang0630 on github +lkordos on github lllaffer on github Lloyd Fournier Lluís Batlle i Rossell locpyl-tidnyd on github Loganaden Velvindron Loic Dachary +LoRd_MuldeR Loren Kirkby Lorenzo Miniero Loïc Yhuel +lRoccoon on github Luan Cestari Luca Altea Luca Boccassi @@ -1667,6 +1691,7 @@ Maksim Arhipov Maksim Kuzevanov Maksim Sciepanienka Maksim Stsepanenka +Maksymilian Arciemowicz Malik Idrees Hasan Khan Mamoru Tasaka Mamta Upadhyay @@ -1693,6 +1718,7 @@ Marcelo Juchem Marcin Adamski Marcin Gryszkalis Marcin Konicki +Marcin Rataj Marco Deckel Marco G. Salvagno Marco Kamner @@ -1756,6 +1782,7 @@ Martin Jansen Martin Kammerhofer Martin Kepplinger Martin Lemke +Martin Schmatz Martin Skinner Martin Staael Martin Storsjö @@ -1995,6 +2022,7 @@ Nick Zitzmann nick-telia on github Nicklas Avén Nico Baggus +Nico Rieck nico-abram on github Nicolas Berloquin Nicolas Croiset @@ -2018,6 +2046,7 @@ nimaje on github niner on github Ning Dong Nir Soffer +Niracler Li Niranjan Hasabnis Nis Jorgensen nk @@ -2037,6 +2066,7 @@ Nuru on github Octavio Schroeder odek86 on github Ofer +ohyeaah on github Okhin Vasilij Ola Mork Olaf Flebbe @@ -2063,6 +2093,7 @@ omau on github Ondřej Koláček opensignature on github opensslonzos-github on github +Ophir Lojkine Orange Tsai Oren Souroujon Oren Tirosh @@ -2346,6 +2377,7 @@ Ricky-Tigg on github Rider Linden RiderALT on github Rikard Falkeborn +rilysh rl1987 on github Rob Boeckermann Rob Cotrone @@ -2373,6 +2405,7 @@ Robert Prag Robert Ronto Robert Schumann Robert Simpson +Robert Southee Robert Weaver Robert Wruck Robin A. Meade @@ -2448,6 +2481,7 @@ Salvador Dávila Salvatore Sorrentino Sam Deane Sam Hurst +Sam James Sam Roth Sam Schanken Samanta Navarro @@ -2482,6 +2516,7 @@ Scott Barrett Scott Cantor Scott Davis Scott McCreary +sd0 on hackerone Sean Boudreau Sean Burford Sean MacLennan @@ -2559,10 +2594,12 @@ Simon Warta simplerobot on github Siva Sivaraman SLDiggie on github +Smackd0wn Smackd0wn on github smuellerDD on github sn on hackerone sofaboss on github +Sohom Datta Somnath Kundu Song Ma Sonia Subramanian @@ -2629,6 +2666,7 @@ Steve Marx Steve Oliphant Steve Roskowski Steve Walch +Steven Allen Steven Bazyl Steven G. Johnson Steven Gu @@ -2714,6 +2752,7 @@ Tim Chen Tim Costello Tim Harder Tim Heckman +Tim Hill Tim Mcdonough Tim Newsome Tim Rühsen @@ -2793,6 +2832,7 @@ tonystz on Github Toon Verwaest Tor Arntsen Torben Dannhauer +Torben Dury Torsten Foertsch Toshio Kuratomi Toshiyuki Maezawa @@ -2809,6 +2849,7 @@ Tseng Jun Tuomas Siipola Tuomo Rinne Tupone Alfredo +Turiiya Tyler Hall Török Edwin u20221022 on github @@ -2976,6 +3017,7 @@ Zhang Xiuhua zhanghu on xiaomi Zhao Yisha Zhaoyang Wu +zhengqwe on github Zhibiao Wu zhihaoy on github Zhouyihai Ding diff --git a/docs/TODO b/docs/TODO index f487f88aa..06162c8bb 100644 --- a/docs/TODO +++ b/docs/TODO @@ -122,6 +122,7 @@ 13.8 Support DANE 13.9 TLS record padding 13.10 Support Authority Information Access certificate extension (AIA) + 13.11 Some TLS options are not offered for HTTPS proxies 13.12 Reduce CA certificate bundle reparsing 13.13 Make sure we forbid TLS 1.3 post-handshake authentication 13.14 Support the clienthello extension @@ -884,6 +885,14 @@ See https://github.com/curl/curl/issues/2793 +13.11 Some TLS options are not offered for HTTPS proxies + + Some TLS related options to the command line tool and libcurl are only + provided for the server and not for HTTPS proxies. --proxy-tls-max, + --proxy-tlsv1.3, --proxy-curves and a few more.a + + https://github.com/curl/curl/issues/12286 + 13.12 Reduce CA certificate bundle reparsing When using the OpenSSL backend, curl will load and reparse the CA bundle at diff --git a/docs/VULN-DISCLOSURE-POLICY.md b/docs/VULN-DISCLOSURE-POLICY.md index 3ce220329..650599348 100644 --- a/docs/VULN-DISCLOSURE-POLICY.md +++ b/docs/VULN-DISCLOSURE-POLICY.md @@ -59,8 +59,7 @@ announcement. [SECURITY-ADVISORY](https://curl.se/dev/advisory.html) for help on creating the advisory. -- Request a CVE number from - [HackerOne](https://docs.hackerone.com/programs/cve-requests.html) +- Request a CVE number from HackerOne - Update the "security advisory" with the CVE number. @@ -283,3 +282,12 @@ and if an attacker can trick the user to run a specifically crafted curl command line, all bets are off. Such an attacker can just as well have the user run a much worse command that can do something fatal (like `sudo rm -rf /`). + +## Terminal output and escape sequences + +Content that is transferred from a server and gets displayed in a terminal by +curl may contain escape sequences or use other tricks to fool the user. This +is curl working as designed and is not a curl security problem. Escape +sequences, moving cursor, changing color etc, is also frequently used for +good. To reduce the risk of getting fooled, save files and browse them after +download using a display method that minimizes risks. diff --git a/docs/cmdline-opts/gen.pl b/docs/cmdline-opts/gen.pl index 8b9b98bb2..edf90622b 100755 --- a/docs/cmdline-opts/gen.pl +++ b/docs/cmdline-opts/gen.pl @@ -48,8 +48,14 @@ my %catlong; use POSIX qw(strftime); -my $date = strftime "%B %d %Y", localtime; -my $year = strftime "%Y", localtime; +my @ts; +if (defined($ENV{SOURCE_DATE_EPOCH})) { + @ts = localtime($ENV{SOURCE_DATE_EPOCH}); +} else { + @ts = localtime; +} +my $date = strftime "%B %d %Y", @ts; +my $year = strftime "%Y", @ts; my $version = "unknown"; my $globals; diff --git a/docs/cmdline-opts/header.d b/docs/cmdline-opts/header.d index f5b768552..95c1565e8 100644 --- a/docs/cmdline-opts/header.d +++ b/docs/cmdline-opts/header.d @@ -34,7 +34,8 @@ with no-value then its header must be terminated with a semicolon, such as \-H curl makes sure that each header you add/replace is sent with the proper end-of-line marker, you should thus **not** add that as a part of the header content: do not add newlines or carriage returns, they only mess things up for -you. +you. curl passes on the verbatim string you give it without any filter or +other safe guards. That includes white space and control characters. This option can take an argument in @filename style, which then adds a header for each line in the input file. Using @- makes curl read the header file from diff --git a/docs/cmdline-opts/ipfs-gateway.d b/docs/cmdline-opts/ipfs-gateway.d index 5d5f8b2d4..e6845b327 100644 --- a/docs/cmdline-opts/ipfs-gateway.d +++ b/docs/cmdline-opts/ipfs-gateway.d @@ -9,36 +9,24 @@ Category: ipfs Example: --ipfs-gateway $URL ipfs:// Multi: single --- -Specifies which gateway to use for IPFS and IPNS URLs. -Not specifying this argument will let cURL try to automatically -check if IPFS_GATEWAY environment variable is set, -or if ~/.ipfs/gateway plain text file exists. +Specify which gateway to use for IPFS and IPNS URLs. Not specifying this will +instead make curl check if the IPFS_GATEWAY environment variable is set, or if +a ~/.ipfs/gateway file holding the gateway URL exists. -If you run a local IPFS node, this gateway is by default -available under http://localhost:8080. A full example URL would -look like: +If you run a local IPFS node, this gateway is by default available under +http://localhost:8080. A full example URL would look like: curl --ipfs-gateway http://localhost:8080 ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi - -You can also specify publicly available gateways. One such -gateway is https://ipfs.io. A full example url would look like: - - curl --ipfs-gateway https://ipfs.io ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi - - -There are many public IPFS gateways. As a starting point to find -one that works for your case, consult this page: +There are many public IPFS gateways. See for example: https://ipfs.github.io/public-gateway-checker/ - -A word of caution! When you opt to go for a remote gateway you should -be aware that you completely trust the gateway. This is fine in local gateways -as you host it yourself. With remote gateways there could potentially be -a malicious actor returning you data that does not match the request you made, -inspect or even interfere with the request. You won't notice this when using cURL. -A mitigation could be to go for a "trustless" gateway. This means you -locally verify that the data. Consult the docs page on trusted vs trustless: +WARNING: If you opt to go for a remote gateway you should be aware that you +completely trust the gateway. This is fine in local gateways as you host it +yourself. With remote gateways there could potentially be a malicious actor +returning you data that does not match the request you made, inspect or even +interfere with the request. You will not notice this when using curl. A +mitigation could be to go for a "trustless" gateway. This means you locally +verify that the data. Consult the docs page on trusted vs trustless: https://docs.ipfs.tech/reference/http/gateway/#trusted-vs-trustless - diff --git a/docs/cmdline-opts/page-footer b/docs/cmdline-opts/page-footer index beae49ac1..af41c9482 100644 --- a/docs/cmdline-opts/page-footer +++ b/docs/cmdline-opts/page-footer @@ -173,8 +173,8 @@ appears if --fail is used. .IP 23 Write error. Curl could not write data to a local filesystem or similar. .IP 25 -FTP could not STOR file. The server denied the STOR operation, used for FTP -uploading. +Failed starting the upload. For FTP, the server typically denied the STOR +command. .IP 26 Read error. Various reading problems. .IP 27 diff --git a/docs/cmdline-opts/request-target.d b/docs/cmdline-opts/request-target.d index 61ead5f2b..be53c658c 100644 --- a/docs/cmdline-opts/request-target.d +++ b/docs/cmdline-opts/request-target.d @@ -14,3 +14,6 @@ Tells curl to use an alternative "target" (path) instead of using the path as provided in the URL. Particularly useful when wanting to issue HTTP requests without leading slash or other data that does not follow the regular URL pattern, like "OPTIONS *". + +curl passes on the verbatim string you give it its the request without any +filter or other safe guards. That includes white space and control characters. diff --git a/docs/cmdline-opts/request.d b/docs/cmdline-opts/request.d index 0020babf9..6afd53564 100644 --- a/docs/cmdline-opts/request.d +++ b/docs/cmdline-opts/request.d @@ -12,6 +12,9 @@ See-also: request-target Multi: single --- Change the method to use when starting the transfer. + +curl passes on the verbatim string you give it its the request without any +filter or other safe guards. That includes white space and control characters. .RS .TP 15 **HTTP** diff --git a/docs/cmdline-opts/resolve.d b/docs/cmdline-opts/resolve.d index 31dd099a2..badb54e45 100644 --- a/docs/cmdline-opts/resolve.d +++ b/docs/cmdline-opts/resolve.d @@ -37,5 +37,3 @@ Support for providing multiple IP addresses per entry was added in 7.59.0. Support for resolving with wildcard was added in 7.64.0. Support for the '+' prefix was was added in 7.75.0. - -This option can be used many times to add many host names to resolve. diff --git a/docs/cmdline-opts/write-out.d b/docs/cmdline-opts/write-out.d index b2ac2ec06..e069afcf1 100644 --- a/docs/cmdline-opts/write-out.d +++ b/docs/cmdline-opts/write-out.d @@ -91,7 +91,7 @@ curl CONNECT request. (Added in 7.12.4) The http version that was effectively used. (Added in 7.50.0) .TP **json** -A JSON object with all available keys. +A JSON object with all available keys. (Added in 7.70.0) .TP **local_ip** The IP address of the local end of the most recently done connection - can be diff --git a/docs/examples/10-at-a-time.c b/docs/examples/10-at-a-time.c index b54a4410c..607775058 100644 --- a/docs/examples/10-at-a-time.c +++ b/docs/examples/10-at-a-time.c @@ -29,7 +29,7 @@ #include #include #include -#ifndef WIN32 +#ifndef _WIN32 # include #endif #include diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc index 60a006ca9..1f1996c37 100644 --- a/docs/examples/Makefile.inc +++ b/docs/examples/Makefile.inc @@ -76,7 +76,10 @@ check_PROGRAMS = \ imap-ssl \ imap-store \ imap-tls \ + interface \ ipv6 \ + keepalive \ + localport \ maxconnects \ multi-app \ multi-debugcallback \ @@ -105,6 +108,7 @@ check_PROGRAMS = \ progressfunc \ protofeats \ resolve \ + rtsp-options \ sendrecv \ sepheaders \ sftpget \ diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c index 8b979515a..1f4340f4d 100644 --- a/docs/examples/anyauthput.c +++ b/docs/examples/anyauthput.c @@ -33,7 +33,7 @@ #include -#ifdef WIN32 +#ifdef _WIN32 # define FILENO(fp) _fileno(fp) #else # define FILENO(fp) fileno(fp) diff --git a/docs/examples/cookie_interface.c b/docs/examples/cookie_interface.c index 557b57dc2..120049830 100644 --- a/docs/examples/cookie_interface.c +++ b/docs/examples/cookie_interface.c @@ -91,7 +91,7 @@ main(void) printf("-----------------------------------------------\n" "Setting a cookie \"PREF\" via cookie interface:\n"); -#ifdef WIN32 +#ifdef _WIN32 #define snprintf _snprintf #endif /* Netscape format cookie */ diff --git a/docs/examples/externalsocket.c b/docs/examples/externalsocket.c index 1c78c3db4..270a31996 100644 --- a/docs/examples/externalsocket.c +++ b/docs/examples/externalsocket.c @@ -30,7 +30,7 @@ #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #include #include @@ -96,7 +96,7 @@ int main(void) struct sockaddr_in servaddr; /* socket address structure */ curl_socket_t sockfd; -#ifdef WIN32 +#ifdef _WIN32 WSADATA wsaData; int initwsa = WSAStartup(MAKEWORD(2, 2), &wsaData); if(initwsa) { @@ -168,7 +168,7 @@ int main(void) } } -#ifdef WIN32 +#ifdef _WIN32 WSACleanup(); #endif return 0; diff --git a/docs/examples/ftpupload.c b/docs/examples/ftpupload.c index 00de126ea..92bb0b8a0 100644 --- a/docs/examples/ftpupload.c +++ b/docs/examples/ftpupload.c @@ -29,7 +29,7 @@ #include #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #else #include diff --git a/docs/examples/interface.c b/docs/examples/interface.c new file mode 100644 index 000000000..f1a2016ce --- /dev/null +++ b/docs/examples/interface.c @@ -0,0 +1,52 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ +/* + * Use CURLOPT_INTERFACE to bind the outgoing socket to an interface + * + */ +#include +#include + +int main(void) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + curl = curl_easy_init(); + if(curl) { + /* The interface needs to be a local existing interface over which you can + connect to the host in the URL. It can also specify an IP address, but + that address needs to be assigned one of the local network + interfaces. */ + curl_easy_setopt(curl, CURLOPT_INTERFACE, "enp3s0"); + curl_easy_setopt(curl, CURLOPT_URL, "https://curl.se/"); + + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + + return (int)res; +} diff --git a/docs/examples/ipv6.c b/docs/examples/ipv6.c index 49a44fa7a..dc305a072 100644 --- a/docs/examples/ipv6.c +++ b/docs/examples/ipv6.c @@ -28,13 +28,13 @@ #include #include -#ifndef WIN32 +#ifndef _WIN32 #include #endif int main(void) { -#ifndef WIN32 +#ifndef _WIN32 /* Windows users need to find how to use if_nametoindex() */ CURL *curl; CURLcode res; diff --git a/docs/examples/keepalive.c b/docs/examples/keepalive.c new file mode 100644 index 000000000..1c876bb1f --- /dev/null +++ b/docs/examples/keepalive.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ +/* + * Use the TCP keep-alive options + * + */ +#include +#include + +int main(void) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + curl = curl_easy_init(); + if(curl) { + /* enable TCP keep-alive for this transfer */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + + /* keep-alive idle time to 120 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); + + /* interval time between keep-alive probes: 60 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); + + curl_easy_setopt(curl, CURLOPT_URL, "https://curl.se/"); + + res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + } + + return (int)res; +} diff --git a/docs/examples/localport.c b/docs/examples/localport.c new file mode 100644 index 000000000..56e0b62cf --- /dev/null +++ b/docs/examples/localport.c @@ -0,0 +1,53 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ +/* + * Use CURLOPT_LOCALPORT to control local port number + * + */ +#include +#include + +int main(void) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + curl = curl_easy_init(); + if(curl) { + /* Try to use a local port number between 20000-20009 */ + curl_easy_setopt(curl, CURLOPT_LOCALPORT, 20000L); + /* 10 means number of attempts, which starts with the number set in + CURLOPT_LOCALPORT. The lowe value set, the smaller the change it will + work. */ + curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 10L); + curl_easy_setopt(curl, CURLOPT_URL, "https://curl.se/"); + + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + + return (int)res; +} diff --git a/docs/examples/rtsp-options.c b/docs/examples/rtsp-options.c new file mode 100644 index 000000000..e4a623048 --- /dev/null +++ b/docs/examples/rtsp-options.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + * + ***************************************************************************/ +/* + * Very simple RTSP request sending OPTIONS. + * + */ +#include +#include + +int main(void) +{ + CURL *curl; + CURLcode res; + + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + + curl_easy_setopt(curl, CURLOPT_RTSP_SESSION_ID, "12345"); + + curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); + + /* Perform the request, res will get 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)); + + /* always cleanup */ + curl_easy_cleanup(curl); + } + return 0; +} diff --git a/docs/libcurl/curl_easy_cleanup.3 b/docs/libcurl/curl_easy_cleanup.3 index d40ba67a8..9d54d2e25 100644 --- a/docs/libcurl/curl_easy_cleanup.3 +++ b/docs/libcurl/curl_easy_cleanup.3 @@ -57,12 +57,17 @@ Passing in a NULL pointer in \fIhandle\fP makes this function return immediately with no action. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res) + printf("error: %s\\n", curl_easy_strerror(res)); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_duphandle.3 b/docs/libcurl/curl_easy_duphandle.3 index f66c1dffb..545938654 100644 --- a/docs/libcurl/curl_easy_duphandle.3 +++ b/docs/libcurl/curl_easy_duphandle.3 @@ -45,19 +45,25 @@ The new handle does \fBnot\fP inherit any state information, no connections, no SSL sessions and no cookies. It also does not inherit any share object states or options (created as if \fICURLOPT_SHARE(3)\fP was set to NULL). +If the source handle has HSTS or alt-svc enabled, the duplicate gets data read +data from the main file name to populate the cache. + In multi-threaded programs, this function must be called in a synchronous way, the input handle may not be in use when cloned. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -CURL *nother; -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - nother = curl_easy_duphandle(curl); - res = curl_easy_perform(nother); - curl_easy_cleanup(nother); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + CURL *nother; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + nother = curl_easy_duphandle(curl); + res = curl_easy_perform(nother); + curl_easy_cleanup(nother); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_escape.3 b/docs/libcurl/curl_easy_escape.3 index e9ad9ff60..5aa01a964 100644 --- a/docs/libcurl/curl_easy_escape.3 +++ b/docs/libcurl/curl_easy_escape.3 @@ -57,14 +57,17 @@ The caller of \fIcurl_easy_escape(3)\fP must make sure that the data passed in to the function is encoded correctly. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - char *output = curl_easy_escape(curl, "data to convert", 15); - if(output) { - printf("Encoded: %s\\n", output); - curl_free(output); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + char *output = curl_easy_escape(curl, "data to convert", 15); + if(output) { + printf("Encoded: %s\\n", output); + curl_free(output); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3 index b0d8ae89d..f3c9f946c 100644 --- a/docs/libcurl/curl_easy_getinfo.3 +++ b/docs/libcurl/curl_easy_getinfo.3 @@ -298,8 +298,11 @@ pretransfer and transfer before final transaction was started. So, this is zero if no redirection took place. .SH EXAMPLE .nf - curl = curl_easy_init(); +int main(void) +{ + CURL *curl = curl_easy_init(); if(curl) { + CURLcode res; curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/"); res = curl_easy_perform(curl); @@ -315,6 +318,7 @@ zero if no redirection took place. /* always cleanup */ curl_easy_cleanup(curl); } +} .fi .SH AVAILABILITY Added in 7.4.1 diff --git a/docs/libcurl/curl_easy_header.3 b/docs/libcurl/curl_easy_header.3 index 3aa62649e..a5f44db1c 100644 --- a/docs/libcurl/curl_easy_header.3 +++ b/docs/libcurl/curl_easy_header.3 @@ -34,6 +34,7 @@ CURLHcode curl_easy_header(CURL *easy, unsigned int origin, int request, struct curl_header **hout); +.fi .SH DESCRIPTION \fIcurl_easy_header(3)\fP returns a pointer to a "curl_header" struct in \fBhout\fP with data for the HTTP response header \fIname\fP. The case @@ -126,9 +127,18 @@ response that might happen before the "real" response. The header is an HTTP/2 or HTTP/3 pseudo header .SH EXAMPLE .nf -struct curl_header *type; -CURLHcode h = - curl_easy_header(easy, "Content-Type", 0, CURLH_HEADER, -1, &type); +int main(void) +{ + struct curl_header *type; + CURL *curl = curl_easy_init(); + if(curl) { + CURLHcode h; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_perform(curl); + h = curl_easy_header(curl, "Content-Type", 0, CURLH_HEADER, -1, &type); + curl_easy_cleanup(curl); + } +} .fi .SH AVAILABILITY Added in 7.83.0. Officially supported since 7.84.0. diff --git a/docs/libcurl/curl_easy_init.3 b/docs/libcurl/curl_easy_init.3 index 0fd901699..238016986 100644 --- a/docs/libcurl/curl_easy_init.3 +++ b/docs/libcurl/curl_easy_init.3 @@ -57,12 +57,15 @@ this function. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_nextheader.3 b/docs/libcurl/curl_easy_nextheader.3 index b704e7643..44262463d 100644 --- a/docs/libcurl/curl_easy_nextheader.3 +++ b/docs/libcurl/curl_easy_nextheader.3 @@ -68,20 +68,29 @@ is associated with the easy handle. Applications must copy the data if they want it to survive subsequent API calls or the life-time of the easy handle. .SH EXAMPLE .nf -struct curl_header *prev = NULL; -struct curl_header *h; +int main(void) +{ + struct curl_header *prev = NULL; + struct curl_header *h; -/* extract the normal headers from the first request */ -while((h = curl_easy_nextheader(easy, CURLH_HEADER, 0, prev))) { - printf("%s: %s\\n", h->name, h->value); - prev = h; -} + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_perform(curl); + + /* extract the normal headers from the first request */ + while((h = curl_easy_nextheader(curl, CURLH_HEADER, 0, prev))) { + printf("%s: %s\\n", h->name, h->value); + prev = h; + } -/* extract the normal headers + 1xx + trailers from the last request */ -unsigned int origin = CURLH_HEADER| CURLH_1XX | CURLH_TRAILER; -while((h = curl_easy_nextheader(easy, origin, -1, prev))) { - printf("%s: %s\\n", h->name, h->value); - prev = h; + /* extract the normal headers + 1xx + trailers from the last request */ + unsigned int origin = CURLH_HEADER| CURLH_1XX | CURLH_TRAILER; + while((h = curl_easy_nextheader(curl, origin, -1, prev))) { + printf("%s: %s\\n", h->name, h->value); + prev = h; + } + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_option_by_id.3 b/docs/libcurl/curl_easy_option_by_id.3 index 3be115182..ded364bca 100644 --- a/docs/libcurl/curl_easy_option_by_id.3 +++ b/docs/libcurl/curl_easy_option_by_id.3 @@ -41,9 +41,12 @@ well. If libcurl has no option with the given id, this function returns NULL. .SH EXAMPLE .nf -const struct curl_easyoption *opt = curl_easy_option_by_id(CURLOPT_URL); -if(opt) { - printf("This option wants type %x\\n", opt->type); +int main(void) +{ + const struct curl_easyoption *opt = curl_easy_option_by_id(CURLOPT_URL); + if(opt) { + printf("This option wants type %x\\n", opt->type); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_option_by_name.3 b/docs/libcurl/curl_easy_option_by_name.3 index 701587792..87652e723 100644 --- a/docs/libcurl/curl_easy_option_by_name.3 +++ b/docs/libcurl/curl_easy_option_by_name.3 @@ -40,9 +40,12 @@ insensitive. If libcurl has no option with the given name, this function returns NULL. .SH EXAMPLE .nf -const struct curl_easyoption *opt = curl_easy_option_by_name("URL"); -if(opt) { - printf("This option wants CURLoption %x\\n", (int)opt->id); +int main(void) +{ + const struct curl_easyoption *opt = curl_easy_option_by_name("URL"); + if(opt) { + printf("This option wants CURLoption %x\\n", (int)opt->id); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_option_next.3 b/docs/libcurl/curl_easy_option_next.3 index 8109573e1..e2b35c522 100644 --- a/docs/libcurl/curl_easy_option_next.3 +++ b/docs/libcurl/curl_easy_option_next.3 @@ -28,6 +28,25 @@ curl_easy_option_next - iterate over easy setopt options .nf #include +const struct curl_easyoption * +curl_easy_option_next(const struct curl_easyoption *prev); +.fi +.SH DESCRIPTION +This function returns a pointer to the first or the next \fIcurl_easyoption\fP +struct, providing an ability to iterate over all known options for +\fIcurl_easy_setopt(3)\fP in this instance of libcurl. + +Pass a \fBNULL\fP argument as \fBprev\fP to get the first option returned, or +pass in the current option to get the next one returned. If there is no more +option to return, \fIcurl_easy_option_next(3)\fP returns NULL. + +The options returned by this functions are the ones known to this libcurl and +information about what argument type they want. + +If the \fBCURLOT_FLAG_ALIAS\fP bit is set in the flags field, it means the +name is provided for backwards compatibility as an alias. +.SH struct +.nf typedef enum { CURLOT_LONG, /* long (a range of values) */ CURLOT_VALUES, /* (a defined set or bitmask) */ @@ -48,32 +67,18 @@ struct curl_easyoption { curl_easytype type; unsigned int flags; }; - -const struct curl_easyoption * -curl_easy_option_next(const struct curl_easyoption *prev); .fi -.SH DESCRIPTION -This function returns a pointer to the first or the next \fIcurl_easyoption\fP -struct, providing an ability to iterate over all known options for -\fIcurl_easy_setopt(3)\fP in this instance of libcurl. - -Pass a \fBNULL\fP argument as \fBprev\fP to get the first option returned, or -pass in the current option to get the next one returned. If there is no more -option to return, \fIcurl_easy_option_next(3)\fP returns NULL. - -The options returned by this functions are the ones known to this libcurl and -information about what argument type they want. - -If the \fBCURLOT_FLAG_ALIAS\fP bit is set in the flags field, it means the -name is provided for backwards compatibility as an alias. .SH EXAMPLE .nf -/* iterate over all available options */ -const struct curl_easyoption *opt; -opt = curl_easy_option_by_next(NULL); -while(opt) { - printf("Name: %s\\n", opt->name); - opt = curl_easy_option_by_next(opt); +int main(void) +{ + /* iterate over all available options */ + const struct curl_easyoption *opt; + opt = curl_easy_option_next(NULL); + while(opt) { + printf("Name: %s\\n", opt->name); + opt = curl_easy_option_next(opt); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_pause.3 b/docs/libcurl/curl_easy_pause.3 index a3cf4b81c..e5ff8827d 100644 --- a/docs/libcurl/curl_easy_pause.3 +++ b/docs/libcurl/curl_easy_pause.3 @@ -26,9 +26,9 @@ curl_easy_pause - pause and unpause a connection .SH SYNOPSIS .nf -.B #include +#include -.BI "CURLcode curl_easy_pause(CURL *"handle ", int "bitmask ");" +CURLcode curl_easy_pause(CURL *handle, int bitmask ); .fi .SH DESCRIPTION Using this function, you can explicitly mark a running connection to get @@ -92,8 +92,15 @@ When such a paused stream is unpaused again, any buffered data is delivered first. .SH EXAMPLE .nf -/* pause a transfer in both directions */ -curl_easy_pause(curl, CURL_READFUNC_PAUSE | CURL_WRITEFUNC_PAUSE); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* pause a transfer in both directions */ + curl_easy_pause(curl, CURL_READFUNC_PAUSE | CURL_WRITEFUNC_PAUSE); + + } +} .fi .SH "MEMORY USE" When pausing a download transfer by returning the magic return code from a diff --git a/docs/libcurl/curl_easy_perform.3 b/docs/libcurl/curl_easy_perform.3 index 7852d764f..18430771a 100644 --- a/docs/libcurl/curl_easy_perform.3 +++ b/docs/libcurl/curl_easy_perform.3 @@ -63,12 +63,15 @@ While the \fBeasy_handle\fP is added to a multi handle, it cannot be used by \fIcurl_easy_perform(3)\fP. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_recv.3 b/docs/libcurl/curl_easy_recv.3 index c215a544f..5238f97b6 100644 --- a/docs/libcurl/curl_easy_recv.3 +++ b/docs/libcurl/curl_easy_recv.3 @@ -27,7 +27,7 @@ curl_easy_recv - receives raw data on an "easy" connection .SH SYNOPSIS .nf -#include +#include CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n); .fi @@ -63,18 +63,29 @@ Furthermore if you wait on the socket and it tells you there is data to read, read was for internal SSL processing, and no other data is available. .SH EXAMPLE .nf - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Do not do the transfer - only connect to host */ - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); - res = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + /* Do not do the transfer - only connect to host */ + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); + res = curl_easy_perform(curl); - if(res == CURLE_OK) { - /* Extract the socket from the curl handle - we need it for waiting. */ - res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd); + if(res == CURLE_OK) { + char buf[256]; + size_t nread; + long sockfd; - /* read data */ - res = curl_easy_recv(curl, buf, sizeof(buf), &nread); - } + /* Extract the socket from the curl handle - we need it for waiting. */ + res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd); + + /* read data */ + res = curl_easy_recv(curl, buf, sizeof(buf), &nread); + } + } +} .fi .SH AVAILABILITY Added in 7.18.2. diff --git a/docs/libcurl/curl_easy_reset.3 b/docs/libcurl/curl_easy_reset.3 index c7615655d..5fa9b13b3 100644 --- a/docs/libcurl/curl_easy_reset.3 +++ b/docs/libcurl/curl_easy_reset.3 @@ -40,11 +40,15 @@ connections, the Session ID cache, the DNS cache, the cookies, the shares or the alt-svc cache. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { -/* ... the handle is used and options are set ... */ - -curl_easy_reset(curl); + /* ... the handle is used and options are set ... */ + curl_easy_reset(curl); + } +} .fi .SH AVAILABILITY This function was added in libcurl 7.12.1 diff --git a/docs/libcurl/curl_easy_send.3 b/docs/libcurl/curl_easy_send.3 index 4da5a2387..820029ec0 100644 --- a/docs/libcurl/curl_easy_send.3 +++ b/docs/libcurl/curl_easy_send.3 @@ -27,7 +27,7 @@ curl_easy_send - sends raw data over an "easy" connection .SH SYNOPSIS .nf -#include +#include CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen, size_t *n); @@ -58,18 +58,27 @@ Furthermore if you wait on the socket and it tells you it's writable, sent was for internal SSL processing, and no other data could be sent. .SH EXAMPLE .nf - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Do not do the transfer - only connect to host */ - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); - res = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + /* Do not do the transfer - only connect to host */ + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); + res = curl_easy_perform(curl); - if(res == CURLE_OK) { - /* Extract the socket from the curl handle - we need it for waiting. */ - res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd); + if(res == CURLE_OK) { + long sockfd; + size_t sent; + /* Extract the socket from the curl handle - we need it for waiting. */ + res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd); - /* send data */ - res = curl_easy_send(curl, "hello", 5, &sent); - } + /* send data */ + res = curl_easy_send(curl, "hello", 5, &sent); + } + } +} .fi .SH AVAILABILITY Added in 7.18.2. diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index ae43811ab..7e7819f64 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -709,12 +709,15 @@ To be set by toplevel tools like "curl" to skip lengthy cleanups when they are a TELNET options. See \fICURLOPT_TELNETOPTIONS(3)\fP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_strerror.3 b/docs/libcurl/curl_easy_strerror.3 index 393ef420a..87a8f77b9 100644 --- a/docs/libcurl/curl_easy_strerror.3 +++ b/docs/libcurl/curl_easy_strerror.3 @@ -38,12 +38,20 @@ Typically applications also appreciate \fICURLOPT_ERRORBUFFER(3)\fP for more specific error descriptions generated at runtime. .SH EXAMPLE .nf - /* Perform the entire transfer */ - res = curl_easy_perform(curl); - /* Check for errors */ - if(res != CURLE_OK) - fprintf(stderr, "curl_easy_perform() failed: %s\\n", - curl_easy_strerror(res)); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + /* set options */ + /* Perform the entire transfer */ + res = curl_easy_perform(curl); + /* Check for errors */ + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\\n", + curl_easy_strerror(res)); + } +} .fi .SH AVAILABILITY This function was added in libcurl 7.12.0 diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3 index 26bf7e126..9c52cbfa5 100644 --- a/docs/libcurl/curl_easy_unescape.3 +++ b/docs/libcurl/curl_easy_unescape.3 @@ -54,17 +54,20 @@ TPF, but it was otherwise ignored. You must \fIcurl_free(3)\fP the returned string when you are done with it. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - int decodelen; - char *decoded = curl_easy_unescape(curl, "%63%75%72%6c", 12, &decodelen); - if(decoded) { - /* do not assume printf() works on the decoded data! */ - printf("Decoded: "); - /* ... */ - curl_free(decoded); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + int decodelen; + char *decoded = curl_easy_unescape(curl, "%63%75%72%6c", 12, &decodelen); + if(decoded) { + /* do not assume printf() works on the decoded data! */ + printf("Decoded: "); + /* ... */ + curl_free(decoded); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_easy_upkeep.3 b/docs/libcurl/curl_easy_upkeep.3 index ade0a5d46..b4d35716f 100644 --- a/docs/libcurl/curl_easy_upkeep.3 +++ b/docs/libcurl/curl_easy_upkeep.3 @@ -47,27 +47,30 @@ The connection upkeep interval is set with \fICURLOPT_UPKEEP_INTERVAL_MS(3)\fP. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - /* Make a connection to an HTTP/2 server. */ - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* Make a connection to an HTTP/2 server. */ + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Set the interval to 30000ms / 30s */ - curl_easy_setopt(curl, CURLOPT_UPKEEP_INTERVAL_MS, 30000L); + /* Set the interval to 30000ms / 30s */ + curl_easy_setopt(curl, CURLOPT_UPKEEP_INTERVAL_MS, 30000L); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* Perform more work here. */ + /* Perform more work here. */ - /* While the connection is being held open, curl_easy_upkeep() can be - called. If curl_easy_upkeep() is called and the time since the last - upkeep exceeds the interval, then an HTTP/2 PING is sent. */ - curl_easy_upkeep(curl); + /* While the connection is being held open, curl_easy_upkeep() can be + called. If curl_easy_upkeep() is called and the time since the last + upkeep exceeds the interval, then an HTTP/2 PING is sent. */ + curl_easy_upkeep(curl); - /* Perform more work here. */ + /* Perform more work here. */ - /* always cleanup */ - curl_easy_cleanup(curl); + /* always cleanup */ + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_escape.3 b/docs/libcurl/curl_escape.3 index b379b7a6b..1cd262540 100644 --- a/docs/libcurl/curl_escape.3 +++ b/docs/libcurl/curl_escape.3 @@ -44,10 +44,13 @@ on \fBstring\fP to find out the size. You must \fIcurl_free(3)\fP the returned string when you are done with it. .SH EXAMPLE .nf -char *output = curl_escape("data to convert", 15); -if(output) { - printf("Encoded: %s\\n", output); - curl_free(output); +int main(void) +{ + char *output = curl_escape("data to convert", 15); + if(output) { + printf("Encoded: %s\\n", output); + curl_free(output); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_formadd.3 b/docs/libcurl/curl_formadd.3 index b379d0acb..8d8e91d89 100644 --- a/docs/libcurl/curl_formadd.3 +++ b/docs/libcurl/curl_formadd.3 @@ -175,82 +175,99 @@ for the curl handle. See example below. .SH EXAMPLE .nf - struct curl_httppost *post = NULL; - struct curl_httppost *last = NULL; - char namebuffer[] = "name buffer"; - long namelength = strlen(namebuffer); - char buffer[] = "test buffer"; - char htmlbuffer[] = "test buffer"; - long htmlbufferlength = strlen(htmlbuffer); - struct curl_forms forms[3]; - char file1[] = "my-face.jpg"; - char file2[] = "your-face.jpg"; - /* add null character into htmlbuffer, to demonstrate that - transfers of buffers containing null characters actually work - */ - htmlbuffer[8] = '\\0'; - - /* Add simple name/content section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", - CURLFORM_COPYCONTENTS, "content", CURLFORM_END); - - /* Add simple name/content/contenttype section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", - CURLFORM_COPYCONTENTS, "", - CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); - - /* Add name/ptrcontent section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", - CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); - - /* Add ptrname/ptrcontent section */ - curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer, - CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH, - namelength, CURLFORM_END); - - /* Add name/ptrcontent/contenttype section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole", - CURLFORM_PTRCONTENTS, htmlbuffer, - CURLFORM_CONTENTSLENGTH, htmlbufferlength, - CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); - - /* Add simple file section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", - CURLFORM_FILE, "my-face.jpg", CURLFORM_END); - - /* Add file/contenttype section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", - CURLFORM_FILE, "my-face.jpg", - CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); - - /* Add two file section */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", - CURLFORM_FILE, "my-face.jpg", - CURLFORM_FILE, "your-face.jpg", CURLFORM_END); - - /* Add two file section using CURLFORM_ARRAY */ - forms[0].option = CURLFORM_FILE; - forms[0].value = file1; - forms[1].option = CURLFORM_FILE; - forms[1].value = file2; - forms[2].option = CURLFORM_END; - - /* Add a buffer to upload */ - curl_formadd(&post, &last, - CURLFORM_COPYNAME, "name", - CURLFORM_BUFFER, "data", - CURLFORM_BUFFERPTR, record, - CURLFORM_BUFFERLENGTH, record_length, - CURLFORM_END); - - /* no option needed for the end marker */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", - CURLFORM_ARRAY, forms, CURLFORM_END); - /* Add the content of a file as a normal post text value */ - curl_formadd(&post, &last, CURLFORM_COPYNAME, "filecontent", - CURLFORM_FILECONTENT, ".bashrc", CURLFORM_END); - /* Set the form info */ - curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); +#include /* for strlen */ + +static const char record[]="data in a buffer"; + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct curl_httppost *post = NULL; + struct curl_httppost *last = NULL; + char namebuffer[] = "name buffer"; + long namelength = strlen(namebuffer); + char buffer[] = "test buffer"; + char htmlbuffer[] = "test buffer"; + long htmlbufferlength = strlen(htmlbuffer); + struct curl_forms forms[3]; + char file1[] = "my-face.jpg"; + char file2[] = "your-face.jpg"; + /* add null character into htmlbuffer, to demonstrate that + transfers of buffers containing null characters actually work + */ + htmlbuffer[8] = '\\0'; + + /* Add simple name/content section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", + CURLFORM_COPYCONTENTS, "content", CURLFORM_END); + + /* Add simple name/content/contenttype section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode", + CURLFORM_COPYCONTENTS, "", + CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); + + /* Add name/ptrcontent section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent", + CURLFORM_PTRCONTENTS, buffer, CURLFORM_END); + + /* Add ptrname/ptrcontent section */ + curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer, + CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH, + namelength, CURLFORM_END); + + /* Add name/ptrcontent/contenttype section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole", + CURLFORM_PTRCONTENTS, htmlbuffer, + CURLFORM_CONTENTSLENGTH, htmlbufferlength, + CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END); + + /* Add simple file section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", + CURLFORM_FILE, "my-face.jpg", CURLFORM_END); + + /* Add file/contenttype section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture", + CURLFORM_FILE, "my-face.jpg", + CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); + + /* Add two file section */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", + CURLFORM_FILE, "my-face.jpg", + CURLFORM_FILE, "your-face.jpg", CURLFORM_END); + + /* Add two file section using CURLFORM_ARRAY */ + forms[0].option = CURLFORM_FILE; + forms[0].value = file1; + forms[1].option = CURLFORM_FILE; + forms[1].value = file2; + forms[2].option = CURLFORM_END; + + /* Add a buffer to upload */ + curl_formadd(&post, &last, + CURLFORM_COPYNAME, "name", + CURLFORM_BUFFER, "data", + CURLFORM_BUFFERPTR, record, + CURLFORM_BUFFERLENGTH, sizeof(record), + CURLFORM_END); + + /* no option needed for the end marker */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures", + CURLFORM_ARRAY, forms, CURLFORM_END); + /* Add the content of a file as a normal post text value */ + curl_formadd(&post, &last, CURLFORM_COPYNAME, "filecontent", + CURLFORM_FILECONTENT, ".bashrc", CURLFORM_END); + /* Set the form info */ + curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); + + curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + curl_formfree(post); + } +} +.fi .SH AVAILABILITY Deprecated in 7.56.0. Before this release, field names were allowed to contain zero-valued bytes. The pseudo-filename "-" to read stdin is diff --git a/docs/libcurl/curl_formfree.3 b/docs/libcurl/curl_formfree.3 index cb0129da5..b3166745e 100644 --- a/docs/libcurl/curl_formfree.3 +++ b/docs/libcurl/curl_formfree.3 @@ -48,19 +48,28 @@ Passing in a NULL pointer in \fIform\fP makes this function return immediately with no action. .SH EXAMPLE .nf - /* Fill in a file upload field */ - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "file", - CURLFORM_FILE, "nice-image.jpg", - CURLFORM_END); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct curl_httppost *formpost; + struct curl_httppost *lastptr; - curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + /* Fill in a file upload field */ + curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "file", + CURLFORM_FILE, "nice-image.jpg", + CURLFORM_END); - curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); - /* then cleanup the formpost chain */ - curl_formfree(formpost); + curl_easy_perform(curl); + + /* then cleanup the formpost chain */ + curl_formfree(formpost); + } +} .fi .SH AVAILABILITY Deprecated in 7.56.0. diff --git a/docs/libcurl/curl_formget.3 b/docs/libcurl/curl_formget.3 index 0ce761013..395ae7df6 100644 --- a/docs/libcurl/curl_formget.3 +++ b/docs/libcurl/curl_formget.3 @@ -26,10 +26,11 @@ curl_formget - serialize a previously built multipart form POST chain .SH SYNOPSIS .nf -.B #include +#include int curl_formget(struct curl_httppost * form, void *userp, - curl_formget_callback append ); + curl_formget_callback append); +.fi .SH DESCRIPTION curl_formget() is used to serialize data previously built/appended with \fIcurl_formadd(3)\fP. Accepts a void pointer as second argument named @@ -49,21 +50,22 @@ request. This, because first then does libcurl known which actual read callback to use! .SH EXAMPLE .nf - size_t print_httppost_callback(void *arg, const char *buf, size_t len) - { - fwrite(buf, len, 1, stdout); - (*(size_t *) arg) += len; - return len; - } +size_t print_httppost_callback(void *arg, const char *buf, size_t len) +{ + fwrite(buf, len, 1, stdout); + (*(size_t *) arg) += len; + return len; +} - size_t print_httppost(struct curl_httppost *post) - { - size_t total_size = 0; - if(curl_formget(post, &total_size, print_httppost_callback)) { - return (size_t) -1; - } - return total_size; - } +size_t print_httppost(struct curl_httppost *post) +{ + size_t total_size = 0; + if(curl_formget(post, &total_size, print_httppost_callback)) { + return (size_t) -1; + } + return total_size; +} +.fi .SH AVAILABILITY This function was added in libcurl 7.15.5. The form API is deprecated in libcurl 7.56.0. diff --git a/docs/libcurl/curl_free.3 b/docs/libcurl/curl_free.3 index 9192b9303..f29d8f1e1 100644 --- a/docs/libcurl/curl_free.3 +++ b/docs/libcurl/curl_free.3 @@ -39,11 +39,14 @@ Passing in a NULL pointer in \fIptr\fP makes this function return immediately with no action. .SH EXAMPLE .nf +int main(void) +{ char *width = curl_getenv("COLUMNS"); if(width) { /* it was set! */ curl_free(width); } +} .fi .SH AVAILABILITY Always diff --git a/docs/libcurl/curl_getdate.3 b/docs/libcurl/curl_getdate.3 index 2f88fdb99..42dc29997 100644 --- a/docs/libcurl/curl_getdate.3 +++ b/docs/libcurl/curl_getdate.3 @@ -21,14 +21,14 @@ .\" * SPDX-License-Identifier: curl .\" * .\" ************************************************************************** -a.TH curl_getdate 3 "12 Aug 2005" "libcurl" "libcurl" +.TH curl_getdate 3 "12 Aug 2005" "libcurl" "libcurl" .SH NAME curl_getdate - Convert a date string to number of seconds .SH SYNOPSIS .nf #include -time_t curl_getdate(char *datestring, time_t *now); +time_t curl_getdate(const char *datestring, const time_t *now); .fi .SH DESCRIPTION \fIcurl_getdate(3)\fP returns the number of seconds since the Epoch, January @@ -70,29 +70,32 @@ year, MM as the month number and DD as the day of the month, for the specified calendar date. .SH EXAMPLE .nf - time_t t; - t = curl_getdate("Sun, 06 Nov 1994 08:49:37 GMT", NULL); - t = curl_getdate("Sunday, 06-Nov-94 08:49:37 GMT", NULL); - t = curl_getdate("Sun Nov 6 08:49:37 1994", NULL); - t = curl_getdate("06 Nov 1994 08:49:37 GMT", NULL); - t = curl_getdate("06-Nov-94 08:49:37 GMT", NULL); - t = curl_getdate("Nov 6 08:49:37 1994", NULL); - t = curl_getdate("06 Nov 1994 08:49:37", NULL); - t = curl_getdate("06-Nov-94 08:49:37", NULL); - t = curl_getdate("1994 Nov 6 08:49:37", NULL); - t = curl_getdate("GMT 08:49:37 06-Nov-94 Sunday", NULL); - t = curl_getdate("94 6 Nov 08:49:37", NULL); - t = curl_getdate("1994 Nov 6", NULL); - t = curl_getdate("06-Nov-94", NULL); - t = curl_getdate("Sun Nov 6 94", NULL); - t = curl_getdate("1994.Nov.6", NULL); - t = curl_getdate("Sun/Nov/6/94/GMT", NULL); - t = curl_getdate("Sun, 06 Nov 1994 08:49:37 CET", NULL); - t = curl_getdate("06 Nov 1994 08:49:37 EST", NULL); - t = curl_getdate("Sun, 12 Sep 2004 15:05:58 -0700", NULL); - t = curl_getdate("Sat, 11 Sep 2004 21:32:11 +0200", NULL); - t = curl_getdate("20040912 15:05:58 -0700", NULL); - t = curl_getdate("20040911 +0200", NULL); +int main(void) +{ + time_t t; + t = curl_getdate("Sun, 06 Nov 1994 08:49:37 GMT", NULL); + t = curl_getdate("Sunday, 06-Nov-94 08:49:37 GMT", NULL); + t = curl_getdate("Sun Nov 6 08:49:37 1994", NULL); + t = curl_getdate("06 Nov 1994 08:49:37 GMT", NULL); + t = curl_getdate("06-Nov-94 08:49:37 GMT", NULL); + t = curl_getdate("Nov 6 08:49:37 1994", NULL); + t = curl_getdate("06 Nov 1994 08:49:37", NULL); + t = curl_getdate("06-Nov-94 08:49:37", NULL); + t = curl_getdate("1994 Nov 6 08:49:37", NULL); + t = curl_getdate("GMT 08:49:37 06-Nov-94 Sunday", NULL); + t = curl_getdate("94 6 Nov 08:49:37", NULL); + t = curl_getdate("1994 Nov 6", NULL); + t = curl_getdate("06-Nov-94", NULL); + t = curl_getdate("Sun Nov 6 94", NULL); + t = curl_getdate("1994.Nov.6", NULL); + t = curl_getdate("Sun/Nov/6/94/GMT", NULL); + t = curl_getdate("Sun, 06 Nov 1994 08:49:37 CET", NULL); + t = curl_getdate("06 Nov 1994 08:49:37 EST", NULL); + t = curl_getdate("Sun, 12 Sep 2004 15:05:58 -0700", NULL); + t = curl_getdate("Sat, 11 Sep 2004 21:32:11 +0200", NULL); + t = curl_getdate("20040912 15:05:58 -0700", NULL); + t = curl_getdate("20040911 +0200", NULL); +} .fi .SH STANDARDS This parser handles date formats specified in RFC 822 (including the update in diff --git a/docs/libcurl/curl_getenv.3 b/docs/libcurl/curl_getenv.3 index e74357f8a..a13d59671 100644 --- a/docs/libcurl/curl_getenv.3 +++ b/docs/libcurl/curl_getenv.3 @@ -38,11 +38,14 @@ systems libcurl builds on (including win32). You must \fIcurl_free(3)\fP the returned string when you are done with it. .SH EXAMPLE .nf +int main(void) +{ char *width = curl_getenv("COLUMNS"); if(width) { /* it was set! */ curl_free(width); } +} .fi .SH AVAILABILITY Always diff --git a/docs/libcurl/curl_global_cleanup.3 b/docs/libcurl/curl_global_cleanup.3 index b40949411..75a0a01ac 100644 --- a/docs/libcurl/curl_global_cleanup.3 +++ b/docs/libcurl/curl_global_cleanup.3 @@ -58,11 +58,14 @@ recommend you do not run libcurl from any module that may be unloaded dynamically. This behavior may be addressed in the future. .SH EXAMPLE .nf - curl_global_init(CURL_GLOBAL_DEFAULT); +int main(void) +{ + curl_global_init(CURL_GLOBAL_DEFAULT); - /* use libcurl, then before exiting... */ + /* use libcurl, then before exiting... */ - curl_global_cleanup(); + curl_global_cleanup(); +} .fi .SH AVAILABILITY Added in 7.8 diff --git a/docs/libcurl/curl_global_init.3 b/docs/libcurl/curl_global_init.3 index 74658c633..b76999100 100644 --- a/docs/libcurl/curl_global_init.3 +++ b/docs/libcurl/curl_global_init.3 @@ -101,11 +101,14 @@ connecting or when waiting for data. Otherwise, curl waits until full timeout elapses. (Added in 7.30.0) .SH EXAMPLE .nf - curl_global_init(CURL_GLOBAL_DEFAULT); +int main(void) +{ + curl_global_init(CURL_GLOBAL_DEFAULT); - /* use libcurl, then before exiting... */ + /* use libcurl, then before exiting... */ - curl_global_cleanup(); + curl_global_cleanup(); +} .fi .SH AVAILABILITY Added in 7.8 diff --git a/docs/libcurl/curl_global_init_mem.3 b/docs/libcurl/curl_global_init_mem.3 index 99f0f963c..3aa65ba93 100644 --- a/docs/libcurl/curl_global_init_mem.3 +++ b/docs/libcurl/curl_global_init_mem.3 @@ -65,9 +65,18 @@ Manipulating these gives considerable powers to the application to severely screw things up for libcurl. Take care! .SH EXAMPLE .nf - curl_global_init_mem(CURL_GLOBAL_DEFAULT, curl_malloc_cb, - curl_free_cb, curl_realloc_cb, - curl_strdup_cb, curl_calloc_cb); +extern void *malloc_cb(size_t); +extern void free_cb(void *); +extern void *realloc_cb(void *, size_t); +extern char *strdup_cb(const char *); +extern void *calloc_cb(size_t, size_t); + +int main(void) +{ + curl_global_init_mem(CURL_GLOBAL_DEFAULT, malloc_cb, + free_cb, realloc_cb, + strdup_cb, calloc_cb); +} .fi .SH AVAILABILITY Added in 7.12.0 diff --git a/docs/libcurl/curl_global_sslset.3 b/docs/libcurl/curl_global_sslset.3 index e1d5bdfb4..3384b551a 100644 --- a/docs/libcurl/curl_global_sslset.3 +++ b/docs/libcurl/curl_global_sslset.3 @@ -28,31 +28,9 @@ curl_global_sslset - Select SSL backend to use with libcurl .nf #include -typedef struct { - curl_sslbackend id; - const char *name; -} curl_ssl_backend; - -typedef enum { - CURLSSLBACKEND_NONE = 0, - CURLSSLBACKEND_OPENSSL = 1, /* or one of its forks */ - CURLSSLBACKEND_GNUTLS = 2, - CURLSSLBACKEND_NSS = 3, - CURLSSLBACKEND_GSKIT = 5, /* deprecated */ - CURLSSLBACKEND_POLARSSL = 6, /* deprecated */ - CURLSSLBACKEND_WOLFSSL = 7, - CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_SECURETRANSPORT = 9, - CURLSSLBACKEND_AXTLS = 10, /* deprecated */ - CURLSSLBACKEND_MBEDTLS = 11, - CURLSSLBACKEND_MESALINK = 12, /* deprecated */ - CURLSSLBACKEND_BEARSSL = 13, - CURLSSLBACKEND_RUSTLS = 14 -} curl_sslbackend; - CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, - curl_ssl_backend ***avail); + const curl_ssl_backend ***avail); .fi .SH DESCRIPTION This function configures at runtime which SSL backend to use with @@ -99,8 +77,35 @@ provide the same API. \fIcurl_version_info(3)\fP can return more specific info about the exact OpenSSL flavor and version number is use. +.SH struct +.nf +typedef struct { + curl_sslbackend id; + const char *name; +} curl_ssl_backend; + +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, /* or one of its forks */ + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_GSKIT = 5, /* deprecated */ + CURLSSLBACKEND_POLARSSL = 6, /* deprecated */ + CURLSSLBACKEND_WOLFSSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_SECURETRANSPORT = 9, + CURLSSLBACKEND_AXTLS = 10, /* deprecated */ + CURLSSLBACKEND_MBEDTLS = 11, + CURLSSLBACKEND_MESALINK = 12, /* deprecated */ + CURLSSLBACKEND_BEARSSL = 13, + CURLSSLBACKEND_RUSTLS = 14 +} curl_sslbackend; +.fi .SH EXAMPLE .nf +int main(void) +{ + int i; /* choose a specific backend */ curl_global_sslset(CURLSSLBACKEND_WOLFSSL, NULL, NULL); @@ -111,6 +116,7 @@ OpenSSL flavor and version number is use. for(i = 0; list[i]; i++) printf("SSL backend #%d: '%s' (ID: %d)\\n", i, list[i]->name, list[i]->id); +} .fi .SH AVAILABILITY This function was added in libcurl 7.56.0. Before this version, there was no diff --git a/docs/libcurl/curl_global_trace.3 b/docs/libcurl/curl_global_trace.3 index 8f16bb4ab..926a86b1d 100644 --- a/docs/libcurl/curl_global_trace.3 +++ b/docs/libcurl/curl_global_trace.3 @@ -91,21 +91,24 @@ trace. .SH EXAMPLE .nf - /* log details of HTTP/2 and SSL handling */ - curl_global_trace("http/2,ssl"); +int main(void) +{ + /* log details of HTTP/2 and SSL handling */ + curl_global_trace("http/2,ssl"); - /* log all details, except SSL handling */ - curl_global_trace("all,-ssl"); + /* log all details, except SSL handling */ + curl_global_trace("all,-ssl"); +} .fi Below is a trace sample where "http/2" was configured. The trace output of an enabled component appears at the beginning in brackets. .nf * [HTTP/2] [h2sid=1] cf_send(len=96) submit https://example.com/ -... +\&... * [HTTP/2] [h2sid=1] FRAME[HEADERS] * [HTTP/2] [h2sid=1] 249 header bytes -... +\&... .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_mime_addpart.3 b/docs/libcurl/curl_mime_addpart.3 index 34d365b10..c9eccf55b 100644 --- a/docs/libcurl/curl_mime_addpart.3 +++ b/docs/libcurl/curl_mime_addpart.3 @@ -39,18 +39,24 @@ subsequently be populated using functions from the mime API. appended. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* add a part */ - part = curl_mime_addpart(mime); + /* add a part */ + part = curl_mime_addpart(mime); - /* continue and set name + data to the part */ - curl_mime_data(part, "This is the field data", CURL_ZERO_TERMINATED); - curl_mime_name(part, "data"); + /* continue and set name + data to the part */ + curl_mime_data(part, "This is the field data", CURL_ZERO_TERMINATED); + curl_mime_name(part, "data"); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_data.3 b/docs/libcurl/curl_mime_data.3 index baeb281b2..71042daa1 100644 --- a/docs/libcurl/curl_mime_data.3 +++ b/docs/libcurl/curl_mime_data.3 @@ -52,17 +52,23 @@ Setting large data is memory consuming: one might consider using \fIcurl_mime_data_cb(3)\fP in such a case. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* add a part */ - part = curl_mime_addpart(mime); + /* add a part */ + part = curl_mime_addpart(mime); - /* add data to the part */ - curl_mime_data(part, "raw contents to send", CURL_ZERO_TERMINATED); + /* add data to the part */ + curl_mime_data(part, "raw contents to send", CURL_ZERO_TERMINATED); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_data_cb.3 b/docs/libcurl/curl_mime_data_cb.3 index 03e6bd86d..8ca3df3e3 100644 --- a/docs/libcurl/curl_mime_data_cb.3 +++ b/docs/libcurl/curl_mime_data_cb.3 @@ -104,7 +104,7 @@ to avoid overhead resources consumption, one might want to use a callback source to avoid data duplication. In this case, original data must be retained until after the transfer terminates. .nf - +#include /* for memcpy */ char hugedata[512000]; struct ctl { @@ -146,17 +146,22 @@ int seek_callback(void *arg, curl_off_t offset, int origin) return CURL_SEEKFUNC_OK; } - CURL *easy = curl_easy_init(); - curl_mime *mime = curl_mime_init(easy); - curl_mimepart *part = curl_mime_addpart(mime); - struct ctl hugectl; - - hugectl.buffer = hugedata; - hugectl.size = sizeof hugedata; - hugectl.position = 0; - curl_mime_data_cb(part, hugectl.size, read_callback, seek_callback, NULL, - &hugectl); - +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_mime *mime = curl_mime_init(curl); + curl_mimepart *part = curl_mime_addpart(mime); + struct ctl hugectl; + + hugectl.buffer = hugedata; + hugectl.size = sizeof(hugedata); + hugectl.position = 0; + curl_mime_data_cb(part, hugectl.size, read_callback, seek_callback, NULL, + &hugectl); + } +} +.fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. .SH RETURN VALUE diff --git a/docs/libcurl/curl_mime_encoder.3 b/docs/libcurl/curl_mime_encoder.3 index 7e61d93d2..64c2636e3 100644 --- a/docs/libcurl/curl_mime_encoder.3 +++ b/docs/libcurl/curl_mime_encoder.3 @@ -74,20 +74,26 @@ a part with content set with \fIcurl_mime_subparts(3)\fP is strongly discouraged. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* add a part */ - part = curl_mime_addpart(mime); + /* add a part */ + part = curl_mime_addpart(mime); - /* send a file */ - curl_mime_filedata(part, "image.png"); + /* send a file */ + curl_mime_filedata(part, "image.png"); - /* encode file data in base64 for transfer */ - curl_mime_encoder(part, "base64"); + /* encode file data in base64 for transfer */ + curl_mime_encoder(part, "base64"); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_filedata.3 b/docs/libcurl/curl_mime_filedata.3 index 085ebbf0c..cb20fea42 100644 --- a/docs/libcurl/curl_mime_filedata.3 +++ b/docs/libcurl/curl_mime_filedata.3 @@ -58,20 +58,26 @@ Setting a part's contents multiple times is valid: only the value set by the last call is retained. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* add a part */ - part = curl_mime_addpart(mime); + /* add a part */ + part = curl_mime_addpart(mime); - /* send data from this file */ - curl_mime_filedata(part, "image.png"); + /* send data from this file */ + curl_mime_filedata(part, "image.png"); - /* set name */ - curl_mime_name(part, "data"); + /* set name */ + curl_mime_name(part, "data"); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_filename.3 b/docs/libcurl/curl_mime_filename.3 index 1241dfb77..a10bf803e 100644 --- a/docs/libcurl/curl_mime_filename.3 +++ b/docs/libcurl/curl_mime_filename.3 @@ -47,23 +47,32 @@ storage may safely be released or reused after call. Setting a part's file name multiple times is valid: only the value set by the last call is retained. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); +static char imagebuf[]="imagedata"; - /* add a part */ - part = curl_mime_addpart(mime); +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* send image data from memory */ - curl_mime_data(part, imagebuf, imagebuf_len); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* set a file name to make it look like a file upload */ - curl_mime_filename(part, "image.png"); + /* add a part */ + part = curl_mime_addpart(mime); - /* set name */ - curl_mime_name(part, "data"); + /* send image data from memory */ + curl_mime_data(part, imagebuf, sizeof(imagebuf)); + + /* set a file name to make it look like a file upload */ + curl_mime_filename(part, "image.png"); + + /* set name */ + curl_mime_name(part, "data"); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_free.3 b/docs/libcurl/curl_mime_free.3 index 8d4d32862..b37b15803 100644 --- a/docs/libcurl/curl_mime_free.3 +++ b/docs/libcurl/curl_mime_free.3 @@ -47,13 +47,19 @@ Passing in a NULL pointer in \fImime\fP makes this function return immediately with no action. .SH EXAMPLE .nf - /* Build the mime message. */ - mime = curl_mime_init(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* Build the mime message. */ + curl_mime *mime = curl_mime_init(curl); - /* ... */ + /* send off the transfer */ - /* Free multipart message. */ - curl_mime_free(mime); + /* Free multipart message. */ + curl_mime_free(mime); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_headers.3 b/docs/libcurl/curl_mime_headers.3 index e25ebef87..dd6a41669 100644 --- a/docs/libcurl/curl_mime_headers.3 +++ b/docs/libcurl/curl_mime_headers.3 @@ -47,18 +47,32 @@ Setting a part's custom headers list multiple times is valid: only the value set by the last call is retained. .SH EXAMPLE .nf - struct curl_slist *headers = NULL; +int main(void) +{ + struct curl_slist *headers = NULL; + CURL *easy = curl_easy_init(); + curl_mime *mime; + curl_mimepart *part; - headers = curl_slist_append(headers, "Custom-Header: mooo"); + headers = curl_slist_append(headers, "Custom-Header: mooo"); - /* use these headers, please take ownership */ - curl_mime_headers(part, headers, TRUE); + mime = curl_mime_init(easy); + part = curl_mime_addpart(mime); - /* pass on this data */ - curl_mime_data(part, "12345679", CURL_ZERO_TERMINATED); + /* use these headers in the part, takes ownership */ + curl_mime_headers(part, headers, 1); - /* set name */ - curl_mime_name(part, "numbers"); + /* pass on this data */ + curl_mime_data(part, "12345679", CURL_ZERO_TERMINATED); + + /* set name */ + curl_mime_name(part, "numbers"); + + /* Post and send it. */ + curl_easy_setopt(easy, CURLOPT_MIMEPOST, mime); + curl_easy_setopt(easy, CURLOPT_URL, "https://example.com"); + curl_easy_perform(easy); +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_init.3 b/docs/libcurl/curl_mime_init.3 index b48de436f..dc93fd15f 100644 --- a/docs/libcurl/curl_mime_init.3 +++ b/docs/libcurl/curl_mime_init.3 @@ -44,24 +44,28 @@ Using a mime handle is the recommended way to post an HTTP form, format and send a multi-part email with SMTP or upload such an email to an IMAP server. .SH EXAMPLE .nf - CURL *easy = curl_easy_init(); - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + CURL *easy = curl_easy_init(); + curl_mime *mime; + curl_mimepart *part; - /* Build an HTTP form with a single field named "data", */ - mime = curl_mime_init(easy); - part = curl_mime_addpart(mime); - curl_mime_data(part, "This is the field data", CURL_ZERO_TERMINATED); - curl_mime_name(part, "data"); + /* Build an HTTP form with a single field named "data", */ + mime = curl_mime_init(easy); + part = curl_mime_addpart(mime); + curl_mime_data(part, "This is the field data", CURL_ZERO_TERMINATED); + curl_mime_name(part, "data"); - /* Post and send it. */ - curl_easy_setopt(easy, CURLOPT_MIMEPOST, mime); - curl_easy_setopt(easy, CURLOPT_URL, "https://example.com"); - curl_easy_perform(easy); + /* Post and send it. */ + curl_easy_setopt(easy, CURLOPT_MIMEPOST, mime); + curl_easy_setopt(easy, CURLOPT_URL, "https://example.com"); + curl_easy_perform(easy); - /* Clean-up. */ - curl_easy_cleanup(easy); - curl_mime_free(mime); + /* Clean-up. */ + curl_easy_cleanup(easy); + curl_mime_free(mime); +} +.fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. .SH RETURN VALUE diff --git a/docs/libcurl/curl_mime_name.3 b/docs/libcurl/curl_mime_name.3 index a4ddeb83a..52953e548 100644 --- a/docs/libcurl/curl_mime_name.3 +++ b/docs/libcurl/curl_mime_name.3 @@ -44,17 +44,23 @@ is valid: only the value set by the last call is retained. It is possible to reset the name of a part by setting \fIname\fP to NULL. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* add a part */ - part = curl_mime_addpart(mime); + /* add a part */ + part = curl_mime_addpart(mime); - /* give the part a name */ - curl_mime_name(part, "shoe_size"); + /* give the part a name */ + curl_mime_name(part, "shoe_size"); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_subparts.3 b/docs/libcurl/curl_mime_subparts.3 index 45bc62c86..459f3cdcc 100644 --- a/docs/libcurl/curl_mime_subparts.3 +++ b/docs/libcurl/curl_mime_subparts.3 @@ -46,25 +46,38 @@ last call is retained. It is possible to unassign previous part's contents by setting \fIsubparts\fP to NULL. .SH EXAMPLE .nf - /* The inline part is an alternative proposing the html and the text - versions of the email. */ - alt = curl_mime_init(curl); - /* HTML message. */ - part = curl_mime_addpart(alt); - curl_mime_data(part, inline_html, CURL_ZERO_TERMINATED); - curl_mime_type(part, "text/html"); +static char *inline_html = "example"; +static char *inline_text = "once upon the time"; - /* Text message. */ - part = curl_mime_addpart(alt); - curl_mime_data(part, inline_text, CURL_ZERO_TERMINATED); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct curl_slist *slist; - /* Create the inline part. */ - part = curl_mime_addpart(mime); - curl_mime_subparts(part, alt); - curl_mime_type(part, "multipart/alternative"); - slist = curl_slist_append(NULL, "Content-Disposition: inline"); - curl_mime_headers(part, slist, 1); + /* The inline part is an alternative proposing the html and the text + versions of the email. */ + curl_mime *alt = curl_mime_init(curl); + curl_mimepart *part; + + /* HTML message. */ + part = curl_mime_addpart(alt); + curl_mime_data(part, inline_html, CURL_ZERO_TERMINATED); + curl_mime_type(part, "text/html"); + + /* Text message. */ + part = curl_mime_addpart(alt); + curl_mime_data(part, inline_text, CURL_ZERO_TERMINATED); + + /* Create the inline part. */ + part = curl_mime_addpart(alt); + curl_mime_subparts(part, alt); + curl_mime_type(part, "multipart/alternative"); + slist = curl_slist_append(NULL, "Content-Disposition: inline"); + curl_mime_headers(part, slist, 1); + } +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mime_type.3 b/docs/libcurl/curl_mime_type.3 index 74d7d9416..6d0c6a872 100644 --- a/docs/libcurl/curl_mime_type.3 +++ b/docs/libcurl/curl_mime_type.3 @@ -57,23 +57,29 @@ extension, or application/octet-stream by default. - text/plain in other cases. .SH EXAMPLE .nf - curl_mime *mime; - curl_mimepart *part; +int main(void) +{ + curl_mime *mime; + curl_mimepart *part; - /* create a mime handle */ - mime = curl_mime_init(easy); + CURL *curl = curl_easy_init(); + if(curl) { + /* create a mime handle */ + mime = curl_mime_init(curl); - /* add a part */ - part = curl_mime_addpart(mime); + /* add a part */ + part = curl_mime_addpart(mime); - /* get data from this file */ - curl_mime_filedata(part, "image.png"); + /* get data from this file */ + curl_mime_filedata(part, "image.png"); - /* content-type for this part */ - curl_mime_type(part, "image/png"); + /* content-type for this part */ + curl_mime_type(part, "image/png"); - /* set name */ - curl_mime_name(part, "image"); + /* set name */ + curl_mime_name(part, "image"); +} +} .fi .SH AVAILABILITY As long as at least one of HTTP, SMTP or IMAP is enabled. Added in 7.56.0. diff --git a/docs/libcurl/curl_mprintf.3 b/docs/libcurl/curl_mprintf.3 index c7e0a35dd..c60ef0a81 100644 --- a/docs/libcurl/curl_mprintf.3 +++ b/docs/libcurl/curl_mprintf.3 @@ -237,8 +237,13 @@ by the corresponding argument. A '%' is written. No argument is converted. .SH EXAMPLE .nf +const char *name = "John"; + +int main(void) +{ curl_mprintf("My name is %s\\n", name); - curl_mprintf("Pi is almost %f\\n", 25/8); + curl_mprintf("Pi is almost %f\\n", (double)25.0/8); +} .fi .SH AVAILABILITY These functions might be removed from the public libcurl API in the future. Do diff --git a/docs/libcurl/curl_multi_add_handle.3 b/docs/libcurl/curl_multi_add_handle.3 index f53673bd5..749b24e67 100644 --- a/docs/libcurl/curl_multi_add_handle.3 +++ b/docs/libcurl/curl_multi_add_handle.3 @@ -67,12 +67,19 @@ first the easy handle and then the multi handle: 3 - \fIcurl_multi_cleanup(3)\fP .SH EXAMPLE .nf +int main(void) +{ /* init a multi stack */ - multi_handle = curl_multi_init(); + CURLM *multi = curl_multi_init(); + + /* create two easy handles */ + CURL *http_handle = curl_easy_init(); + CURL *http_handle2 = curl_easy_init(); /* add individual transfers */ - curl_multi_add_handle(multi_handle, http_handle); - curl_multi_add_handle(multi_handle, http_handle2); + curl_multi_add_handle(multi, http_handle); + curl_multi_add_handle(multi, http_handle2); +} .fi .SH AVAILABILITY Added in 7.9.6 diff --git a/docs/libcurl/curl_multi_assign.3 b/docs/libcurl/curl_multi_assign.3 index 78714aa8f..5b6170536 100644 --- a/docs/libcurl/curl_multi_assign.3 +++ b/docs/libcurl/curl_multi_assign.3 @@ -54,8 +54,17 @@ functionality. It is acceptable to call this function from your multi callback functions. .SH EXAMPLE .nf - /* make our struct pointer associated with socket fd */ - mc = curl_multi_assign(multi_handle, fd, ourstructp); +int main(void) +{ + CURLM *multi = curl_multi_init(); + void *ourstructp; /* pointer to our data */ + curl_socket_t fd; /* file descriptor to associate our data with */ + + /* make our struct pointer associated with socket fd */ + CURLMcode mc = curl_multi_assign(multi, fd, ourstructp); + if(mc) + printf("error: %s\\n", curl_multi_strerror(mc)); +} .fi .SH AVAILABILITY Added in 7.15.5 diff --git a/docs/libcurl/curl_multi_cleanup.3 b/docs/libcurl/curl_multi_cleanup.3 index 8b41b78c4..751bce9fd 100644 --- a/docs/libcurl/curl_multi_cleanup.3 +++ b/docs/libcurl/curl_multi_cleanup.3 @@ -48,10 +48,15 @@ Passing in a NULL pointer in \fImulti_handle\fP makes this function return CURLM_BAD_HANDLE immediately with no other action. .SH EXAMPLE .nf - /* when the multi transfer is done ... */ +int main(void) +{ + CURLM *multi = curl_multi_init(); - /* remove all easy handles, then: */ - curl_multi_cleanup(multi_handle); + /* when the multi transfer is done ... */ + + /* remove all easy handles, then: */ + curl_multi_cleanup(multi); +} .fi .SH AVAILABILITY Added in 7.9.6 diff --git a/docs/libcurl/curl_multi_fdset.3 b/docs/libcurl/curl_multi_fdset.3 index dbcb5b2b5..8a3ae965a 100644 --- a/docs/libcurl/curl_multi_fdset.3 +++ b/docs/libcurl/curl_multi_fdset.3 @@ -33,7 +33,7 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle, fd_set *write_fd_set, fd_set *exc_fd_set, int *max_fd); -.ad +.fi .SH DESCRIPTION This function extracts file descriptor information from a given multi_handle. libcurl returns its \fIfd_set\fP sets. The application can use these to @@ -80,16 +80,35 @@ save you from the crash, but makes your program NOT wait for sockets it should wait for... .SH EXAMPLE .nf - /* get file descriptors from the transfers */ - mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); +int main(void) +{ + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd; + int rc; + CURLMcode mc; + struct timeval timeout = {1, 0}; + + CURLM *multi = curl_multi_init(); + + do { + + /* call curl_multi_perform() */ + + /* get file descriptors from the transfers */ + mc = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); + + if(mc != CURLM_OK) { + fprintf(stderr, "curl_multi_fdset() failed, code %d.\\n", mc); + break; + } - if(mc != CURLM_OK) { - fprintf(stderr, "curl_multi_fdset() failed, code %d.\\n", mc); - break; - } + /* wait for activity on one of the sockets */ + rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); - /* wait for activity on one of the sockets */ - rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); + } while(!mc); +} .fi .SH AVAILABILITY Added in 7.9.6 diff --git a/docs/libcurl/curl_multi_get_handles.3 b/docs/libcurl/curl_multi_get_handles.3 index 7ee6c734e..060c6e651 100644 --- a/docs/libcurl/curl_multi_get_handles.3 +++ b/docs/libcurl/curl_multi_get_handles.3 @@ -47,22 +47,29 @@ The order of the easy handles within the array is not guaranteed. The returned array must be freed with a call to \fIcurl_free(3)\fP after use. .SH EXAMPLE .nf +int main(void) +{ /* init a multi stack */ - multi_handle = curl_multi_init(); + CURLM *multi = curl_multi_init(); + CURL *curl = curl_easy_init(); - /* add a transfer */ - curl_multi_add_handle(multi_handle, http_handle); + if(curl) { + /* add the transfer */ + curl_multi_add_handle(multi, curl); - /* extract all added handles */ - CURL **list = curl_multi_get_handles(multi_handle); + /* extract all added handles */ + CURL **list = curl_multi_get_handles(multi); - if(list) { - /* remove all added handles */ - for(i = 0; list[i]; i++) { - curl_multi_remove_handle(multi_handle, list[i]); + if(list) { + int i; + /* remove all added handles */ + for(i = 0; list[i]; i++) { + curl_multi_remove_handle(multi, list[i]); + } + curl_free(list); } - curl_free(list); } +} .fi .SH AVAILABILITY Added in 8.4.0 diff --git a/docs/libcurl/curl_multi_info_read.3 b/docs/libcurl/curl_multi_info_read.3 index 2a15ad582..c833548c8 100644 --- a/docs/libcurl/curl_multi_info_read.3 +++ b/docs/libcurl/curl_multi_info_read.3 @@ -72,21 +72,28 @@ that just completed. At this point, there are no other \fBmsg\fP types defined. .SH EXAMPLE .nf -struct CURLMsg *m; +int main(void) +{ + CURLM *multi = curl_multi_init(); + CURL *curl = curl_easy_init(); + if(curl) { + struct CURLMsg *m; -/* call curl_multi_perform or curl_multi_socket_action first, then loop - through and check if there are any transfers that have completed */ + /* call curl_multi_perform or curl_multi_socket_action first, then loop + through and check if there are any transfers that have completed */ -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); + do { + int msgq = 0; + m = curl_multi_info_read(multi, &msgq); + if(m && (m->msg == CURLMSG_DONE)) { + CURL *e = m->easy_handle; + /* m->data.result holds the error code for the transfer */ + curl_multi_remove_handle(multi, e); + curl_easy_cleanup(e); + } + } while(m); } -} while(m); +} .fi .SH AVAILABILITY Added in 7.9.6 diff --git a/docs/libcurl/curl_multi_init.3 b/docs/libcurl/curl_multi_init.3 index 5fe21b781..9b589a11e 100644 --- a/docs/libcurl/curl_multi_init.3 +++ b/docs/libcurl/curl_multi_init.3 @@ -37,12 +37,17 @@ places in the documentation. This init call MUST have a corresponding call to \fIcurl_multi_cleanup(3)\fP when the operation is complete. .SH EXAMPLE .nf -/* init a multi stack */ -multi_handle = curl_multi_init(); +int main(void) +{ + /* init a multi stack */ + CURLM *multi = curl_multi_init(); + CURL *curl = curl_easy_init(); + CURL *curl2 = curl_easy_init(); -/* add individual transfers */ -curl_multi_add_handle(multi_handle, http_handle); -curl_multi_add_handle(multi_handle, http_handle2); + /* add individual transfers */ + curl_multi_add_handle(multi, curl); + curl_multi_add_handle(multi, curl2); +} .fi .SH AVAILABILITY Added in 7.9.6 diff --git a/docs/libcurl/curl_multi_perform.3 b/docs/libcurl/curl_multi_perform.3 index 49ad6e02c..8088c433e 100644 --- a/docs/libcurl/curl_multi_perform.3 +++ b/docs/libcurl/curl_multi_perform.3 @@ -62,21 +62,29 @@ again on the same multi handle after an error has been returned, unless first removing all the handles and adding new ones. .SH EXAMPLE .nf -int still_running; -do { - CURLMcode mc = curl_multi_perform(multi_handle, &still_running); +int main(void) +{ + int still_running; + CURL *multi = curl_multi_init(); + CURL *curl = curl_easy_init(); + if(curl) { + curl_multi_add_handle(multi, curl); + do { + CURLMcode mc = curl_multi_perform(multi, &still_running); - if(!mc && still_running) - /* wait for activity, timeout or "nothing" */ - mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); + if(!mc && still_running) + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_poll(multi, NULL, 0, 1000, NULL); - if(mc) { - fprintf(stderr, "curl_multi_poll() failed, code %d.\\n", (int)mc); - break; - } + if(mc) { + fprintf(stderr, "curl_multi_poll() failed, code %d.\\n", (int)mc); + break; + } -/* if there are still transfers, loop! */ -} while(still_running); + /* if there are still transfers, loop! */ + } while(still_running); + } +} .fi .SH AVAILABILITY Added in 7.9.6 diff --git a/docs/libcurl/curl_multi_poll.3 b/docs/libcurl/curl_multi_poll.3 index c70912316..dfc5bbd55 100644 --- a/docs/libcurl/curl_multi_poll.3 +++ b/docs/libcurl/curl_multi_poll.3 @@ -33,7 +33,7 @@ CURLMcode curl_multi_poll(CURLM *multi_handle, unsigned int extra_nfds, int timeout_ms, int *numfds); -.ad +.fi .SH DESCRIPTION \fIcurl_multi_poll(3)\fP polls all file descriptors used by the curl easy handles contained in the given multi handle set. It blocks until activity is @@ -83,31 +83,35 @@ Bit flag to curl_waitfd.events indicating the socket should poll on write events such as the socket being clear to write without blocking. .SH EXAMPLE .nf -CURL *easy_handle; -CURLM *multi_handle; +int main(void) +{ + CURL *easy_handle; + CURLM *multi_handle; + int still_running = 0; -/* add the individual easy handle */ -curl_multi_add_handle(multi_handle, easy_handle); + /* add the individual easy handle */ + curl_multi_add_handle(multi_handle, easy_handle); -do { - CURLMcode mc; - int numfds; + do { + CURLMcode mc; + int numfds; - mc = curl_multi_perform(multi_handle, &still_running); + mc = curl_multi_perform(multi_handle, &still_running); - if(mc == CURLM_OK) { - /* wait for activity or timeout */ - mc = curl_multi_poll(multi_handle, NULL, 0, 1000, &numfds); - } + if(mc == CURLM_OK) { + /* wait for activity or timeout */ + mc = curl_multi_poll(multi_handle, NULL, 0, 1000, &numfds); + } - if(mc != CURLM_OK) { - fprintf(stderr, "curl_multi failed, code %d.\\n", mc); - break; - } + if(mc != CURLM_OK) { + fprintf(stderr, "curl_multi failed, code %d.\\n", mc); + break; + } -} while(still_running); + } while(still_running); -curl_multi_remove_handle(multi_handle, easy_handle); + curl_multi_remove_handle(multi_handle, easy_handle); +} .fi .SH AVAILABILITY Added in 7.66.0. diff --git a/docs/libcurl/curl_multi_remove_handle.3 b/docs/libcurl/curl_multi_remove_handle.3 index dccf75f92..eb2aaf399 100644 --- a/docs/libcurl/curl_multi_remove_handle.3 +++ b/docs/libcurl/curl_multi_remove_handle.3 @@ -52,13 +52,19 @@ multi handle, ready to get reused for a future transfer using this multi handle. .SH EXAMPLE .nf -/* when an easy handle has completed, remove it */ -msg = curl_multi_info_read(multi_handle, &queued); -if(msg) { - if(msg->msg == CURLMSG_DONE) { - /* a transfer ended */ - fprintf(stderr, "Transfer completed\\n"); - curl_multi_remove_handle(multi_handle, msg->easy_handle); +int main(void) +{ + CURLM *multi = curl_multi_init(); + int queued = 0; + + /* when an easy handle has completed, remove it */ + CURLMsg *msg = curl_multi_info_read(multi, &queued); + if(msg) { + if(msg->msg == CURLMSG_DONE) { + /* a transfer ended */ + fprintf(stderr, "Transfer completed\\n"); + curl_multi_remove_handle(multi, msg->easy_handle); + } } } .fi diff --git a/docs/libcurl/curl_multi_setopt.3 b/docs/libcurl/curl_multi_setopt.3 index f09765355..1752fe4fd 100644 --- a/docs/libcurl/curl_multi_setopt.3 +++ b/docs/libcurl/curl_multi_setopt.3 @@ -28,17 +28,17 @@ curl_multi_setopt \- set options for a curl multi handle .nf #include -CURLMcode curl_multi_setopt(CURLM *multi_handle, CURLMoption option, param); +CURLMcode curl_multi_setopt(CURLM *multi_handle, CURLMoption option, parameter); .fi .SH DESCRIPTION \fIcurl_multi_setopt(3)\fP is used to tell a libcurl multi handle how to behave. By using the appropriate options to \fIcurl_multi_setopt(3)\fP, you can change libcurl's behavior when using that multi handle. All options are -set with the \fIoption\fP followed by the parameter \fIparam\fP. That -parameter can be a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject -pointer\fP or a \fBcurl_off_t\fP type, depending on what the specific option -expects. Read this manual carefully as bad input values may cause libcurl to -behave badly. You can only set one option in each function call. +set with the \fIoption\fP followed by the \fIparameter\fP. That parameter can +be a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a +\fBcurl_off_t\fP type, depending on what the specific option expects. Read +this manual carefully as bad input values may cause libcurl to behave +badly. You can only set one option in each function call. .SH OPTIONS .IP CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE @@ -74,10 +74,17 @@ See \fICURLMOPT_TIMERDATA(3)\fP .IP CURLMOPT_MAX_CONCURRENT_STREAMS See \fICURLMOPT_MAX_CONCURRENT_STREAMS(3)\fP .SH EXAMPLE -.fi - /* Limit the amount of simultaneous connections curl should allow: */ - curl_multi_setopt(handle, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL); .nf + +#define MAX_PARALLEL 45 + +int main(void) +{ + CURLM *multi; + /* Limit the amount of simultaneous connections curl should allow: */ + curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL); +} +.fi .SH AVAILABILITY Added in 7.15.4 .SH RETURN VALUE diff --git a/docs/libcurl/curl_multi_socket.3 b/docs/libcurl/curl_multi_socket.3 index 140776f3d..e4759eb2d 100644 --- a/docs/libcurl/curl_multi_socket.3 +++ b/docs/libcurl/curl_multi_socket.3 @@ -70,10 +70,16 @@ just a single one by calling \fIcurl_multi_socket_all(3)\fP. Note that there should not be any reason to use this function. .SH EXAMPLE .nf -/* the event-library gets told when there activity on the socket 'fd', - which we translate to a call to curl_multi_socket_action() */ -int running; -rc = curl_multi_socket(multi_handle, fd, &running); +int main(void) +{ + /* the event-library gets told when there activity on the socket 'fd', + which we translate to a call to curl_multi_socket_action() */ + int running; + int rc; + int fd; + CURLM *multi; + rc = curl_multi_socket(multi, fd, &running); +} .fi .SH AVAILABILITY This function was added in libcurl 7.15.4, and is deemed stable since diff --git a/docs/libcurl/curl_multi_socket_action.3 b/docs/libcurl/curl_multi_socket_action.3 index 265a9f85a..445ac2c8d 100644 --- a/docs/libcurl/curl_multi_socket_action.3 +++ b/docs/libcurl/curl_multi_socket_action.3 @@ -97,11 +97,18 @@ socket(s) that got action. If no activity is detected and the timeout expires, call \fIcurl_multi_socket_action(3)\fP with \fICURL_SOCKET_TIMEOUT\fP. .SH EXAMPLE .nf -/* the event-library gets told when there activity on the socket 'fd', - which we translate to a call to curl_multi_socket_action() */ -int running; -rc = curl_multi_socket_action(multi_handle, fd, EVENT, - &running); +int main(void) +{ + /* the event-library gets told when there activity on the socket 'fd', + which we translate to a call to curl_multi_socket_action() */ + int running; + CURLM *multi; /* the stack we work with */ + int fd; /* the descriptor that had action */ + int bitmask; /* what activity that happened */ + CURLMcode mc = curl_multi_socket_action(multi, fd, bitmask, &running); + if(mc) + printf("error: %s\\n", curl_multi_strerror(mc)); +} .fi .SH AVAILABILITY This function was added in libcurl 7.15.4, and is deemed stable since 7.16.0. diff --git a/docs/libcurl/curl_multi_strerror.3 b/docs/libcurl/curl_multi_strerror.3 index 7dd7e8892..598767910 100644 --- a/docs/libcurl/curl_multi_strerror.3 +++ b/docs/libcurl/curl_multi_strerror.3 @@ -26,18 +26,24 @@ curl_multi_strerror - return string describing error code .SH SYNOPSIS .nf -.B #include -.BI "const char *curl_multi_strerror(CURLMcode " errornum ");" +#include + +const char *curl_multi_strerror(CURLMcode errornum); +.fi .SH DESCRIPTION This function returns a string describing the \fICURLMcode\fP error code passed in the argument \fIerrornum\fP. .SH EXAMPLE .nf -int still_running; +int main(void) +{ + int still_running; + CURLM *multi = curl_multi_init(); -CURLMcode mc = curl_multi_perform(multi_handle, &still_running); -if(mc) - printf("error: %s\\n", curl_multi_strerror(mc)); + CURLMcode mc = curl_multi_perform(multi, &still_running); + if(mc) + printf("error: %s\\n", curl_multi_strerror(mc)); +} .fi .SH AVAILABILITY This function was added in libcurl 7.12.0 diff --git a/docs/libcurl/curl_multi_timeout.3 b/docs/libcurl/curl_multi_timeout.3 index 23abe9491..1951282ee 100644 --- a/docs/libcurl/curl_multi_timeout.3 +++ b/docs/libcurl/curl_multi_timeout.3 @@ -54,19 +54,27 @@ currently has no stored timeout value. You must not wait too long (more than a few seconds perhaps) before you call \fIcurl_multi_perform(3)\fP again. .SH EXAMPLE .nf -struct timeval timeout; -long timeo; +int main(void) +{ + struct timeval timeout; + long timeo; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd; + CURLM *multi = curl_multi_init(); -curl_multi_timeout(multi_handle, &timeo); -if(timeo < 0) - /* no set timeout, use a default */ - timeo = 980; + curl_multi_timeout(multi, &timeo); + if(timeo < 0) + /* no set timeout, use a default */ + timeo = 980; -timeout.tv_sec = timeo / 1000; -timeout.tv_usec = (timeo % 1000) * 1000; + timeout.tv_sec = timeo / 1000; + timeout.tv_usec = (timeo % 1000) * 1000; -/* wait for activities no longer than the set timeout */ -select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); + /* wait for activities no longer than the set timeout */ + select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); +} .fi .SH TYPICAL USAGE Call \fIcurl_multi_timeout(3)\fP, then wait for action on the sockets. Figure diff --git a/docs/libcurl/curl_multi_wait.3 b/docs/libcurl/curl_multi_wait.3 index 565fdb8de..1f73dc354 100644 --- a/docs/libcurl/curl_multi_wait.3 +++ b/docs/libcurl/curl_multi_wait.3 @@ -33,7 +33,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle, unsigned int extra_nfds, int timeout_ms, int *numfds); -.ad +.fi .SH DESCRIPTION \fIcurl_multi_wait(3)\fP polls all file descriptors used by the curl easy handles contained in the given multi handle set. It blocks until activity is @@ -77,45 +77,35 @@ Bit flag to \fIcurl_waitfd.events\fP indicating the socket should poll on write events such as the socket being clear to write without blocking. .SH EXAMPLE .nf -CURL *easy_handle; -CURLM *multi_handle; - -/* add the individual easy handle */ -curl_multi_add_handle(multi_handle, easy_handle); +int main(void) +{ + CURL *easy; + CURLM *multi = curl_multi_init(); + int still_running; -do { - CURLMcode mc; - int numfds; + /* add the individual easy handle */ + curl_multi_add_handle(multi, easy); - mc = curl_multi_perform(multi_handle, &still_running); + do { + CURLMcode mc; + int numfds; - if(mc == CURLM_OK ) { - /* wait for activity, timeout or "nothing" */ - mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); - } + mc = curl_multi_perform(multi, &still_running); - if(mc != CURLM_OK) { - fprintf(stderr, "curl_multi failed, code %d.\\n", mc); - break; - } - - /* 'numfds' being zero means either a timeout or no file descriptors to - wait for. Try timeout on first occurrence, then assume no file - descriptors and no file descriptors to wait for means wait for 100 - milliseconds. */ + if(mc == CURLM_OK) { + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_wait(multi, NULL, 0, 1000, &numfds); + } - if(!numfds) { - repeats++; /* count number of repeated zero numfds */ - if(repeats > 1) { - WAITMS(100); /* sleep 100 milliseconds */ + if(mc != CURLM_OK) { + fprintf(stderr, "curl_multi failed, code %d.\\n", mc); + break; } - } - else - repeats = 0; -} while(still_running); + } while(still_running); -curl_multi_remove_handle(multi_handle, easy_handle); + curl_multi_remove_handle(multi, easy); +} .fi .SH AVAILABILITY This function was added in libcurl 7.28.0. diff --git a/docs/libcurl/curl_multi_wakeup.3 b/docs/libcurl/curl_multi_wakeup.3 index c4a71b678..980923279 100644 --- a/docs/libcurl/curl_multi_wakeup.3 +++ b/docs/libcurl/curl_multi_wakeup.3 @@ -45,40 +45,47 @@ that multiple calls to this function wake up the same waiting operation. This function has no effect on \fIcurl_multi_wait(3)\fP calls. .SH EXAMPLE .nf -CURL *easy_handle; -CURLM *multi_handle; +extern int time_to_die(void); +extern int set_something_to_signal_thread_1_to_exit(void); +extern int decide_to_stop_thread1(); -/* add the individual easy handle */ -curl_multi_add_handle(multi_handle, easy_handle); +int main(void) +{ + CURL *easy; + CURLM *multi; + int still_running; -/* this is thread 1 */ -do { - CURLMcode mc; - int numfds; + /* add the individual easy handle */ + curl_multi_add_handle(multi, easy); - mc = curl_multi_perform(multi_handle, &still_running); + /* this is thread 1 */ + do { + CURLMcode mc; + int numfds; - if(mc == CURLM_OK) { - /* wait for activity, timeout or wakeup */ - mc = curl_multi_poll(multi_handle, NULL, 0, 10000, &numfds); - } + mc = curl_multi_perform(multi, &still_running); - if(time_to_die()) - exit(1); + if(mc == CURLM_OK) { + /* wait for activity, timeout or wakeup */ + mc = curl_multi_poll(multi, NULL, 0, 10000, &numfds); + } -} while(still_running); + if(time_to_die()) + return 1; -curl_multi_remove_handle(multi_handle, easy_handle); + } while(still_running); -/* this is thread 2 */ + curl_multi_remove_handle(multi, easy); -if(something makes us decide to stop thread 1) { + /* this is thread 2 */ - set_something_to_signal_thread_1_to_exit(); + if(decide_to_stop_thread1()) { - curl_multi_wakeup(multi_handle); -} + set_something_to_signal_thread_1_to_exit(); + curl_multi_wakeup(multi); + } +} .fi .SH AVAILABILITY Added in 7.68.0 diff --git a/docs/libcurl/curl_pushheader_byname.3 b/docs/libcurl/curl_pushheader_byname.3 index 4b0aff7b6..ad8459c36 100644 --- a/docs/libcurl/curl_pushheader_byname.3 +++ b/docs/libcurl/curl_pushheader_byname.3 @@ -43,11 +43,13 @@ one header field use the same name, this returns only the first one. .SH EXAMPLE .nf -int curl_push_callback(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *clientp) +#include /* for strncmp */ + +static int push_cb(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *clientp) { char *headp; int *transfers = (int *)clientp; @@ -69,8 +71,13 @@ int curl_push_callback(CURL *parent, return CURL_PUSH_DENY; } -curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, curl_push_callback); -curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); +int main(void) +{ + int counter; + CURLM *multi = curl_multi_init(); + curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_cb); + curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); +} .fi .SH AVAILABILITY Added in 7.44.0 diff --git a/docs/libcurl/curl_pushheader_bynum.3 b/docs/libcurl/curl_pushheader_bynum.3 index 491c00432..da951bafb 100644 --- a/docs/libcurl/curl_pushheader_bynum.3 +++ b/docs/libcurl/curl_pushheader_bynum.3 @@ -43,13 +43,13 @@ libcurl when this callback returns. The returned pointer points to a .SH EXAMPLE .nf /* output all the incoming push request headers */ -int curl_push_callback(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *clientp) +static int push_cb(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *clientp) { - sizt_t i = 0; + int i = 0; char *field; do { field = curl_pushheader_bynum(headers, i); @@ -60,7 +60,11 @@ int curl_push_callback(CURL *parent, return CURL_PUSH_OK; /* permission granted */ } -curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, curl_push_callback); +int main(void) +{ + CURLM *multi = curl_multi_init(); + curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_cb); +} .fi .SH AVAILABILITY Added in 7.44.0 diff --git a/docs/libcurl/curl_share_cleanup.3 b/docs/libcurl/curl_share_cleanup.3 index 93f098e2a..ad49857f2 100644 --- a/docs/libcurl/curl_share_cleanup.3 +++ b/docs/libcurl/curl_share_cleanup.3 @@ -38,11 +38,14 @@ Passing in a NULL pointer in \fIshare_handle\fP makes this function return immediately with no action. .SH EXAMPLE .nf +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); /* use the share, then ... */ curl_share_cleanup(share); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/curl_share_init.3 b/docs/libcurl/curl_share_init.3 index f414a14f3..b68c4bd8d 100644 --- a/docs/libcurl/curl_share_init.3 +++ b/docs/libcurl/curl_share_init.3 @@ -42,11 +42,14 @@ This \fIshare handle\fP is what you pass to curl using the specific curl handle use the data in this share. .SH EXAMPLE .nf +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/curl_share_setopt.3 b/docs/libcurl/curl_share_setopt.3 index d894291ba..960354991 100644 --- a/docs/libcurl/curl_share_setopt.3 +++ b/docs/libcurl/curl_share_setopt.3 @@ -45,11 +45,14 @@ See \fICURLSHOPT_UNSHARE(3)\fP. See \fICURLSHOPT_USERDATA(3)\fP. .SH EXAMPLE .nf +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/curl_share_strerror.3 b/docs/libcurl/curl_share_strerror.3 index 6dd857dca..b1f5e2f39 100644 --- a/docs/libcurl/curl_share_strerror.3 +++ b/docs/libcurl/curl_share_strerror.3 @@ -26,18 +26,23 @@ curl_share_strerror - return string describing error code .SH SYNOPSIS .nf -.B #include -.BI "const char *curl_share_strerror(CURLSHcode " errornum ");" +#include + +const char *curl_share_strerror(CURLSHcode errornum); +.fi .SH DESCRIPTION The \fIcurl_share_strerror(3)\fP function returns a string describing the \fICURLSHcode\fP error code passed in the argument \fIerrornum\fP. .SH EXAMPLE .nf +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY This function was added in libcurl 7.12.0 diff --git a/docs/libcurl/curl_slist_append.3 b/docs/libcurl/curl_slist_append.3 index b869d3aea..09dbc99a4 100644 --- a/docs/libcurl/curl_slist_append.3 +++ b/docs/libcurl/curl_slist_append.3 @@ -42,29 +42,32 @@ The list should be freed again (after usage) with \fIcurl_slist_free_all(3)\fP. .SH EXAMPLE .nf -CURL *handle; -struct curl_slist *slist=NULL; -struct curl_slist *temp=NULL; +int main(void) +{ + CURL *handle; + struct curl_slist *slist = NULL; + struct curl_slist *temp = NULL; -slist = curl_slist_append(slist, "pragma:"); + slist = curl_slist_append(slist, "pragma:"); -if (slist == NULL) - return -1; + if(!slist) + return -1; -temp = curl_slist_append(slist, "Accept:") + temp = curl_slist_append(slist, "Accept:"); -if (temp == NULL) { - curl_slist_free_all(slist); - return -1; -} + if(!temp) { + curl_slist_free_all(slist); + return -1; + } -slist = temp; + slist = temp; -curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist); -curl_easy_perform(handle); + curl_easy_perform(handle); -curl_slist_free_all(slist); /* free the list again */ + curl_slist_free_all(slist); /* free the list again */ +} .fi .SH AVAILABILITY Always diff --git a/docs/libcurl/curl_slist_free_all.3 b/docs/libcurl/curl_slist_free_all.3 index 5b562a063..4eeb54132 100644 --- a/docs/libcurl/curl_slist_free_all.3 +++ b/docs/libcurl/curl_slist_free_all.3 @@ -38,19 +38,22 @@ Passing in a NULL pointer in \fIlist\fP makes this function return immediately with no action. .SH EXAMPLE .nf -CURL *handle; -struct curl_slist *slist=NULL; +int main(void) +{ + CURL *handle; + struct curl_slist *slist = NULL; -slist = curl_slist_append(slist, "X-libcurl: coolness"); + slist = curl_slist_append(slist, "X-libcurl: coolness"); -if (slist == NULL) - return -1; + if(!slist) + return -1; -curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist); -curl_easy_perform(handle); + curl_easy_perform(handle); -curl_slist_free_all(slist); /* free the list again */ + curl_slist_free_all(slist); /* free the list again */ +} .fi .SH AVAILABILITY Always diff --git a/docs/libcurl/curl_strequal.3 b/docs/libcurl/curl_strequal.3 index c66c6529a..89eec323f 100644 --- a/docs/libcurl/curl_strequal.3 +++ b/docs/libcurl/curl_strequal.3 @@ -28,8 +28,8 @@ curl_strequal, curl_strnequal - case insensitive string comparisons .nf #include -int curl_strequal(char *str1, char *str2); -int curl_strnequal(char *str1, char *str2, size_t length); +int curl_strequal(const char *str1, const char *str2); +int curl_strnequal(const char *str1, const char *str2, size_t length); .fi .SH DESCRIPTION The @@ -46,10 +46,14 @@ strings in a truly portable manner. There are no standard portable case insensitive string comparison functions. These two work on all platforms. .SH EXAMPLE .nf -if(curl_strequal(name, input)) - printf("Name and input matches\\n"); -if(curl_strnequal(name, input, 5)) - printf("Name and input matches in the 5 first bytes\\n"); +int main(int argc, char **argv) +{ + const char *name = "compare"; + if(curl_strequal(name, argv[1])) + printf("Name and input matches\\n"); + if(curl_strnequal(name, argv[1], 5)) + printf("Name and input matches in the 5 first bytes\\n"); +} .fi .SH AVAILABILITY Always diff --git a/docs/libcurl/curl_unescape.3 b/docs/libcurl/curl_unescape.3 index d91349282..5df8a8f82 100644 --- a/docs/libcurl/curl_unescape.3 +++ b/docs/libcurl/curl_unescape.3 @@ -44,15 +44,17 @@ strlen() on \fBinput\fP to find out the size. You must \fIcurl_free(3)\fP the returned string when you are done with it. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - int decodelen; - char *decoded = curl_unescape("%63%75%72%6c", 12, &decodelen); - if(decoded) { - /* do not assume printf() works on the decoded data! */ - printf("Decoded: "); - /* ... */ - curl_free(decoded); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + char *decoded = curl_unescape("%63%75%72%6c", 12); + if(decoded) { + /* do not assume printf() works on the decoded data! */ + printf("Decoded: "); + /* ... */ + curl_free(decoded); + } } } .fi diff --git a/docs/libcurl/curl_url.3 b/docs/libcurl/curl_url.3 index 01eb55e61..3f6eb0c01 100644 --- a/docs/libcurl/curl_url.3 +++ b/docs/libcurl/curl_url.3 @@ -40,6 +40,8 @@ stored. They are then set in the object with the \fIcurl_url_set(3)\fP function. .SH EXAMPLE .nf +int main(void) +{ CURLUcode rc; CURLU *url = curl_url(); rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); @@ -52,6 +54,7 @@ function. } curl_url_cleanup(url); } +} .fi .SH AVAILABILITY Added in 7.62.0 diff --git a/docs/libcurl/curl_url_cleanup.3 b/docs/libcurl/curl_url_cleanup.3 index 7dc5f61a7..94507efc3 100644 --- a/docs/libcurl/curl_url_cleanup.3 +++ b/docs/libcurl/curl_url_cleanup.3 @@ -37,9 +37,12 @@ Passing in a NULL pointer in \fIhandle\fP makes this function return immediately with no action. .SH EXAMPLE .nf +int main(void) +{ CURLU *url = curl_url(); curl_url_set(url, CURLUPART_URL, "https://example.com", 0); curl_url_cleanup(url); +} .fi .SH AVAILABILITY Added in 7.62.0 diff --git a/docs/libcurl/curl_url_dup.3 b/docs/libcurl/curl_url_dup.3 index a2e9850b5..228834771 100644 --- a/docs/libcurl/curl_url_dup.3 +++ b/docs/libcurl/curl_url_dup.3 @@ -28,7 +28,7 @@ curl_url_dup - duplicate a URL handle .nf #include -CURLU *curl_url_dup(CURLU *inhandle); +CURLU *curl_url_dup(const CURLU *inhandle); .fi .SH DESCRIPTION Duplicates the URL object the input \fICURLU\fP \fIinhandle\fP identifies and @@ -36,6 +36,8 @@ returns a pointer to the copy as a new \fICURLU\fP handle. The new handle also needs to be freed with \fIcurl_url_cleanup(3)\fP. .SH EXAMPLE .nf +int main(void) +{ CURLUcode rc; CURLU *url = curl_url(); CURLU *url2; @@ -45,6 +47,7 @@ needs to be freed with \fIcurl_url_cleanup(3)\fP. curl_url_cleanup(url2); } curl_url_cleanup(url); +} .fi .SH AVAILABILITY Added in 7.62.0 diff --git a/docs/libcurl/curl_url_get.3 b/docs/libcurl/curl_url_get.3 index 815e5587e..1940f4b6a 100644 --- a/docs/libcurl/curl_url_get.3 +++ b/docs/libcurl/curl_url_get.3 @@ -28,7 +28,7 @@ curl_url_get - extract a part from a URL .nf #include -CURLUcode curl_url_get(CURLU *url, +CURLUcode curl_url_get(const CURLU *url, CURLUPart part, char **content, unsigned int flags); @@ -145,6 +145,8 @@ The initial hash sign that denotes the beginning of the fragment is a delimiter only. It is not part of the fragment contents. .SH EXAMPLE .nf +int main(void) +{ CURLUcode rc; CURLU *url = curl_url(); rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); @@ -157,6 +159,7 @@ delimiter only. It is not part of the fragment contents. } curl_url_cleanup(url); } +} .fi .SH AVAILABILITY Added in 7.62.0. CURLUPART_ZONEID was added in 7.65.0. diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 index 912694f7b..e5b1790b8 100644 --- a/docs/libcurl/curl_url_set.3 +++ b/docs/libcurl/curl_url_set.3 @@ -179,15 +179,17 @@ If set, the URL parser does not accept embedded credentials for the such URLs. .SH EXAMPLE .nf +int main(void) +{ CURLUcode rc; CURLU *url = curl_url(); rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); if(!rc) { - char *scheme; /* change it to an FTP URL */ rc = curl_url_set(url, CURLUPART_SCHEME, "ftp", 0); } curl_url_cleanup(url); +} .fi .SH AVAILABILITY Added in 7.62.0. CURLUPART_ZONEID was added in 7.65.0. diff --git a/docs/libcurl/curl_url_strerror.3 b/docs/libcurl/curl_url_strerror.3 index b3fd40379..38af12e9c 100644 --- a/docs/libcurl/curl_url_strerror.3 +++ b/docs/libcurl/curl_url_strerror.3 @@ -26,21 +26,25 @@ curl_url_strerror - return string describing error code .SH SYNOPSIS .nf -.B #include -.BI "const char *curl_url_strerror(CURLUcode " errornum ");" +#include + +const char *curl_url_strerror(CURLUcode errornum); +.fi .SH DESCRIPTION This function returns a string describing the CURLUcode error code passed in the argument \fIerrornum\fP. .SH EXAMPLE .nf +int main(void) +{ CURLUcode rc; CURLU *url = curl_url(); rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); if(rc) printf("URL error: %s\\n", curl_url_strerror(rc)); curl_url_cleanup(url); +} .fi - .SH AVAILABILITY Added in 7.80.0 .SH RETURN VALUE diff --git a/docs/libcurl/curl_version.3 b/docs/libcurl/curl_version.3 index 0036778e7..fdf09d1ba 100644 --- a/docs/libcurl/curl_version.3 +++ b/docs/libcurl/curl_version.3 @@ -37,7 +37,10 @@ its important components (like OpenSSL version). We recommend using \fIcurl_version_info(3)\fP instead! .SH EXAMPLE .nf -printf("libcurl version %s\\n", curl_version()); +int main(void) +{ + printf("libcurl version %s\\n", curl_version()); +} .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3 index ac07abee3..e7fb8af65 100644 --- a/docs/libcurl/curl_version_info.3 +++ b/docs/libcurl/curl_version_info.3 @@ -306,11 +306,14 @@ names are the same as would be used in URLs. The array is terminated by a NULL entry. .SH EXAMPLE .nf -curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW); -printf("libcurl version %u.%u.%u\\n", - (ver->version_num >> 16) & 0xff, - (ver->version_num >> 8) & 0xff, - ver->version_num & 0xff); +int main(void) +{ + curl_version_info_data *ver = curl_version_info(CURLVERSION_NOW); + printf("libcurl version %u.%u.%u\\n", + (ver->version_num >> 16) & 0xff, + (ver->version_num >> 8) & 0xff, + ver->version_num & 0xff); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/curl_ws_meta.3 b/docs/libcurl/curl_ws_meta.3 index d9ab43a11..8623ad089 100644 --- a/docs/libcurl/curl_ws_meta.3 +++ b/docs/libcurl/curl_ws_meta.3 @@ -27,14 +27,7 @@ curl_ws_meta - meta data WebSocket information .SH SYNOPSIS .nf -#include - -struct curl_ws_frame { - int age; /* zero */ - int flags; /* See the CURLWS_* defines */ - curl_off_t offset; /* the offset of this data into the frame */ - curl_off_t bytesleft; /* number of pending bytes left of the payload */ -}; +#include const struct curl_ws_frame *curl_ws_meta(CURL *curl); .fi @@ -53,7 +46,15 @@ what transfer the question is about, but as there is no such pointer provided to the callback by libcurl itself, applications that want to use \fIcurl_ws_meta(3)\fP need to pass it on to the callback on its own. -.SH "struct fields" +.SH "struct curl_ws_frame" +.nf +struct curl_ws_frame { + int age; + int flags; + curl_off_t offset; + curl_off_t bytesleft; +}; +.fi .IP age This field specify the age of this struct. It is always zero for now. .IP flags @@ -95,15 +96,22 @@ static size_t writecb(unsigned char *buffer, struct customdata *c = (struct customdata *)p; const struct curl_ws_frame *m = curl_ws_meta(c->easy); - /* m->flags tells us about the traffic */ + printf("flags: %x\\n", m->flags); } +int main(void) { - struct customdata custom; - custom.easy = easy; - custom.ptr = NULL; - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &custom); + CURL *curl = curl_easy_init(); + if(curl) { + struct customdata custom; + custom.easy = curl; + custom.ptr = NULL; + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &custom); + + curl_easy_perform(curl); + + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/curl_ws_recv.3 b/docs/libcurl/curl_ws_recv.3 index a9df029e8..e35d93688 100644 --- a/docs/libcurl/curl_ws_recv.3 +++ b/docs/libcurl/curl_ws_recv.3 @@ -27,7 +27,7 @@ curl_ws_recv - receive WebSocket data .SH SYNOPSIS .nf -#include +#include CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, size_t *recv, const struct curl_ws_frame **meta); @@ -48,10 +48,18 @@ that contains information about the received data. See the \fIcurl_ws_meta(3)\fP for details on that struct. .SH EXAMPLE .nf +int main(void) +{ size_t rlen; const struct curl_ws_frame *meta; char buffer[256]; - CURLcode result = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res = curl_ws_recv(curl, buffer, sizeof(buffer), &rlen, &meta); + if(res) + printf("error: %s\\n", curl_easy_strerror(res)); + } +} .fi .SH AVAILABILITY Added in 7.86.0. diff --git a/docs/libcurl/curl_ws_send.3 b/docs/libcurl/curl_ws_send.3 index 9df2cc164..95873b787 100644 --- a/docs/libcurl/curl_ws_send.3 +++ b/docs/libcurl/curl_ws_send.3 @@ -27,7 +27,7 @@ curl_ws_send - send WebSocket data .SH SYNOPSIS .nf -#include +#include CURLcode curl_ws_send(CURL *curl, const void *buffer, size_t buflen, size_t *sent, curl_off_t fragsize, @@ -79,13 +79,22 @@ expected fragment size in the first call and it needs to be zero in subsequent calls. .SH EXAMPLE .nf -int ping(CURL *curl, const char *send_payload) +#include /* for strlen */ + +const char *send_payload = "magic"; + +int main(void) { size_t sent; - CURLcode result = - curl_ws_send(curl, send_payload, strlen(send_payload), &sent, 0, - CURLWS_PING); - return (int)result; + CURLcode res; + CURL *curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, "wss://example.com/"); + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L); + curl_easy_perform(curl); + res = curl_ws_send(curl, send_payload, strlen(send_payload), &sent, 0, + CURLWS_PING); + curl_easy_cleanup(curl); + return (int)res; } .fi .SH AVAILABILITY diff --git a/docs/libcurl/libcurl-errors.3 b/docs/libcurl/libcurl-errors.3 index f83bf6a2f..03f18e6b5 100644 --- a/docs/libcurl/libcurl-errors.3 +++ b/docs/libcurl/libcurl-errors.3 @@ -288,9 +288,6 @@ the specific problem. SSL Client Certificate required. .IP "CURLE_UNRECOVERABLE_POLL (99)" An internal call to poll() or select() returned error that is not recoverable. -.IP "CURLE_OBSOLETE*" -These error codes are never returned. They were used in an old libcurl version -and are currently unused. .SH "CURLMcode" This is the generic return code used by functions in the libcurl multi interface. Also consider \fIcurl_multi_strerror(3)\fP. @@ -300,9 +297,6 @@ This is not really an error. It means you should call between. Before version 7.20.0 (released on February 9 2010) this could be returned by \fIcurl_multi_perform(3)\fP, but in later versions this return code is never used. -.IP "CURLM_CALL_MULTI_SOCKET (-1)" -An alias for \fICURLM_CALL_MULTI_PERFORM\fP. Never returned by modern libcurl -versions. .IP "CURLM_OK (0)" Things are fine. .IP "CURLM_BAD_HANDLE (1)" @@ -414,9 +408,13 @@ The scheme part of the URL contained bad or invalid characters. The URL contained an invalid number of slashes. .IP "CURLUE_BAD_USER (29)" The user part of the URL contained bad or invalid characters. +.IP "CURLUE_LACKS_IDN (30)" +libcurl lacks IDN support. .SH "CURLHcode" The header interface returns a \fICURLHcode\fP to indicate when an error has occurred. +.IP "CURLHE_OK (0)" +All fine. Proceed as usual. .IP "CURLHE_BADINDEX (1)" There is no header with the requested index. .IP "CURLHE_MISSING (2)" diff --git a/docs/libcurl/libcurl-security.3 b/docs/libcurl/libcurl-security.3 index 0bc056c5f..0d7bce06b 100644 --- a/docs/libcurl/libcurl-security.3 +++ b/docs/libcurl/libcurl-security.3 @@ -68,7 +68,7 @@ plain text anywhere. Many of the protocols libcurl supports send name and password unencrypted as clear text (HTTP Basic authentication, FTP, TELNET etc). It is easy for anyone on your network or a network nearby yours to just fire up a network analyzer -tool and eavesdrop on your passwords. do not let the fact that HTTP Basic uses +tool and eavesdrop on your passwords. Do not let the fact that HTTP Basic uses base64 encoded passwords fool you. They may not look readable at a first glance, but they are easily "deciphered" by anyone within seconds. diff --git a/docs/libcurl/libcurl-thread.3 b/docs/libcurl/libcurl-thread.3 index 00e7d69d4..397eeae66 100644 --- a/docs/libcurl/libcurl-thread.3 +++ b/docs/libcurl/libcurl-thread.3 @@ -42,37 +42,10 @@ interface but you must provide your own locking and set Note that some items are specifically documented as not thread-safe in the share API (the connection pool and HSTS cache for example). .SH TLS -If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are -then of course using the underlying SSL library multi-threaded and those libs -might have their own requirements on this issue. You may need to provide one -or two functions to allow it to function properly: -.IP OpenSSL -OpenSSL 1.1.0+ "can be safely used in multi-threaded applications provided that -support for the underlying OS threading API is built-in." In that case the -engine is used by libcurl in a way that is fully thread-safe. - -https://www.openssl.org/docs/man1.1.0/man3/CRYPTO_THREAD_run_once.html#DESCRIPTION - -OpenSSL <= 1.0.2 the user must set callbacks. - -https://www.openssl.org/docs/man1.0.2/man3/CRYPTO_set_locking_callback.html#DESCRIPTION - -https://curl.se/libcurl/c/opensslthreadlock.html - -.IP GnuTLS -https://gnutls.org/manual/html_node/Thread-safety.html -.IP NSS -thread-safe already without anything required. -.IP Secure-Transport -The engine is used by libcurl in a way that is fully thread-safe. -.IP Schannel -The engine is used by libcurl in a way that is fully thread-safe. -.IP wolfSSL -The engine is used by libcurl in a way that is fully thread-safe. -.IP BoringSSL -The engine is used by libcurl in a way that is fully thread-safe. -.IP AWS-LC -The engine is used by libcurl in a way that is fully thread-safe. +All current TLS libraries libcurl supports are thread-safe. OpenSSL 1.1.0+ can +be safely used in multi-threaded applications provided that support for the +underlying OS threading API is built-in. For older versions of OpenSSL, the +user must set mutex callbacks. .SH "Signals" Signals are used for timing out name resolves (during DNS lookup) - when built without using either the c-ares or threaded resolver backends. On systems that diff --git a/docs/libcurl/libcurl.3 b/docs/libcurl/libcurl.3 index 1c1740663..dd4163a7e 100644 --- a/docs/libcurl/libcurl.3 +++ b/docs/libcurl/libcurl.3 @@ -71,7 +71,7 @@ get information about a performed transfer. See \fIcurl_easy_getinfo(3)\fP helps building an HTTP form POST. See \fIcurl_mime_addpart(3)\fP .IP curl_slist_append() builds a linked list. See \fIcurl_slist_append(3)\fP -.IP Sharing data between transfers +.IP "Sharing data between transfers" You can have multiple easy handles share certain data, even if they are used in different threads. This magic is setup using the share interface, as described in the \fIlibcurl-share(3)\fP man page. diff --git a/docs/libcurl/mksymbolsmanpage.pl b/docs/libcurl/mksymbolsmanpage.pl index a8cb10d82..3bc686949 100755 --- a/docs/libcurl/mksymbolsmanpage.pl +++ b/docs/libcurl/mksymbolsmanpage.pl @@ -26,8 +26,14 @@ my $version="7.41.0"; use POSIX qw(strftime); -my $date = strftime "%b %e, %Y", localtime; -my $year = strftime "%Y", localtime; +my @ts; +if (defined($ENV{SOURCE_DATE_EPOCH})) { + @ts = localtime($ENV{SOURCE_DATE_EPOCH}); +} else { + @ts = localtime; +} +my $date = strftime "%b %e, %Y", @ts; +my $year = strftime "%Y", @ts; print <
num_of_certs); + if(!res) { + printf("%d certs!\\n", ci->num_of_certs); - for(i = 0; i < ci->num_of_certs; i++) { - struct curl_slist *slist; + for(i = 0; i < ci->num_of_certs; i++) { + struct curl_slist *slist; - for(slist = ci->certinfo[i]; slist; slist = slist->next) - printf("%s\\n", slist->data); + for(slist = ci->certinfo[i]; slist; slist = slist->next) + printf("%s\\n", slist->data); + } } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi diff --git a/docs/libcurl/opts/CURLINFO_CONDITION_UNMET.3 b/docs/libcurl/opts/CURLINFO_CONDITION_UNMET.3 index 1d1627b3c..d59d16adb 100644 --- a/docs/libcurl/opts/CURLINFO_CONDITION_UNMET.3 +++ b/docs/libcurl/opts/CURLINFO_CONDITION_UNMET.3 @@ -44,26 +44,31 @@ custom "If-Match-*" header. HTTP and some .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; - /* January 1, 2020 is 1577833200 */ - curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* If-Modified-Since the above time stamp */ - curl_easy_setopt(curl, CURLOPT_TIMECONDITION, - (long)CURL_TIMECOND_IFMODSINCE); + /* January 1, 2020 is 1577833200 */ + curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); - /* Perform the request */ - res = curl_easy_perform(curl); + /* If-Modified-Since the above time stamp */ + curl_easy_setopt(curl, CURLOPT_TIMECONDITION, + (long)CURL_TIMECOND_IFMODSINCE); + + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - /* check the time condition */ - long unmet; - res = curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &unmet); if(!res) { - printf("The time condition was %sfulfilled\\n", unmet?"NOT":""); + /* check the time condition */ + long unmet; + res = curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &unmet); + if(!res) { + printf("The time condition was %sfulfilled\\n", unmet?"NOT":""); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_CONNECT_TIME.3 b/docs/libcurl/opts/CURLINFO_CONNECT_TIME.3 index cf0ce8a85..299e2d520 100644 --- a/docs/libcurl/opts/CURLINFO_CONNECT_TIME.3 +++ b/docs/libcurl/opts/CURLINFO_CONNECT_TIME.3 @@ -42,19 +42,23 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - double connect; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &connect); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + double connect; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %.1f", connect); + res = curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &connect); + if(CURLE_OK == res) { + printf("Time: %.1f", connect); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_CONNECT_TIME_T.3 b/docs/libcurl/opts/CURLINFO_CONNECT_TIME_T.3 index 8641de0ac..d215839c2 100644 --- a/docs/libcurl/opts/CURLINFO_CONNECT_TIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_CONNECT_TIME_T.3 @@ -43,20 +43,24 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_off_t connect; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME_T, &connect); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_off_t connect; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", connect / 1000000, - (long)(connect % 1000000)); + res = curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME_T, &connect); + if(CURLE_OK == res) { + printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", connect / 1000000, + (long)(connect % 1000000)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_CONN_ID.3 b/docs/libcurl/opts/CURLINFO_CONN_ID.3 index 3a63520e0..1b9da9338 100644 --- a/docs/libcurl/opts/CURLINFO_CONN_ID.3 +++ b/docs/libcurl/opts/CURLINFO_CONN_ID.3 @@ -44,18 +44,23 @@ same multi handle. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; - /* Perform the request */ - res = curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - curl_off_t conn_id; - res = curl_easy_getinfo(curl, CURLINFO_CONN_ID, &conn_id); if(!res) { - printf("Connection used: %" CURL_FORMAT_CURL_OFF_T "\\n", conn_id); + curl_off_t conn_id; + res = curl_easy_getinfo(curl, CURLINFO_CONN_ID, &conn_id); + if(!res) { + printf("Connection used: %" CURL_FORMAT_CURL_OFF_T "\\n", conn_id); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 index 474c21af0..fbb89b223 100644 --- a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 +++ b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 @@ -43,19 +43,23 @@ sensible variable type. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - /* check the size */ - double cl; - res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl); if(!res) { - printf("Size: %.0f\\n", cl); + /* check the size */ + double cl; + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl); + if(!res) { + printf("Size: %.0f\\n", cl); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 index cea6ad0f6..f924df26d 100644 --- a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 +++ b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 @@ -40,19 +40,23 @@ the size is not known. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - /* check the size */ - curl_off_t cl; - res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &cl); if(!res) { - printf("Download size: %" CURL_FORMAT_CURL_OFF_T "\\n", cl); + /* check the size */ + curl_off_t cl; + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &cl); + if(!res) { + printf("Download size: %" CURL_FORMAT_CURL_OFF_T "\\n", cl); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD.3 b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD.3 index b2da1af25..418e3c720 100644 --- a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD.3 +++ b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD.3 @@ -42,19 +42,23 @@ more sensible variable type. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the upload */ - res = curl_easy_perform(curl); + /* Perform the upload */ + res = curl_easy_perform(curl); - if(!res) { - /* check the size */ - double cl; - res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD, &cl); if(!res) { - printf("Size: %.0f\\n", cl); + /* check the size */ + double cl; + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD, &cl); + if(!res) { + printf("Size: %.0f\\n", cl); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 index 61a1fde5f..170c1080a 100644 --- a/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 +++ b/docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 @@ -39,19 +39,23 @@ upload. Stores -1 if the size is not known. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the upload */ - res = curl_easy_perform(curl); + /* Perform the upload */ + res = curl_easy_perform(curl); - if(!res) { - /* check the size */ - curl_off_t cl; - res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &cl); if(!res) { - printf("Upload size: %" CURL_FORMAT_CURL_OFF_T "\\n", cl); + /* check the size */ + curl_off_t cl; + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &cl); + if(!res) { + printf("Upload size: %" CURL_FORMAT_CURL_OFF_T "\\n", cl); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_CONTENT_TYPE.3 b/docs/libcurl/opts/CURLINFO_CONTENT_TYPE.3 index 56caea7df..1045821b5 100644 --- a/docs/libcurl/opts/CURLINFO_CONTENT_TYPE.3 +++ b/docs/libcurl/opts/CURLINFO_CONTENT_TYPE.3 @@ -47,21 +47,25 @@ The modern way to get this header from a response is to instead use the HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - if(!res) { - /* extract the content-type */ - char *ct = NULL; - res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); - if(!res && ct) { - printf("Content-Type: %s\\n", ct); + if(!res) { + /* extract the content-type */ + char *ct = NULL; + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); + if(!res && ct) { + printf("Content-Type: %s\\n", ct); + } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_COOKIELIST.3 b/docs/libcurl/opts/CURLINFO_COOKIELIST.3 index 29c8983ce..02e2490eb 100644 --- a/docs/libcurl/opts/CURLINFO_COOKIELIST.3 +++ b/docs/libcurl/opts/CURLINFO_COOKIELIST.3 @@ -45,31 +45,35 @@ domain name are not exported by this option. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* enable the cookie engine */ - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); + /* enable the cookie engine */ + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - if(!res) { - /* extract all known cookies */ - struct curl_slist *cookies = NULL; - 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; + if(!res) { + /* extract all known cookies */ + struct curl_slist *cookies = NULL; + 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; + } + /* we must free these cookies when we are done */ + curl_slist_free_all(cookies); } - /* we must free these cookies when we are done */ - curl_slist_free_all(cookies); } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_EFFECTIVE_METHOD.3 b/docs/libcurl/opts/CURLINFO_EFFECTIVE_METHOD.3 index 4129a63fa..50f028b57 100644 --- a/docs/libcurl/opts/CURLINFO_EFFECTIVE_METHOD.3 +++ b/docs/libcurl/opts/CURLINFO_EFFECTIVE_METHOD.3 @@ -46,20 +46,23 @@ corresponding CURL handle. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "data"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - char *method = NULL; - curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_METHOD, &method); - if(method) - printf("Redirected to method: %s\\n", method); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "data"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + char *method = NULL; + curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_METHOD, &method); + if(method) + printf("Redirected to method: %s\\n", method); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_EFFECTIVE_URL.3 b/docs/libcurl/opts/CURLINFO_EFFECTIVE_URL.3 index 987a179d4..810e7873e 100644 --- a/docs/libcurl/opts/CURLINFO_EFFECTIVE_URL.3 +++ b/docs/libcurl/opts/CURLINFO_EFFECTIVE_URL.3 @@ -44,19 +44,22 @@ CURL handle. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - char *url = NULL; - curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); - if(url) - printf("Redirect to: %s\\n", url); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + char *url = NULL; + curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); + if(url) + printf("Redirect to: %s\\n", url); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_FILETIME.3 b/docs/libcurl/opts/CURLINFO_FILETIME.3 index e8da80cf3..ae08db367 100644 --- a/docs/libcurl/opts/CURLINFO_FILETIME.3 +++ b/docs/libcurl/opts/CURLINFO_FILETIME.3 @@ -48,21 +48,26 @@ the year 2038 on systems using 32 bit longs (Windows). HTTP(S), FTP(S), SFTP .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, url); - /* Ask for filetime */ - curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); - if((CURLE_OK == res) && (filetime >= 0)) { - time_t file_time = (time_t)filetime; - printf("filetime %s: %s", filename, ctime(&file_time)); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + /* Ask for filetime */ + curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); + res = curl_easy_perform(curl); + if(CURLE_OK == res) { + long filetime = 0; + res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); + if((CURLE_OK == res) && (filetime >= 0)) { + time_t file_time = (time_t)filetime; + printf("filetime: %s", ctime(&file_time)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_FILETIME_T.3 b/docs/libcurl/opts/CURLINFO_FILETIME_T.3 index ffed16677..48ddc4163 100644 --- a/docs/libcurl/opts/CURLINFO_FILETIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_FILETIME_T.3 @@ -50,22 +50,26 @@ range. HTTP(S), FTP(S), SFTP .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, url); - /* Ask for filetime */ - curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - curl_off_t filetime; - res = curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime); - if((CURLE_OK == res) && (filetime >= 0)) { - time_t file_time = (time_t)filetime; - printf("filetime %s: %s", filename, ctime(&file_time)); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* Ask for filetime */ + curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); + res = curl_easy_perform(curl); + if(CURLE_OK == res) { + curl_off_t filetime; + res = curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime); + if((CURLE_OK == res) && (filetime >= 0)) { + time_t file_time = (time_t)filetime; + printf("filetime: %s", ctime(&file_time)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_FTP_ENTRY_PATH.3 b/docs/libcurl/opts/CURLINFO_FTP_ENTRY_PATH.3 index 8ca9a0571..8e0f1a23b 100644 --- a/docs/libcurl/opts/CURLINFO_FTP_ENTRY_PATH.3 +++ b/docs/libcurl/opts/CURLINFO_FTP_ENTRY_PATH.3 @@ -44,21 +44,25 @@ CURL handle. FTP(S) and SFTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com"); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - if(!res) { - /* extract the entry path */ - char *ep = NULL; - res = curl_easy_getinfo(curl, CURLINFO_FTP_ENTRY_PATH, &ep); - if(!res && ep) { - printf("Entry path was: %s\\n", ep); + if(!res) { + /* extract the entry path */ + char *ep = NULL; + res = curl_easy_getinfo(curl, CURLINFO_FTP_ENTRY_PATH, &ep); + if(!res && ep) { + printf("Entry path was: %s\\n", ep); + } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_HEADER_SIZE.3 b/docs/libcurl/opts/CURLINFO_HEADER_SIZE.3 index bce4b8a3c..2c9d8faed 100644 --- a/docs/libcurl/opts/CURLINFO_HEADER_SIZE.3 +++ b/docs/libcurl/opts/CURLINFO_HEADER_SIZE.3 @@ -41,18 +41,21 @@ The total includes the size of any received headers suppressed by All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long size; - res = curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &size); - if(!res) - printf("Header size: %ld bytes\\n", size); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long size; + res = curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &size); + if(!res) + printf("Header size: %ld bytes\\n", size); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_HTTPAUTH_AVAIL.3 b/docs/libcurl/opts/CURLINFO_HTTPAUTH_AVAIL.3 index 07c967547..7ceb790b4 100644 --- a/docs/libcurl/opts/CURLINFO_HTTPAUTH_AVAIL.3 +++ b/docs/libcurl/opts/CURLINFO_HTTPAUTH_AVAIL.3 @@ -40,29 +40,33 @@ bits is explained in the \fICURLOPT_HTTPAUTH(3)\fP option for HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - if(!res) { - /* extract the available authentication types */ - long auth; - res = curl_easy_getinfo(curl, CURLINFO_HTTPAUTH_AVAIL, &auth); if(!res) { - if(!auth) - printf("No auth available, perhaps no 401?\\n"); - else { - printf("%s%s%s%s\\n", - auth & CURLAUTH_BASIC ? "Basic ":"", - auth & CURLAUTH_DIGEST ? "Digest ":"", - auth & CURLAUTH_NEGOTIATE ? "Negotiate ":"", - auth % CURLAUTH_NTLM ? "NTLM ":""); + /* extract the available authentication types */ + long auth; + res = curl_easy_getinfo(curl, CURLINFO_HTTPAUTH_AVAIL, &auth); + if(!res) { + if(!auth) + printf("No auth available, perhaps no 401?\\n"); + else { + printf("%s%s%s%s\\n", + auth & CURLAUTH_BASIC ? "Basic ":"", + auth & CURLAUTH_DIGEST ? "Digest ":"", + auth & CURLAUTH_NEGOTIATE ? "Negotiate ":"", + auth % CURLAUTH_NTLM ? "NTLM ":""); + } } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_HTTP_CONNECTCODE.3 b/docs/libcurl/opts/CURLINFO_HTTP_CONNECTCODE.3 index 3262aa686..b4b3ac3fe 100644 --- a/docs/libcurl/opts/CURLINFO_HTTP_CONNECTCODE.3 +++ b/docs/libcurl/opts/CURLINFO_HTTP_CONNECTCODE.3 @@ -39,21 +39,24 @@ available. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* typically CONNECT is used to do HTTPS over HTTP proxies */ - curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long code; - res = curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE, &code); - if(!res && code) - printf("The CONNECT response code: %03ld\\n", code); + /* typically CONNECT is used to do HTTPS over HTTP proxies */ + curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long code; + res = curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE, &code); + if(!res && code) + printf("The CONNECT response code: %03ld\\n", code); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_HTTP_VERSION.3 b/docs/libcurl/opts/CURLINFO_HTTP_VERSION.3 index 8058c47b6..d4d4e8940 100644 --- a/docs/libcurl/opts/CURLINFO_HTTP_VERSION.3 +++ b/docs/libcurl/opts/CURLINFO_HTTP_VERSION.3 @@ -40,16 +40,19 @@ CURL_HTTP_VERSION_3 or 0 if the version cannot be determined. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long http_version; - curl_easy_getinfo(curl, CURLINFO_HTTP_VERSION, &http_version); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long http_version; + curl_easy_getinfo(curl, CURLINFO_HTTP_VERSION, &http_version); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_LASTSOCKET.3 b/docs/libcurl/opts/CURLINFO_LASTSOCKET.3 index efc137946..88a7345a9 100644 --- a/docs/libcurl/opts/CURLINFO_LASTSOCKET.3 +++ b/docs/libcurl/opts/CURLINFO_LASTSOCKET.3 @@ -48,21 +48,25 @@ type is 64 bits large while its 'long' is 32 bits. Use the All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - long sockfd; /* does not work on win64! */ - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + long sockfd; /* does not work on win64! */ + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Do not do the transfer - only connect to host */ - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); - res = curl_easy_perform(curl); + /* Do not do the transfer - only connect to host */ + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); + res = curl_easy_perform(curl); - /* Extract the socket from the curl handle */ - res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockfd); + /* Extract the socket from the curl handle */ + res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockfd); - if(res != CURLE_OK) { - printf("Error: %s\\n", curl_easy_strerror(res)); - return 1; + if(res != CURLE_OK) { + printf("Error: %s\\n", curl_easy_strerror(res)); + return 1; + } } } .fi diff --git a/docs/libcurl/opts/CURLINFO_LOCAL_IP.3 b/docs/libcurl/opts/CURLINFO_LOCAL_IP.3 index 151340301..5501ba7f9 100644 --- a/docs/libcurl/opts/CURLINFO_LOCAL_IP.3 +++ b/docs/libcurl/opts/CURLINFO_LOCAL_IP.3 @@ -45,8 +45,11 @@ CURL handle. All .SH EXAMPLE .nf +int main(void) { char *ip; + CURLcode res; + CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); diff --git a/docs/libcurl/opts/CURLINFO_LOCAL_PORT.3 b/docs/libcurl/opts/CURLINFO_LOCAL_PORT.3 index 9a5d16a0d..31617ac31 100644 --- a/docs/libcurl/opts/CURLINFO_LOCAL_PORT.3 +++ b/docs/libcurl/opts/CURLINFO_LOCAL_PORT.3 @@ -38,6 +38,7 @@ connection done with this \fBcurl\fP handle. All .SH EXAMPLE .nf +int main(void) { CURL *curl; CURLcode res; diff --git a/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME.3 b/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME.3 index 473342fac..4ad0e9522 100644 --- a/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME.3 +++ b/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME.3 @@ -43,19 +43,23 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - double namelookup; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME, &namelookup); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + double namelookup; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %.1f", namelookup); + res = curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME, &namelookup); + if(CURLE_OK == res) { + printf("Time: %.1f", namelookup); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME_T.3 b/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME_T.3 index 0cedd39fc..91be68a29 100644 --- a/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_NAMELOOKUP_TIME_T.3 @@ -43,20 +43,24 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_off_t namelookup; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME_T, &namelookup); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_off_t namelookup; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", namelookup / 1000000, - (long)(namelookup % 1000000)); + res = curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME_T, &namelookup); + if(CURLE_OK == res) { + printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", namelookup / 1000000, + (long)(namelookup % 1000000)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_NUM_CONNECTS.3 b/docs/libcurl/opts/CURLINFO_NUM_CONNECTS.3 index aec2d709c..b151f1e26 100644 --- a/docs/libcurl/opts/CURLINFO_NUM_CONNECTS.3 +++ b/docs/libcurl/opts/CURLINFO_NUM_CONNECTS.3 @@ -42,19 +42,22 @@ to make persistent connections to save time. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long connects; - res = curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &connects); - if(res) - printf("It needed %d connects\\n", connects); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long connects; + res = curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &connects); + if(res) + printf("It needed %ld connects\\n", connects); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_OS_ERRNO.3 b/docs/libcurl/opts/CURLINFO_OS_ERRNO.3 index 96b3b9dfa..cafeb68a1 100644 --- a/docs/libcurl/opts/CURLINFO_OS_ERRNO.3 +++ b/docs/libcurl/opts/CURLINFO_OS_ERRNO.3 @@ -39,19 +39,22 @@ operation. The number is OS and system specific. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res != CURLE_OK) { - long error; - res = curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &error); - if(res && error) { - printf("Errno: %ld\\n", error); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res != CURLE_OK) { + long error; + res = curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &error); + if(res && error) { + printf("Errno: %ld\\n", error); + } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME.3 b/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME.3 index 05cab3be3..01f90f214 100644 --- a/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME.3 +++ b/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME.3 @@ -38,7 +38,7 @@ start until the file transfer is just about to begin. This time-stamp includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved. It includes the sending of -the protocol- specific protocol instructions that triggers a transfer. +the protocol-specific instructions that trigger a transfer. When a redirect is followed, the time from each request is added together. @@ -47,19 +47,23 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - double pretransfer; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &pretransfer); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + double pretransfer; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %.1f", pretransfer); + res = curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &pretransfer); + if(CURLE_OK == res) { + printf("Time: %.1f", pretransfer); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME_T.3 b/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME_T.3 index eb1434a54..f05543446 100644 --- a/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_PRETRANSFER_TIME_T.3 @@ -33,12 +33,12 @@ CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_PRETRANSFER_TIME_T, curl_off_t *timep); .fi .SH DESCRIPTION -Pass a pointer to a curl_off_t to receive the time, in microseconds, -it took from the -start until the file transfer is just about to begin. This includes all -pre-transfer commands and negotiations that are specific to the particular -protocol(s) involved. It does \fInot\fP involve the sending of the protocol- -specific request that triggers a transfer. +Pass a pointer to a curl_off_t to receive the time, in microseconds, it took +from the start until the file transfer is just about to begin. + +This time-stamp includes all pre-transfer commands and negotiations that are +specific to the particular protocol(s) involved. It includes the sending of +the protocol-specific instructions that trigger a transfer. When a redirect is followed, the time from each request is added together. @@ -47,20 +47,25 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_off_t pretransfer; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME_T, &pretransfer); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_off_t pretransfer; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", pretransfer / 1000000, - (long)(pretransfer % 1000000)); + res = curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME_T, &pretransfer); + if(CURLE_OK == res) { + printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld\\n", + pretransfer / 1000000, + (long)(pretransfer % 1000000)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PRIMARY_IP.3 b/docs/libcurl/opts/CURLINFO_PRIMARY_IP.3 index 6431e36eb..597a797ec 100644 --- a/docs/libcurl/opts/CURLINFO_PRIMARY_IP.3 +++ b/docs/libcurl/opts/CURLINFO_PRIMARY_IP.3 @@ -45,8 +45,11 @@ CURL handle. All network based ones .SH EXAMPLE .nf +int main(void) { char *ip; + CURLcode res; + CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); diff --git a/docs/libcurl/opts/CURLINFO_PRIMARY_PORT.3 b/docs/libcurl/opts/CURLINFO_PRIMARY_PORT.3 index 857999595..51d2b746f 100644 --- a/docs/libcurl/opts/CURLINFO_PRIMARY_PORT.3 +++ b/docs/libcurl/opts/CURLINFO_PRIMARY_PORT.3 @@ -43,18 +43,21 @@ accessed URL. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long port; - res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT, &port); - if(!res) - printf("Connected to remote port: %ld\\n", port); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long port; + res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT, &port); + if(!res) + printf("Connected to remote port: %ld\\n", port); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PRIVATE.3 b/docs/libcurl/opts/CURLINFO_PRIVATE.3 index 58459752f..2c63e3e48 100644 --- a/docs/libcurl/opts/CURLINFO_PRIVATE.3 +++ b/docs/libcurl/opts/CURLINFO_PRIVATE.3 @@ -40,19 +40,26 @@ pointer, although effectively being a 'void *'. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - void *pointer = 0x2345454; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + void *pointer = (void *)0x2345454; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* set the private pointer */ - curl_easy_setopt(curl, CURLOPT_PRIVATE, pointer); - ret = curl_easy_perform(curl); + /* set the private pointer */ + curl_easy_setopt(curl, CURLOPT_PRIVATE, pointer); + res = curl_easy_perform(curl); - /* extract the private pointer again */ - ret = curl_easy_getinfo(curl, CURLINFO_PRIVATE, &pointer); + /* extract the private pointer again */ + res = curl_easy_getinfo(curl, CURLINFO_PRIVATE, &pointer); - curl_easy_cleanup(curl); + if(res) + printf("error: %s\\n", curl_easy_strerror(res)); + + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PROTOCOL.3 b/docs/libcurl/opts/CURLINFO_PROTOCOL.3 index 94b2dacf8..aac7e9f3f 100644 --- a/docs/libcurl/opts/CURLINFO_PROTOCOL.3 +++ b/docs/libcurl/opts/CURLINFO_PROTOCOL.3 @@ -51,16 +51,19 @@ CURLPROTO_SMTPS, CURLPROTO_TELNET, CURLPROTO_TFTP, CURLPROTO_MQTT All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long protocol; - curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long protocol; + curl_easy_getinfo(curl, CURLINFO_PROTOCOL, &protocol); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PROXYAUTH_AVAIL.3 b/docs/libcurl/opts/CURLINFO_PROXYAUTH_AVAIL.3 index 4d0789bf6..3d6e54948 100644 --- a/docs/libcurl/opts/CURLINFO_PROXYAUTH_AVAIL.3 +++ b/docs/libcurl/opts/CURLINFO_PROXYAUTH_AVAIL.3 @@ -41,30 +41,34 @@ bits is explained in the \fICURLOPT_PROXYAUTH(3)\fP option for HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1:80"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1:80"); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - if(!res) { - /* extract the available proxy authentication types */ - long auth; - res = curl_easy_getinfo(curl, CURLINFO_PROXYAUTH_AVAIL, &auth); if(!res) { - if(!auth) - printf("No proxy auth available, perhaps no 407?\\n"); - else { - printf("%s%s%s%s\\n", - auth & CURLAUTH_BASIC ? "Basic ":"", - auth & CURLAUTH_DIGEST ? "Digest ":"", - auth & CURLAUTH_NEGOTIATE ? "Negotiate ":"", - auth % CURLAUTH_NTLM ? "NTLM ":""); + /* extract the available proxy authentication types */ + long auth; + res = curl_easy_getinfo(curl, CURLINFO_PROXYAUTH_AVAIL, &auth); + if(!res) { + if(!auth) + printf("No proxy auth available, perhaps no 407?\\n"); + else { + printf("%s%s%s%s\\n", + auth & CURLAUTH_BASIC ? "Basic ":"", + auth & CURLAUTH_DIGEST ? "Digest ":"", + auth & CURLAUTH_NEGOTIATE ? "Negotiate ":"", + auth % CURLAUTH_NTLM ? "NTLM ":""); + } } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3 b/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3 index 17f6fcf7e..f4ce84918 100644 --- a/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3 +++ b/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3 @@ -79,20 +79,23 @@ The error code is zero (\fBCURLPX_OK\fP) if no response code was available. All that can be done over SOCKS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://127.0.0.1"); - res = curl_easy_perform(curl); - if(res == CURLE_PROXY) { - long proxycode; - res = curl_easy_getinfo(curl, CURLINFO_PROXY_ERROR, &proxycode); - if(!res && proxycode) - printf("The detailed proxy error: %ld\\n", proxycode); + curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://127.0.0.1"); + res = curl_easy_perform(curl); + if(res == CURLE_PROXY) { + long proxycode; + res = curl_easy_getinfo(curl, CURLINFO_PROXY_ERROR, &proxycode); + if(!res && proxycode) + printf("The detailed proxy error: %ld\\n", proxycode); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 b/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 index 3b266f75b..c2a311a2a 100644 --- a/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 +++ b/docs/libcurl/opts/CURLINFO_PROXY_SSL_VERIFYRESULT.3 @@ -40,17 +40,22 @@ option. This is only used for HTTPS proxies. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - long verifyresult; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); - res = curl_easy_perform(curl); - curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT, &verifyresult); - printf("The peer verification said %s\\n", verifyresult? - "fine":"BAAAD"); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + long verifyresult; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); + res = curl_easy_perform(curl); + if(res) + printf("error: %s\\n", curl_easy_strerror(res)); + curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT, &verifyresult); + printf("The peer verification said %s\\n", verifyresult? + "fine" : "bad"); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_REDIRECT_COUNT.3 b/docs/libcurl/opts/CURLINFO_REDIRECT_COUNT.3 index 034c00e2f..a0017d706 100644 --- a/docs/libcurl/opts/CURLINFO_REDIRECT_COUNT.3 +++ b/docs/libcurl/opts/CURLINFO_REDIRECT_COUNT.3 @@ -39,17 +39,20 @@ actually followed. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long redirects; - curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redirects); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long redirects; + curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redirects); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_REDIRECT_TIME.3 b/docs/libcurl/opts/CURLINFO_REDIRECT_TIME.3 index 7d3870acd..ece2055c0 100644 --- a/docs/libcurl/opts/CURLINFO_REDIRECT_TIME.3 +++ b/docs/libcurl/opts/CURLINFO_REDIRECT_TIME.3 @@ -43,19 +43,23 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - double redirect; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME, &redirect); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + double redirect; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %.1f", redirect); + res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME, &redirect); + if(CURLE_OK == res) { + printf("Time: %.1f", redirect); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_REDIRECT_TIME_T.3 b/docs/libcurl/opts/CURLINFO_REDIRECT_TIME_T.3 index 444bbae77..cbda42035 100644 --- a/docs/libcurl/opts/CURLINFO_REDIRECT_TIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_REDIRECT_TIME_T.3 @@ -44,20 +44,24 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_off_t redirect; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME_T, &redirect); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_off_t redirect; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", redirect / 1000000, - (long)(redirect % 1000000)); + res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME_T, &redirect); + if(CURLE_OK == res) { + printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", redirect / 1000000, + (long)(redirect % 1000000)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_REDIRECT_URL.3 b/docs/libcurl/opts/CURLINFO_REDIRECT_URL.3 index aa39803eb..61422f6db 100644 --- a/docs/libcurl/opts/CURLINFO_REDIRECT_URL.3 +++ b/docs/libcurl/opts/CURLINFO_REDIRECT_URL.3 @@ -44,18 +44,21 @@ redirect to happen (since 7.54.1). HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - char *url = NULL; - curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &url); - if(url) - printf("Redirect to: %s\\n", url); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + char *url = NULL; + curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &url); + if(url) + printf("Redirect to: %s\\n", url); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_REFERER.3 b/docs/libcurl/opts/CURLINFO_REFERER.3 index fe4afd0b7..550ccf9ae 100644 --- a/docs/libcurl/opts/CURLINFO_REFERER.3 +++ b/docs/libcurl/opts/CURLINFO_REFERER.3 @@ -41,19 +41,22 @@ CURL handle. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.org/referrer"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - char *hdr = NULL; - curl_easy_getinfo(curl, CURLINFO_REFERER, &hdr); - if(hdr) - printf("Referrer header: %s\\n", hdr); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.org/referrer"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + char *hdr = NULL; + curl_easy_getinfo(curl, CURLINFO_REFERER, &hdr); + if(hdr) + printf("Referrer header: %s\\n", hdr); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_REQUEST_SIZE.3 b/docs/libcurl/opts/CURLINFO_REQUEST_SIZE.3 index fca67a9b8..9f7029107 100644 --- a/docs/libcurl/opts/CURLINFO_REQUEST_SIZE.3 +++ b/docs/libcurl/opts/CURLINFO_REQUEST_SIZE.3 @@ -39,18 +39,21 @@ than one request if \fICURLOPT_FOLLOWLOCATION(3)\fP is enabled. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long req; - res = curl_easy_getinfo(curl, CURLINFO_REQUEST_SIZE, &req); - if(!res) - printf("Request size: %ld bytes\\n", req); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long req; + res = curl_easy_getinfo(curl, CURLINFO_REQUEST_SIZE, &req); + if(!res) + printf("Request size: %ld bytes\\n", req); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_RESPONSE_CODE.3 b/docs/libcurl/opts/CURLINFO_RESPONSE_CODE.3 index 9cda1030f..c006a1580 100644 --- a/docs/libcurl/opts/CURLINFO_RESPONSE_CODE.3 +++ b/docs/libcurl/opts/CURLINFO_RESPONSE_CODE.3 @@ -43,16 +43,19 @@ Note that a proxy's CONNECT response should be read with HTTP, FTP, SMTP and LDAP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long response_code; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long response_code; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_RETRY_AFTER.3 b/docs/libcurl/opts/CURLINFO_RETRY_AFTER.3 index 2c761d731..5a7450ccb 100644 --- a/docs/libcurl/opts/CURLINFO_RETRY_AFTER.3 +++ b/docs/libcurl/opts/CURLINFO_RETRY_AFTER.3 @@ -46,18 +46,21 @@ Returns zero delay if there was no header. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - curl_off_t wait = 0; - curl_easy_getinfo(curl, CURLINFO_RETRY_AFTER, &wait); - if(wait) - printf("Wait for %" CURL_FORMAT_CURL_OFF_T " seconds\\n", wait); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + curl_off_t wait = 0; + curl_easy_getinfo(curl, CURLINFO_RETRY_AFTER, &wait); + if(wait) + printf("Wait for %" CURL_FORMAT_CURL_OFF_T " seconds\\n", wait); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_RTSP_CLIENT_CSEQ.3 b/docs/libcurl/opts/CURLINFO_RTSP_CLIENT_CSEQ.3 index caad1935e..bd8ec271e 100644 --- a/docs/libcurl/opts/CURLINFO_RTSP_CLIENT_CSEQ.3 +++ b/docs/libcurl/opts/CURLINFO_RTSP_CLIENT_CSEQ.3 @@ -39,16 +39,19 @@ by the application. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long cseq; - curl_easy_getinfo(curl, CURLINFO_RTSP_CLIENT_CSEQ, &cseq); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long cseq; + curl_easy_getinfo(curl, CURLINFO_RTSP_CLIENT_CSEQ, &cseq); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_RTSP_CSEQ_RECV.3 b/docs/libcurl/opts/CURLINFO_RTSP_CSEQ_RECV.3 index 5331de260..dc840a847 100644 --- a/docs/libcurl/opts/CURLINFO_RTSP_CSEQ_RECV.3 +++ b/docs/libcurl/opts/CURLINFO_RTSP_CSEQ_RECV.3 @@ -40,16 +40,19 @@ value. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long cseq; - curl_easy_getinfo(curl, CURLINFO_RTSP_CSEQ_RECV, &cseq); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long cseq; + curl_easy_getinfo(curl, CURLINFO_RTSP_CSEQ_RECV, &cseq); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_RTSP_SERVER_CSEQ.3 b/docs/libcurl/opts/CURLINFO_RTSP_SERVER_CSEQ.3 index 478b25836..8cf052261 100644 --- a/docs/libcurl/opts/CURLINFO_RTSP_SERVER_CSEQ.3 +++ b/docs/libcurl/opts/CURLINFO_RTSP_SERVER_CSEQ.3 @@ -44,16 +44,19 @@ retrieve this info before closing the active connection. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - long cseq; - curl_easy_getinfo(curl, CURLINFO_RTSP_SERVER_CSEQ, &cseq); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + long cseq; + curl_easy_getinfo(curl, CURLINFO_RTSP_SERVER_CSEQ, &cseq); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_RTSP_SESSION_ID.3 b/docs/libcurl/opts/CURLINFO_RTSP_SESSION_ID.3 index 375879273..fe1e3fd0d 100644 --- a/docs/libcurl/opts/CURLINFO_RTSP_SESSION_ID.3 +++ b/docs/libcurl/opts/CURLINFO_RTSP_SESSION_ID.3 @@ -45,16 +45,19 @@ CURL handle. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - char *id; - curl_easy_getinfo(curl, CURLINFO_RTSP_SESSION_ID, &id); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://rtsp.example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + char *id; + curl_easy_getinfo(curl, CURLINFO_RTSP_SESSION_ID, &id); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_SCHEME.3 b/docs/libcurl/opts/CURLINFO_SCHEME.3 index a736dd81c..018866a68 100644 --- a/docs/libcurl/opts/CURLINFO_SCHEME.3 +++ b/docs/libcurl/opts/CURLINFO_SCHEME.3 @@ -43,18 +43,21 @@ corresponding CURL handle. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - if(res == CURLE_OK) { - char *scheme = NULL; - curl_easy_getinfo(curl, CURLINFO_SCHEME, &scheme); - if(scheme) - printf("scheme: %s\\n", scheme); /* scheme: HTTP */ +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res == CURLE_OK) { + char *scheme = NULL; + curl_easy_getinfo(curl, CURLINFO_SCHEME, &scheme); + if(scheme) + printf("scheme: %s\\n", scheme); /* scheme: HTTP */ + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD.3 b/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD.3 index c3a2f2641..7ac1f9231 100644 --- a/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD.3 +++ b/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD.3 @@ -44,19 +44,23 @@ sensible variable type. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - /* check the size */ - double dl; - res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &dl); if(!res) { - printf("Downloaded %.0f bytes\\n", cl); + /* check the size */ + double dl; + res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &dl); + if(!res) { + printf("Downloaded %.0f bytes\\n", dl); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD_T.3 b/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD_T.3 index c3bb7f195..5e424f235 100644 --- a/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD_T.3 +++ b/docs/libcurl/opts/CURLINFO_SIZE_DOWNLOAD_T.3 @@ -41,19 +41,23 @@ commonly called body. All meta and header data is excluded from this amount. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - /* check the size */ - curl_off_t dl; - res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD_T, &dl); if(!res) { - printf("Downloaded %" CURL_FORMAT_CURL_OFF_T " bytes\\n", dl); + /* check the size */ + curl_off_t dl; + res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD_T, &dl); + if(!res) { + printf("Downloaded %" CURL_FORMAT_CURL_OFF_T " bytes\\n", dl); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.3 b/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.3 index 89228b011..ba01b3119 100644 --- a/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.3 +++ b/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.3 @@ -42,18 +42,22 @@ sensible variable type. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - double ul; - res = curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &ul); if(!res) { - printf("Uploaded %.0f bytes\\n", ul); + double ul; + res = curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &ul); + if(!res) { + printf("Uploaded %.0f bytes\\n", ul); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.3 b/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.3 index ea77bd7cc..24230c046 100644 --- a/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.3 +++ b/docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.3 @@ -39,18 +39,22 @@ were uploaded. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - curl_off_t ul; - res = curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &ul); if(!res) { - printf("Uploaded %" CURL_FORMAT_CURL_OFF_T " bytes\\n", ul); + curl_off_t ul; + res = curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &ul); + if(!res) { + printf("Uploaded %" CURL_FORMAT_CURL_OFF_T " bytes\\n", ul); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD.3 b/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD.3 index c79e48a71..7c277d51d 100644 --- a/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD.3 +++ b/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD.3 @@ -41,18 +41,22 @@ sensible variable type. .SH PROTOCOLS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - double speed; - res = curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, &speed); if(!res) { - printf("Download speed %.0f bytes/sec\\n", speed); + double speed; + res = curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, &speed); + if(!res) { + printf("Download speed %.0f bytes/sec\\n", speed); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD_T.3 b/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD_T.3 index 9d308c6bf..b17d28281 100644 --- a/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD_T.3 +++ b/docs/libcurl/opts/CURLINFO_SPEED_DOWNLOAD_T.3 @@ -38,18 +38,23 @@ that curl measured for the complete download. Measured in bytes/second. .SH PROTOCOLS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - curl_off_t speed; - res = curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD_T, &speed); if(!res) { - printf("Download speed %" CURL_FORMAT_CURL_OFF_T " bytes/sec\\n", speed); + curl_off_t speed; + res = curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD_T, &speed); + if(!res) { + printf("Download speed %" CURL_FORMAT_CURL_OFF_T " bytes/sec\\n", + speed); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD.3 b/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD.3 index 814a4fa8e..c42f3b517 100644 --- a/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD.3 +++ b/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD.3 @@ -40,18 +40,22 @@ sensible variable type. .SH PROTOCOLS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - double speed; - res = curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed); if(!res) { - printf("Upload speed %.0f bytes/sec\\n", speed); + double speed; + res = curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed); + if(!res) { + printf("Upload speed %.0f bytes/sec\\n", speed); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD_T.3 b/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD_T.3 index eff8554c0..f2bf1d735 100644 --- a/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD_T.3 +++ b/docs/libcurl/opts/CURLINFO_SPEED_UPLOAD_T.3 @@ -38,18 +38,22 @@ curl measured for the complete upload. Measured in bytes/second. .SH PROTOCOLS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - curl_off_t speed; - res = curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD_T, &speed); if(!res) { - printf("Upload speed %" CURL_FORMAT_CURL_OFF_T " bytes/sec\\n", speed); + curl_off_t speed; + res = curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD_T, &speed); + if(!res) { + printf("Upload speed %" CURL_FORMAT_CURL_OFF_T " bytes/sec\\n", speed); + } } } } diff --git a/docs/libcurl/opts/CURLINFO_SSL_ENGINES.3 b/docs/libcurl/opts/CURLINFO_SSL_ENGINES.3 index 0375e79a4..03db5bbb4 100644 --- a/docs/libcurl/opts/CURLINFO_SSL_ENGINES.3 +++ b/docs/libcurl/opts/CURLINFO_SSL_ENGINES.3 @@ -43,17 +43,20 @@ data for you. All TLS based ones. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - struct curl_slist *engines; - res = curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines); - if((res == CURLE_OK) && engines) { - /* we have a list, free it when done using it */ - curl_slist_free_all(engines); - } +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_slist *engines; + res = curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines); + if((res == CURLE_OK) && engines) { + /* we have a list, free it when done using it */ + curl_slist_free_all(engines); + } - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3 b/docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3 index d66d7df60..cf881ec81 100644 --- a/docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3 +++ b/docs/libcurl/opts/CURLINFO_SSL_VERIFYRESULT.3 @@ -42,16 +42,21 @@ option). All using TLS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - long verifyresult; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT, &verifyresult); - printf("The peer verification said %s\\n", verifyresult? - "BAAAD":"fine"); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + long verifyresult; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res) + printf("error: %s\\n", curl_easy_strerror(res)); + curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT, &verifyresult); + printf("The peer verification said %s\\n", verifyresult? + "BAAAD":"fine"); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME.3 b/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME.3 index 0c1793232..c9879d2e5 100644 --- a/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME.3 +++ b/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME.3 @@ -45,19 +45,23 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - double start; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, &start); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + double start; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %.1f", start); + res = curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, &start); + if(CURLE_OK == res) { + printf("Time: %.1f", start); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME_T.3 b/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME_T.3 index 3ad2d525f..7638f115e 100644 --- a/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_STARTTRANSFER_TIME_T.3 @@ -46,20 +46,24 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_off_t start; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME_T, &start); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_off_t start; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", start / 1000000, - (long)(start % 1000000)); + res = curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME_T, &start); + if(CURLE_OK == res) { + printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", start / 1000000, + (long)(start % 1000000)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_TLS_SESSION.3 b/docs/libcurl/opts/CURLINFO_TLS_SESSION.3 index 88166b099..60d648552 100644 --- a/docs/libcurl/opts/CURLINFO_TLS_SESSION.3 +++ b/docs/libcurl/opts/CURLINFO_TLS_SESSION.3 @@ -52,14 +52,19 @@ that document for more information. All TLS-based .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode res; - struct curl_tlssessioninfo *tls; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - res = curl_easy_perform(curl); - curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, &tls); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_tlssessioninfo *tls; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); + if(res) + printf("error: %s\\n", curl_easy_strerror(res)); + curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, &tls); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 b/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 index 53d084d48..8c5f2525e 100644 --- a/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 +++ b/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 @@ -133,13 +133,13 @@ static size_t wf(void *ptr, size_t size, size_t nmemb, void *stream) CURLcode res = curl_easy_getinfo(curl, CURLINFO_TLS_SSL_PTR, &info); if(info && !res) { if(CURLSSLBACKEND_OPENSSL == info->backend) { - printf("OpenSSL ver. %s\\n", SSL_get_version((SSL*)info->internals)); + printf("OpenSSL ver. %s\\n", SSL_get_version((SSL*)info->internals)); } } return size * nmemb; } -int main(int argc, char** argv) +int main(int argc, char **argv) { CURLcode res; curl = curl_easy_init(); diff --git a/docs/libcurl/opts/CURLINFO_TOTAL_TIME.3 b/docs/libcurl/opts/CURLINFO_TOTAL_TIME.3 index 12a8efa3a..c5519fcb0 100644 --- a/docs/libcurl/opts/CURLINFO_TOTAL_TIME.3 +++ b/docs/libcurl/opts/CURLINFO_TOTAL_TIME.3 @@ -43,19 +43,23 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - double total; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + double total; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %.1f", total); + res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total); + if(CURLE_OK == res) { + printf("Time: %.1f", total); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_TOTAL_TIME_T.3 b/docs/libcurl/opts/CURLINFO_TOTAL_TIME_T.3 index d2bc9e886..54a0d547c 100644 --- a/docs/libcurl/opts/CURLINFO_TOTAL_TIME_T.3 +++ b/docs/libcurl/opts/CURLINFO_TOTAL_TIME_T.3 @@ -44,20 +44,24 @@ See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_off_t total; - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &total); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_off_t total; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + res = curl_easy_perform(curl); if(CURLE_OK == res) { - printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", total / 1000000, - (long)(total % 1000000)); + res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &total); + if(CURLE_OK == res) { + printf("Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld", total / 1000000, + (long)(total % 1000000)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLINFO_XFER_ID.3 b/docs/libcurl/opts/CURLINFO_XFER_ID.3 index c10e5d55e..b166b20bf 100644 --- a/docs/libcurl/opts/CURLINFO_XFER_ID.3 +++ b/docs/libcurl/opts/CURLINFO_XFER_ID.3 @@ -45,18 +45,22 @@ same multi handle. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Perform the request */ - res = curl_easy_perform(curl); + /* Perform the request */ + res = curl_easy_perform(curl); - if(!res) { - curl_off_t xfer_id; - res = curl_easy_getinfo(curl, CURLINFO_XFER_ID, &xfer_id); if(!res) { - printf("Transfer ID: %" CURL_FORMAT_CURL_OFF_T "\\n", xfer_id); + curl_off_t xfer_id; + res = curl_easy_getinfo(curl, CURLINFO_XFER_ID, &xfer_id); + if(!res) { + printf("Transfer ID: %" CURL_FORMAT_CURL_OFF_T "\\n", xfer_id); + } } } } diff --git a/docs/libcurl/opts/CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 b/docs/libcurl/opts/CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 index 589b624bf..932e33397 100644 --- a/docs/libcurl/opts/CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 +++ b/docs/libcurl/opts/CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 @@ -46,9 +46,12 @@ The default value is 0, which means that the penalization is inactive. HTTP(S) .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -long maxchunk = 10000; -curl_multi_setopt(m, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, maxchunk); +int main(void) +{ + CURLM *m = curl_multi_init(); + long maxchunk = 10000; + curl_multi_setopt(m, CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, maxchunk); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 b/docs/libcurl/opts/CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 index 5a66d058e..30bbe99ec 100644 --- a/docs/libcurl/opts/CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 +++ b/docs/libcurl/opts/CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 @@ -46,9 +46,12 @@ The default value is 0, which means that the size penalization is inactive. HTTP(S) .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -long maxlength = 10000; -curl_multi_setopt(m, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, maxlength); +int main(void) +{ + CURLM *m = curl_multi_init(); + long maxlength = 10000; + curl_multi_setopt(m, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, maxlength); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_MAXCONNECTS.3 b/docs/libcurl/opts/CURLMOPT_MAXCONNECTS.3 index 97468201e..e0d75f2d5 100644 --- a/docs/libcurl/opts/CURLMOPT_MAXCONNECTS.3 +++ b/docs/libcurl/opts/CURLMOPT_MAXCONNECTS.3 @@ -56,9 +56,12 @@ See DESCRIPTION All .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -/* only keep 10 connections in the cache */ -curl_multi_setopt(m, CURLMOPT_MAXCONNECTS, 10L); +int main(void) +{ + CURLM *m = curl_multi_init(); + /* only keep 10 connections in the cache */ + curl_multi_setopt(m, CURLMOPT_MAXCONNECTS, 10L); +} .fi .SH AVAILABILITY Added in 7.16.3 diff --git a/docs/libcurl/opts/CURLMOPT_MAX_CONCURRENT_STREAMS.3 b/docs/libcurl/opts/CURLMOPT_MAX_CONCURRENT_STREAMS.3 index 64dc2b563..7b5741e58 100644 --- a/docs/libcurl/opts/CURLMOPT_MAX_CONCURRENT_STREAMS.3 +++ b/docs/libcurl/opts/CURLMOPT_MAX_CONCURRENT_STREAMS.3 @@ -34,8 +34,8 @@ CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_MAX_CONCURRENT_STREAMS, .fi .SH DESCRIPTION Pass a long indicating the \fBmax\fP. The set number is used as the maximum -number of concurrent streams for a connections that libcurl should support on -connections done using HTTP/2. +number of concurrent streams libcurl should support on connections done using +HTTP/2 or HTTP/3. Valid values range from 1 to 2147483647 (2^31 - 1) and defaults to 100. The value passed here would be honored based on other system resources properties. @@ -45,9 +45,12 @@ value passed here would be honored based on other system resources properties. All .SH EXAMPLE .nf +int main(void) +{ CURLM *m = curl_multi_init(); /* max concurrent streams 200 */ curl_multi_setopt(m, CURLMOPT_MAX_CONCURRENT_STREAMS, 200L); +} .fi .SH AVAILABILITY Added in 7.67.0 diff --git a/docs/libcurl/opts/CURLMOPT_MAX_HOST_CONNECTIONS.3 b/docs/libcurl/opts/CURLMOPT_MAX_HOST_CONNECTIONS.3 index a9bf0ad78..fb0f6787c 100644 --- a/docs/libcurl/opts/CURLMOPT_MAX_HOST_CONNECTIONS.3 +++ b/docs/libcurl/opts/CURLMOPT_MAX_HOST_CONNECTIONS.3 @@ -58,9 +58,12 @@ timeout is however treated as a per-connect timeout. HTTP(S) .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -/* do no more than 2 connections per host */ -curl_multi_setopt(m, CURLMOPT_MAX_HOST_CONNECTIONS, 2L); +int main(void) +{ + CURLM *m = curl_multi_init(); + /* do no more than 2 connections per host */ + curl_multi_setopt(m, CURLMOPT_MAX_HOST_CONNECTIONS, 2L); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 b/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 index 1785eb427..9f2c6ffbe 100644 --- a/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 +++ b/docs/libcurl/opts/CURLMOPT_MAX_PIPELINE_LENGTH.3 @@ -50,9 +50,12 @@ total number of requests in-flight is \fICURLMOPT_MAX_HOST_CONNECTIONS(3)\fP * HTTP(S) .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -/* set a more conservative pipe length */ -curl_multi_setopt(m, CURLMOPT_MAX_PIPELINE_LENGTH, 3L); +int main(void) +{ + CURLM *m = curl_multi_init(); + /* set a more conservative pipe length */ + curl_multi_setopt(m, CURLMOPT_MAX_PIPELINE_LENGTH, 3L); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 b/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 index 0b7094414..130822f56 100644 --- a/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 +++ b/docs/libcurl/opts/CURLMOPT_MAX_TOTAL_CONNECTIONS.3 @@ -56,9 +56,12 @@ controlled by the number of easy handles added. All .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -/* never do more than 15 connections */ -curl_multi_setopt(m, CURLMOPT_MAX_TOTAL_CONNECTIONS, 15L); +int main(void) +{ + CURLM *m = curl_multi_init(); + /* never do more than 15 connections */ + curl_multi_setopt(m, CURLMOPT_MAX_TOTAL_CONNECTIONS, 15L); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_PIPELINING.3 b/docs/libcurl/opts/CURLMOPT_PIPELINING.3 index de7ccc967..88777320f 100644 --- a/docs/libcurl/opts/CURLMOPT_PIPELINING.3 +++ b/docs/libcurl/opts/CURLMOPT_PIPELINING.3 @@ -53,9 +53,12 @@ Before that, default was \fBCURLPIPE_NOTHING\fP. HTTP(S) .SH EXAMPLE .nf -CURLM *m = curl_multi_init(); -/* try HTTP/2 multiplexing */ -curl_multi_setopt(m, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); +int main(void) +{ + CURLM *m = curl_multi_init(); + /* try HTTP/2 multiplexing */ + curl_multi_setopt(m, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); +} .fi .SH AVAILABILITY Added in 7.16.0. Multiplex support bit added in 7.43.0. HTTP/1 Pipelining diff --git a/docs/libcurl/opts/CURLMOPT_PIPELINING_SERVER_BL.3 b/docs/libcurl/opts/CURLMOPT_PIPELINING_SERVER_BL.3 index 95d475dbe..b59232fb8 100644 --- a/docs/libcurl/opts/CURLMOPT_PIPELINING_SERVER_BL.3 +++ b/docs/libcurl/opts/CURLMOPT_PIPELINING_SERVER_BL.3 @@ -50,14 +50,17 @@ The default value is NULL, which means that there is no block list. .SH PROTOCOLS .SH EXAMPLE .nf - char *server_block_list[] = - { - "Microsoft-IIS/6.0", - "nginx/0.8.54", - NULL - }; - +static char *server_block_list[] = +{ + "Microsoft-IIS/6.0", + "nginx/0.8.54", + NULL +}; +int main(void) +{ + CURLM *m = curl_multi_init(); curl_multi_setopt(m, CURLMOPT_PIPELINING_SERVER_BL, server_block_list); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_PIPELINING_SITE_BL.3 b/docs/libcurl/opts/CURLMOPT_PIPELINING_SITE_BL.3 index 0e4e52e1a..2bbfbfe26 100644 --- a/docs/libcurl/opts/CURLMOPT_PIPELINING_SITE_BL.3 +++ b/docs/libcurl/opts/CURLMOPT_PIPELINING_SITE_BL.3 @@ -46,14 +46,18 @@ The default value is NULL, which means that there is no block list. HTTP(S) .SH EXAMPLE .nf - char *site_block_list[] = - { - "www.haxx.se", - "www.example.com:1234", - NULL - }; +static char *site_block_list[] = +{ + "www.haxx.se", + "www.example.com:1234", + NULL +}; +int main(void) +{ + CURLM *m = curl_multi_init(); curl_multi_setopt(m, CURLMOPT_PIPELINING_SITE_BL, site_block_list); +} .fi .SH AVAILABILITY Added in 7.30.0 diff --git a/docs/libcurl/opts/CURLMOPT_PUSHDATA.3 b/docs/libcurl/opts/CURLMOPT_PUSHDATA.3 index 2b1968417..8ff04bbe0 100644 --- a/docs/libcurl/opts/CURLMOPT_PUSHDATA.3 +++ b/docs/libcurl/opts/CURLMOPT_PUSHDATA.3 @@ -41,6 +41,8 @@ NULL HTTP(S) .SH EXAMPLE .nf +#include + /* only allow pushes for file names starting with "push-" */ int push_callback(CURL *parent, CURL *easy, @@ -68,8 +70,13 @@ int push_callback(CURL *parent, return CURL_PUSH_DENY; } -curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_callback); -curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); +int main(void) +{ + int counter; + CURLM *multi = curl_multi_init(); + curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_callback); + curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); +} .fi .SH AVAILABILITY Added in 7.44.0 diff --git a/docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 b/docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 index 9e0d8b9f2..e1a96218f 100644 --- a/docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 +++ b/docs/libcurl/opts/CURLMOPT_PUSHFUNCTION.3 @@ -91,6 +91,8 @@ NULL, no callback HTTP(S) (HTTP/2 only) .SH EXAMPLE .nf +#include + /* only allow pushes for file names starting with "push-" */ int push_callback(CURL *parent, CURL *easy, @@ -118,8 +120,13 @@ int push_callback(CURL *parent, return CURL_PUSH_DENY; } -curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_callback); -curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); +int main(void) +{ + int counter; + CURLM *multi = curl_multi_init(); + curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_callback); + curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); +} .fi .SH AVAILABILITY Added in 7.44.0 diff --git a/docs/libcurl/opts/CURLMOPT_SOCKETDATA.3 b/docs/libcurl/opts/CURLMOPT_SOCKETDATA.3 index 4dd103bee..aeb04daba 100644 --- a/docs/libcurl/opts/CURLMOPT_SOCKETDATA.3 +++ b/docs/libcurl/opts/CURLMOPT_SOCKETDATA.3 @@ -42,28 +42,32 @@ NULL All .SH EXAMPLE .nf +struct priv { + void *ours; +}; + 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 priv *p = sockp; + printf("my ptr: %p\\n", p->ours); if(what == CURL_POLL_REMOVE) { - remsock(fdp); + /* remove the socket from our collection */ + } + if(what & CURL_POLL_IN) { + /* wait for read on this socket */ } - else { - if(!fdp) { - addsock(s, e, what, g); - } - else { - setsock(fdp, s, e, what, g); - } + if(what & CURL_POLL_OUT) { + /* wait for write on this socket */ } + return 0; } -main() +int main(void) { - GlobalInfo setup; + struct priv setup; + CURLM *multi = curl_multi_init(); /* ... use socket callback and custom pointer */ curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, &setup); diff --git a/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.3 b/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.3 index fa4272e13..701715dd2 100644 --- a/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.3 +++ b/docs/libcurl/opts/CURLMOPT_SOCKETFUNCTION.3 @@ -85,28 +85,32 @@ NULL (no callback) All .SH EXAMPLE .nf +struct priv { + void *ours; +}; + static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) { - GlobalInfo *g = cbp; - SockInfo *fdp = sockp; + struct priv *p = sockp; + printf("our ptr: %p\\n", p->ours); if(what == CURL_POLL_REMOVE) { - remsock(fdp); + /* remove the socket from our collection */ + } + if(what & CURL_POLL_IN) { + /* wait for read on this socket */ } - else { - if(!fdp) { - addsock(s, e, what, g); - } - else { - setsock(fdp, s, e, what, g); - } + if(what & CURL_POLL_OUT) { + /* wait for write on this socket */ } + return 0; } -main() +int main(void) { - GlobalInfo setup; + struct priv setup; + CURLM *multi = curl_multi_init(); /* ... use socket callback and custom pointer */ curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, sock_cb); curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, &setup); diff --git a/docs/libcurl/opts/CURLMOPT_TIMERDATA.3 b/docs/libcurl/opts/CURLMOPT_TIMERDATA.3 index 1da6d4a28..b3f853d23 100644 --- a/docs/libcurl/opts/CURLMOPT_TIMERDATA.3 +++ b/docs/libcurl/opts/CURLMOPT_TIMERDATA.3 @@ -42,39 +42,30 @@ NULL All .SH EXAMPLE .nf -static gboolean timeout_cb(gpointer user_data) -{ - int running; - if(user_data) { - g_free(user_data); - curl_multi_setopt(curl_handle, CURLMOPT_TIMERDATA, NULL); - } - curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, &running); - return G_SOURCE_REMOVE; -} +struct priv { + void *custom; +}; static int timerfunc(CURLM *multi, long timeout_ms, void *clientp) { - guint *id = clientp; - - if(id) - g_source_remove(*id); + struct priv *mydata = clientp; + printf("our ptr: %p\\n", mydata->custom); - /* -1 means we should just delete our timer. */ - if(timeout_ms == -1) { - g_free(id); - id = NULL; - } - else { - if(!id) - id = g_new(guint, 1); - *id = g_timeout_add(timeout_ms, timeout_cb, id); - } - current_timer = id; - return 0; + if(timeout_ms) { + /* this is the new single timeout to wait for */ + } + else { + /* delete the timeout, nothing to wait for now */ + } } -curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, timerfunc); +int main(void) +{ + struct priv mydata; + CURLM *multi = curl_multi_init(); + curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, timerfunc); + curl_multi_setopt(multi, CURLMOPT_TIMERDATA, &mydata); +} .fi .SH AVAILABILITY Added in 7.16.0 diff --git a/docs/libcurl/opts/CURLMOPT_TIMERFUNCTION.3 b/docs/libcurl/opts/CURLMOPT_TIMERFUNCTION.3 index 4914dc6f9..69ad15167 100644 --- a/docs/libcurl/opts/CURLMOPT_TIMERFUNCTION.3 +++ b/docs/libcurl/opts/CURLMOPT_TIMERFUNCTION.3 @@ -70,39 +70,30 @@ NULL All .SH EXAMPLE .nf -static gboolean timeout_cb(gpointer user_data) -{ - int running; - if(user_data) { - g_free(user_data); - curl_multi_setopt(curl_handle, CURLMOPT_TIMERDATA, NULL); - } - curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, &running); - return G_SOURCE_REMOVE; -} +struct priv { + void *custom; +}; static int timerfunc(CURLM *multi, long timeout_ms, void *clientp) { - guint *id = clientp; - - if(id) - g_source_remove(*id); + struct priv *mydata = clientp; + printf("our ptr: %p\\n", mydata->custom); - /* -1 means we should just delete our timer. */ - if(timeout_ms == -1) { - g_free(id); - id = NULL; - } - else { - if(!id) - id = g_new(guint, 1); - *id = g_timeout_add(timeout_ms, timeout_cb, id); - } - current_timer = id; - return 0; + if(timeout_ms) { + /* this is the new single timeout to wait for */ + } + else { + /* delete the timeout, nothing to wait for now */ + } } -curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, timerfunc); +int main(void) +{ + struct priv mydata; + CURLM *multi = curl_multi_init(); + curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, timerfunc); + curl_multi_setopt(multi, CURLMOPT_TIMERDATA, &mydata); +} .fi .SH AVAILABILITY Added in 7.16.0 diff --git a/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 b/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 index dcb34296f..0e89be55f 100644 --- a/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 +++ b/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 @@ -52,10 +52,18 @@ Default is NULL. All .SH EXAMPLE .nf - curl_easy_setopt(curl_handle, CURLOPT_ABSTRACT_UNIX_SOCKET, "/tmp/foo.sock"); - curl_easy_setopt(curl_handle, CURLOPT_URL, "http://localhost/"); -.fi +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_ABSTRACT_UNIX_SOCKET, "/tmp/foo.sock"); + curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/"); + /* Perform the request */ + curl_easy_perform(curl); + } +} +.fi .SH AVAILABILITY Added in 7.53.0. .SH RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_ACCEPTTIMEOUT_MS.3 b/docs/libcurl/opts/CURLOPT_ACCEPTTIMEOUT_MS.3 index 92dcf8757..b93142599 100644 --- a/docs/libcurl/opts/CURLOPT_ACCEPTTIMEOUT_MS.3 +++ b/docs/libcurl/opts/CURLOPT_ACCEPTTIMEOUT_MS.3 @@ -40,14 +40,17 @@ server to connect back to libcurl when an active FTP connection is used. FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/path/file"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/path/file"); - /* wait no more than 5 seconds for FTP server responses */ - curl_easy_setopt(curl, CURLOPT_ACCEPTTIMEOUT_MS, 5000L); + /* wait no more than 5 seconds for FTP server responses */ + curl_easy_setopt(curl, CURLOPT_ACCEPTTIMEOUT_MS, 5000L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.3 b/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.3 index 821bf2f28..230b6b07f 100644 --- a/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.3 +++ b/docs/libcurl/opts/CURLOPT_ACCEPT_ENCODING.3 @@ -82,15 +82,18 @@ NULL HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* enable all supported built-in compressions */ - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); + /* enable all supported built-in compressions */ + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_ADDRESS_SCOPE.3 b/docs/libcurl/opts/CURLOPT_ADDRESS_SCOPE.3 index e3d3e128a..eea7f8847 100644 --- a/docs/libcurl/opts/CURLOPT_ADDRESS_SCOPE.3 +++ b/docs/libcurl/opts/CURLOPT_ADDRESS_SCOPE.3 @@ -39,15 +39,20 @@ Pass a long specifying the scope id value to use when connecting to IPv6 address All, when using IPv6 .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - long my_scope_id; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - my_scope_id = if_nametoindex("eth0"); - curl_easy_setopt(curl, CURLOPT_ADDRESS_SCOPE, my_scope_id); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +#include /* for if_nametoindex() */ + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + long my_scope_id; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + my_scope_id = if_nametoindex("eth0"); + curl_easy_setopt(curl, CURLOPT_ADDRESS_SCOPE, my_scope_id); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_ALTSVC.3 b/docs/libcurl/opts/CURLOPT_ALTSVC.3 index 7338580f5..5af38437d 100644 --- a/docs/libcurl/opts/CURLOPT_ALTSVC.3 +++ b/docs/libcurl/opts/CURLOPT_ALTSVC.3 @@ -44,11 +44,14 @@ NULL. The alt-svc cache is not read nor written to file. HTTPS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, CURLALTSVC_H1); - curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, CURLALTSVC_H1); + curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt"); + curl_easy_perform(curl); + } } .fi .SH "FILE FORMAT" diff --git a/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3 b/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3 index c8318f8d0..5ba91c440 100644 --- a/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3 +++ b/docs/libcurl/opts/CURLOPT_ALTSVC_CTRL.3 @@ -71,11 +71,14 @@ only set if libcurl was built with support for those versions. HTTPS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, (long)CURLALTSVC_H1); - curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, (long)CURLALTSVC_H1); + curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc-cache.txt"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_APPEND.3 b/docs/libcurl/opts/CURLOPT_APPEND.3 index 3ab46b47b..0830c1a50 100644 --- a/docs/libcurl/opts/CURLOPT_APPEND.3 +++ b/docs/libcurl/opts/CURLOPT_APPEND.3 @@ -40,14 +40,17 @@ instead of overwrite it. This is only useful when uploading to an FTP site. FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/to/newfile"); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - curl_easy_setopt(curl, CURLOPT_APPEND, 1L); + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/to/newfile"); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_APPEND, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_AUTOREFERER.3 b/docs/libcurl/opts/CURLOPT_AUTOREFERER.3 index 478e221ad..5f94efc00 100644 --- a/docs/libcurl/opts/CURLOPT_AUTOREFERER.3 +++ b/docs/libcurl/opts/CURLOPT_AUTOREFERER.3 @@ -45,19 +45,23 @@ considered a minor privacy leak by some. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* follow redirects */ - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + /* follow redirects */ + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - /* set Referer: automatically when following redirects */ - curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1L); + /* set Referer: automatically when following redirects */ + curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 index 9dfc3e166..0cea12d02 100644 --- a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 +++ b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 @@ -67,20 +67,23 @@ as calling this with \fB"aws:amz"\fP in parameter. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); +int main(void) +{ + CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, - "https://service.region.example.com/uri"); - curl_easy_setopt(c, CURLOPT_AWS_SIGV4, "provider1:provider2"); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, + "https://service.region.example.com/uri"); + curl_easy_setopt(curl, CURLOPT_AWS_SIGV4, "provider1:provider2"); - /* service and region can also be set in CURLOPT_AWS_SIGV4 */ - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/uri"); - curl_easy_setopt(c, CURLOPT_AWS_SIGV4, - "provider1:provider2:region:service"); + /* service and region can also be set in CURLOPT_AWS_SIGV4 */ + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/uri"); + curl_easy_setopt(curl, CURLOPT_AWS_SIGV4, + "provider1:provider2:region:service"); - curl_easy_setopt(c, CURLOPT_USERPWD, "MY_ACCESS_KEY:MY_SECRET_KEY"); - curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_USERPWD, "MY_ACCESS_KEY:MY_SECRET_KEY"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_BUFFERSIZE.3 b/docs/libcurl/opts/CURLOPT_BUFFERSIZE.3 index 6a14076ee..f90c77295 100644 --- a/docs/libcurl/opts/CURLOPT_BUFFERSIZE.3 +++ b/docs/libcurl/opts/CURLOPT_BUFFERSIZE.3 @@ -54,16 +54,20 @@ CURL_MAX_WRITE_SIZE (16kB) All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/foo.bin"); - /* ask libcurl to allocate a larger receive buffer */ - curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 120000L); + /* ask libcurl to allocate a larger receive buffer */ + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 120000L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CAINFO.3 b/docs/libcurl/opts/CURLOPT_CAINFO.3 index dc94c0cdc..f4e151eff 100644 --- a/docs/libcurl/opts/CURLOPT_CAINFO.3 +++ b/docs/libcurl/opts/CURLOPT_CAINFO.3 @@ -62,12 +62,15 @@ Schannel, this option is not set by default. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/certs/cabundle.pem"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/certs/cabundle.pem"); + curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.3 b/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.3 index ebb27111b..db3bed941 100644 --- a/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_CAINFO_BLOB.3 @@ -37,6 +37,10 @@ Pass a pointer to a curl_blob structure, which contains information (pointer and size) about a memory block with binary data of PEM encoded content holding one or more certificates to verify the HTTPS server with. +If the blob is initialized with the flags member of struct curl_blob set to +CURL_BLOB_COPY, the application does not have to keep the buffer around after +setting this. + If \fICURLOPT_SSL_VERIFYPEER(3)\fP is zero and you avoid verifying the server's certificate, \fICURLOPT_CAINFO_BLOB(3)\fP is not needed. @@ -47,17 +51,23 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -char *strpem; /* strpem must point to a PEM string */ -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - blob.data = strpem; - blob.len = strlen(strpem); - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +#include + +int main(void) +{ + char *strpem; /* strpem must point to a PEM string */ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + blob.data = strpem; + blob.len = strlen(strpem); + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CAPATH.3 b/docs/libcurl/opts/CURLOPT_CAPATH.3 index 5a453beca..8288ee334 100644 --- a/docs/libcurl/opts/CURLOPT_CAPATH.3 +++ b/docs/libcurl/opts/CURLOPT_CAPATH.3 @@ -51,12 +51,16 @@ A default path detected at build time. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/cert-dir"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/cert-dir"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CA_CACHE_TIMEOUT.3 b/docs/libcurl/opts/CURLOPT_CA_CACHE_TIMEOUT.3 index 36d2bf74a..8c2635120 100644 --- a/docs/libcurl/opts/CURLOPT_CA_CACHE_TIMEOUT.3 +++ b/docs/libcurl/opts/CURLOPT_CA_CACHE_TIMEOUT.3 @@ -49,27 +49,31 @@ store remain forever. By default, libcurl caches this info for 24 hours. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* only reuse certificate stores for a short time */ - curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 60L); + /* only reuse certificate stores for a short time */ + curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 60L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - /* in this second request, the cache is not used if more than - sixty seconds passed since the previous connection */ - ret = curl_easy_perform(curl); + /* in this second request, the cache is not used if more than + sixty seconds passed since the previous connection */ + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY This option was added in curl 7.87.0. -Currently the only SSL backend to implement this certificate store caching -functionality is the OpenSSL (and forks) backend. +This option is supported by OpenSSL and its forks (since 7.87.0) and Schannel +(since 8.5.0). .SH RETURN VALUE Returns CURLE_OK .SH "SEE ALSO" diff --git a/docs/libcurl/opts/CURLOPT_CERTINFO.3 b/docs/libcurl/opts/CURLOPT_CERTINFO.3 index 146362960..7b2013407 100644 --- a/docs/libcurl/opts/CURLOPT_CERTINFO.3 +++ b/docs/libcurl/opts/CURLOPT_CERTINFO.3 @@ -43,34 +43,39 @@ its option \fICURLINFO_CERTINFO(3)\fP. All TLS-based .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/"); - /* connect to any HTTPS site, trusted or not */ - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + /* connect to any HTTPS site, trusted or not */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); + curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - if (!res) { - struct curl_certinfo *ci; - res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ci); + if(!res) { + struct curl_certinfo *ci; + res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ci); - if (!res) { - printf("%d certs!\\n", ci->num_of_certs); + if(!res) { + int i; + printf("%d certs!\\n", ci->num_of_certs); - for(i = 0; i < ci->num_of_certs; i++) { - struct curl_slist *slist; + for(i = 0; i < ci->num_of_certs; i++) { + struct curl_slist *slist; - for(slist = ci->certinfo[i]; slist; slist = slist->next) - printf("%s\\n", slist->data); + for(slist = ci->certinfo[i]; slist; slist = slist->next) + printf("%s\\n", slist->data); + } } } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CHUNK_BGN_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_CHUNK_BGN_FUNCTION.3 index a8b227357..88f3768c9 100644 --- a/docs/libcurl/opts/CURLOPT_CHUNK_BGN_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_CHUNK_BGN_FUNCTION.3 @@ -90,10 +90,17 @@ NULL FTP .SH EXAMPLE .nf +#include + +struct callback_data { + FILE *output; +}; + static long file_is_coming(struct curl_fileinfo *finfo, - struct callback_data *data, + void *ptr, int remains) { + struct callback_data *data = ptr; printf("%3d %40s %10luB ", remains, finfo->filename, (unsigned long)finfo->size); @@ -130,6 +137,8 @@ int main() /* data for callback */ struct callback_data callback_info; + CURL *curl = curl_easy_init(); + /* callback is called before download of concrete file started */ curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming); curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &callback_info); diff --git a/docs/libcurl/opts/CURLOPT_CHUNK_DATA.3 b/docs/libcurl/opts/CURLOPT_CHUNK_DATA.3 index 785c010cf..a4e35244d 100644 --- a/docs/libcurl/opts/CURLOPT_CHUNK_DATA.3 +++ b/docs/libcurl/opts/CURLOPT_CHUNK_DATA.3 @@ -41,10 +41,17 @@ NULL FTP .SH EXAMPLE .nf +#include + +struct callback_data { + FILE *output; +}; + static long file_is_coming(struct curl_fileinfo *finfo, - struct callback_data *data, + void *ptr, int remains) { + struct callback_data *data = ptr; printf("%3d %40s %10luB ", remains, finfo->filename, (unsigned long)finfo->size); @@ -81,6 +88,8 @@ int main() /* data for callback */ struct callback_data callback_info; + CURL *curl = curl_easy_init(); + /* callback is called before download of concrete file started */ curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming); curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &callback_info); diff --git a/docs/libcurl/opts/CURLOPT_CHUNK_END_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_CHUNK_END_FUNCTION.3 index c5b752b67..c6bf88e45 100644 --- a/docs/libcurl/opts/CURLOPT_CHUNK_END_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_CHUNK_END_FUNCTION.3 @@ -48,6 +48,12 @@ NULL FTP .SH EXAMPLE .nf +#include + +struct callback_data { + FILE *output; +}; + static long file_is_downloaded(struct callback_data *data) { if(data->output) { @@ -61,6 +67,9 @@ int main() { /* data for callback */ struct callback_data callback_info; + + CURL *curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded); curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &callback_info); } diff --git a/docs/libcurl/opts/CURLOPT_CLOSESOCKETDATA.3 b/docs/libcurl/opts/CURLOPT_CLOSESOCKETDATA.3 index 25601d4a6..d1f870575 100644 --- a/docs/libcurl/opts/CURLOPT_CLOSESOCKETDATA.3 +++ b/docs/libcurl/opts/CURLOPT_CLOSESOCKETDATA.3 @@ -42,15 +42,31 @@ The default value of this parameter is NULL. All except file: .SH EXAMPLE .nf +struct priv { + void *custom; +}; + static int closesocket(void *clientp, curl_socket_t item) { + struct priv *my = clientp; + printf("our ptr: %p\\n", my->custom); + printf("libcurl wants to close %d now\\n", (int)item); return 0; } -/* call this function to close sockets */ -curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closesocket); -curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &sockfd); +int main(void) +{ + struct priv myown; + CURL *curl = curl_easy_init(); + + /* call this function to close sockets */ + curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closesocket); + curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &myown); + + curl_easy_perform(curl); + curl_easy_cleanup(curl); +} .fi .SH AVAILABILITY Added in 7.21.7 diff --git a/docs/libcurl/opts/CURLOPT_CLOSESOCKETFUNCTION.3 b/docs/libcurl/opts/CURLOPT_CLOSESOCKETFUNCTION.3 index 27efd61af..fb81f696f 100644 --- a/docs/libcurl/opts/CURLOPT_CLOSESOCKETFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_CLOSESOCKETFUNCTION.3 @@ -53,15 +53,31 @@ By default libcurl uses the standard socket close function. All .SH EXAMPLE .nf +struct priv { + void *custom; +}; + static int closesocket(void *clientp, curl_socket_t item) { + struct priv *my = clientp; + printf("our ptr: %p\\n", my->custom); + printf("libcurl wants to close %d now\\n", (int)item); return 0; } -/* call this function to close sockets */ -curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closesocket); -curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &sockfd); +int main(void) +{ + struct priv myown; + CURL *curl = curl_easy_init(); + + /* call this function to close sockets */ + curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closesocket); + curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &myown); + + curl_easy_perform(curl); + curl_easy_cleanup(curl); +} .fi .SH AVAILABILITY Added in 7.21.7 diff --git a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.3 b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.3 index c9091cb52..1d4a2ed54 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.3 +++ b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT.3 @@ -66,14 +66,17 @@ signals to be used unless \fICURLOPT_NOSIGNAL(3)\fP is set. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* complete connection within 10 seconds */ - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); + /* complete connection within 10 seconds */ + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.3 b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.3 index ec83ca35b..67c0097ef 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.3 +++ b/docs/libcurl/opts/CURLOPT_CONNECTTIMEOUT_MS.3 @@ -43,14 +43,17 @@ See \fICURLOPT_CONNECTTIMEOUT(3)\fP for details. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* complete connection within 10000 milliseconds */ - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 10000L); + /* complete connection within 10000 milliseconds */ + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 10000L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3 b/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3 index ca71a669a..014c5f2cf 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3 +++ b/docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3 @@ -60,14 +60,17 @@ application wants to use it. Once it has been removed with HTTP, SMTP, POP3 and IMAP. For WS and WSS starting in 7.86.0. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); - ret = curl_easy_perform(curl); - if(ret == CURLE_OK) { - /* only connected! */ +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); + ret = curl_easy_perform(curl); + if(ret == CURLE_OK) { + /* only connected! */ + } } } .fi diff --git a/docs/libcurl/opts/CURLOPT_CONNECT_TO.3 b/docs/libcurl/opts/CURLOPT_CONNECT_TO.3 index 1c4b80b64..e0a45031b 100644 --- a/docs/libcurl/opts/CURLOPT_CONNECT_TO.3 +++ b/docs/libcurl/opts/CURLOPT_CONNECT_TO.3 @@ -88,22 +88,25 @@ NULL All .SH EXAMPLE .nf -CURL *curl; -struct curl_slist *connect_to = NULL; -connect_to = curl_slist_append(NULL, "example.com::server1.example.com:"); +int main(void) +{ + CURL *curl; + struct curl_slist *connect_to = NULL; + connect_to = curl_slist_append(NULL, "example.com::server1.example.com:"); -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_CONNECT_TO, connect_to); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* always cleanup */ - curl_easy_cleanup(curl); -} + /* always cleanup */ + curl_easy_cleanup(curl); + } -curl_slist_free_all(connect_to); + curl_slist_free_all(connect_to); +} .fi .SH AVAILABILITY Added in 7.49.0 diff --git a/docs/libcurl/opts/CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 index 9d14df7cd..2baf5f46f 100644 --- a/docs/libcurl/opts/CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 @@ -77,12 +77,12 @@ FTP, SMTP, IMAP, POP3 .nf static CURLcode my_conv_from_ascii_to_ebcdic(char *buffer, size_t length) { - char *tempptrin, *tempptrout; - size_t bytes = length; - int rc; - tempptrin = tempptrout = buffer; - rc = platform_a2e(&tempptrin, &bytes, &tempptrout, &bytes); - if(rc == PLATFORM_CONV_OK) { + int rc = 0; + + /* in-place convert 'buffer' from ASCII to EBCDIC */ + + if(rc == 0) { + /* success */ return CURLE_OK; } else { @@ -90,9 +90,14 @@ static CURLcode my_conv_from_ascii_to_ebcdic(char *buffer, size_t length) } } -/* use platform-specific functions for codeset conversions */ -curl_easy_setopt(curl, CURLOPT_CONV_FROM_NETWORK_FUNCTION, - my_conv_from_ascii_to_ebcdic); +int main(void) +{ + CURL *curl = curl_easy_init(); + + /* use platform-specific functions for codeset conversions */ + curl_easy_setopt(curl, CURLOPT_CONV_FROM_NETWORK_FUNCTION, + my_conv_from_ascii_to_ebcdic); +} .fi .SH AVAILABILITY Not available and deprecated since 7.82.0. diff --git a/docs/libcurl/opts/CURLOPT_CONV_FROM_UTF8_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_CONV_FROM_UTF8_FUNCTION.3 index d4ae0c54d..e6ab8bf5b 100644 --- a/docs/libcurl/opts/CURLOPT_CONV_FROM_UTF8_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_CONV_FROM_UTF8_FUNCTION.3 @@ -76,12 +76,10 @@ TLS-based protocols. .nf static CURLcode my_conv_from_utf8_to_ebcdic(char *buffer, size_t length) { - char *tempptrin, *tempptrout; - size_t bytes = length; - int rc; - tempptrin = tempptrout = buffer; - rc = platform_u2e(&tempptrin, &bytes, &tempptrout, &bytes); - if(rc == PLATFORM_CONV_OK) { + int rc = 0; + /* in-place convert 'buffer' from UTF-8 to EBCDIC */ + if(rc == 0) { + /* success */ return CURLE_OK; } else { @@ -89,8 +87,12 @@ static CURLcode my_conv_from_utf8_to_ebcdic(char *buffer, size_t length) } } -curl_easy_setopt(curl, CURLOPT_CONV_FROM_UTF8_FUNCTION, - my_conv_from_utf8_to_ebcdic); +int main(void) +{ + CURL *curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_CONV_FROM_UTF8_FUNCTION, + my_conv_from_utf8_to_ebcdic); +} .fi .SH AVAILABILITY Not available and deprecated since 7.82.0. diff --git a/docs/libcurl/opts/CURLOPT_CONV_TO_NETWORK_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_CONV_TO_NETWORK_FUNCTION.3 index a334078a4..e2dc7d606 100644 --- a/docs/libcurl/opts/CURLOPT_CONV_TO_NETWORK_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_CONV_TO_NETWORK_FUNCTION.3 @@ -77,12 +77,10 @@ FTP, SMTP, IMAP, POP3 .nf static CURLcode my_conv_from_ebcdic_to_ascii(char *buffer, size_t length) { - char *tempptrin, *tempptrout; - size_t bytes = length; - int rc; - tempptrin = tempptrout = buffer; - rc = platform_e2a(&tempptrin, &bytes, &tempptrout, &bytes); - if(rc == PLATFORM_CONV_OK) { + int rc = 0; + /* in-place convert 'buffer' from EBCDIC to ASCII */ + if(rc == 0) { + /* success */ return CURLE_OK; } else { @@ -90,8 +88,13 @@ static CURLcode my_conv_from_ebcdic_to_ascii(char *buffer, size_t length) } } -curl_easy_setopt(curl, CURLOPT_CONV_TO_NETWORK_FUNCTION, - my_conv_from_ebcdic_to_ascii); +int main(void) +{ + CURL *curl = curl_easy_init(); + + curl_easy_setopt(curl, CURLOPT_CONV_TO_NETWORK_FUNCTION, + my_conv_from_ebcdic_to_ascii); +} .fi .SH AVAILABILITY Not available and deprecated since 7.82.0. diff --git a/docs/libcurl/opts/CURLOPT_COOKIE.3 b/docs/libcurl/opts/CURLOPT_COOKIE.3 index b7de3ebe2..e21d54c5f 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIE.3 +++ b/docs/libcurl/opts/CURLOPT_COOKIE.3 @@ -68,13 +68,16 @@ NULL, no cookies HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_COOKIE, "tool=curl; fun=yes;"); + curl_easy_setopt(curl, CURLOPT_COOKIE, "tool=curl; fun=yes;"); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_COOKIEFILE.3 b/docs/libcurl/opts/CURLOPT_COOKIEFILE.3 index 08e9582fc..e1d5dbd96 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIEFILE.3 +++ b/docs/libcurl/opts/CURLOPT_COOKIEFILE.3 @@ -72,16 +72,20 @@ NULL HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* get cookies from an existing file */ - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookies.txt"); + /* get cookies from an existing file */ + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookies.txt"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH "Cookie file format" diff --git a/docs/libcurl/opts/CURLOPT_COOKIEJAR.3 b/docs/libcurl/opts/CURLOPT_COOKIEJAR.3 index f84d99a16..f8d75bea4 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIEJAR.3 +++ b/docs/libcurl/opts/CURLOPT_COOKIEJAR.3 @@ -60,17 +60,21 @@ NULL HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* export cookies to this file when closing the handle */ - curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "/tmp/cookies.txt"); + /* export cookies to this file when closing the handle */ + curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "/tmp/cookies.txt"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - /* close the handle, write the cookies! */ - curl_easy_cleanup(curl); + /* close the handle, write the cookies! */ + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_COOKIELIST.3 b/docs/libcurl/opts/CURLOPT_COOKIELIST.3 index da9ca290a..41862311a 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIELIST.3 +++ b/docs/libcurl/opts/CURLOPT_COOKIELIST.3 @@ -74,35 +74,41 @@ HTTP #define SEP "\\t" /* Tab separates the fields */ -char *my_cookie = - "example.com" /* Hostname */ - SEP "FALSE" /* Include subdomains */ - SEP "/" /* Path */ - SEP "FALSE" /* Secure */ - SEP "0" /* Expiry in epoch time format. 0 == Session */ - SEP "foo" /* Name */ - SEP "bar"; /* Value */ - -/* my_cookie is imported immediately via CURLOPT_COOKIELIST. */ -curl_easy_setopt(curl, CURLOPT_COOKIELIST, my_cookie); - -/* The list of cookies in cookies.txt are not be imported until right - before a transfer is performed. Cookies in the list that have the same - hostname, path and name as in my_cookie are skipped. That is because - libcurl has already imported my_cookie and it's considered a "live" - cookie. A live cookie is not replaced by one read from a file. -*/ -curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt"); /* import */ - -/* Cookies are exported after curl_easy_cleanup is called. The server - may have added, deleted or modified cookies by then. The cookies that - were skipped on import are not exported. -*/ -curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt"); /* export */ - -curl_easy_perform(curl); /* cookies imported from cookies.txt */ - -curl_easy_cleanup(curl); /* cookies exported to cookies.txt */ +int main(void) +{ + char *my_cookie = + "example.com" /* Hostname */ + SEP "FALSE" /* Include subdomains */ + SEP "/" /* Path */ + SEP "FALSE" /* Secure */ + SEP "0" /* Expiry in epoch time format. 0 == Session */ + SEP "foo" /* Name */ + SEP "bar"; /* Value */ + + CURL *curl = curl_easy_init(); + if(curl) { + /* my_cookie is imported immediately via CURLOPT_COOKIELIST. */ + curl_easy_setopt(curl, CURLOPT_COOKIELIST, my_cookie); + + /* The list of cookies in cookies.txt are not be imported until right + before a transfer is performed. Cookies in the list that have the same + hostname, path and name as in my_cookie are skipped. That is because + libcurl has already imported my_cookie and it's considered a "live" + cookie. A live cookie is not replaced by one read from a file. + */ + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt"); /* import */ + + /* Cookies are exported after curl_easy_cleanup is called. The server + may have added, deleted or modified cookies by then. The cookies that + were skipped on import are not exported. + */ + curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt"); /* export */ + + curl_easy_perform(curl); /* cookies imported from cookies.txt */ + + curl_easy_cleanup(curl); /* cookies exported to cookies.txt */ + } +} .fi .SH "Cookie file format" The cookie file format and general cookie concepts in curl are described diff --git a/docs/libcurl/opts/CURLOPT_COOKIESESSION.3 b/docs/libcurl/opts/CURLOPT_COOKIESESSION.3 index 3578b8287..b8894d0fe 100644 --- a/docs/libcurl/opts/CURLOPT_COOKIESESSION.3 +++ b/docs/libcurl/opts/CURLOPT_COOKIESESSION.3 @@ -48,19 +48,23 @@ the same session. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* new "session", do not load session cookies */ - curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1L); + /* new "session", do not load session cookies */ + curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1L); - /* get the (non session) cookies from this file */ - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookies.txt"); + /* get the (non session) cookies from this file */ + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookies.txt"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.3 b/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.3 index 870bb670b..447c66833 100644 --- a/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.3 +++ b/docs/libcurl/opts/CURLOPT_COPYPOSTFIELDS.3 @@ -51,18 +51,21 @@ NULL HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - char local_buffer[1024]="data to send"; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + char local_buffer[1024]="data to send"; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* size of the data to copy from the buffer and send in the request */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L); + /* size of the data to copy from the buffer and send in the request */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L); - /* send data from the local stack */ - curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, local_buffer); + /* send data from the local stack */ + curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, local_buffer); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CRLF.3 b/docs/libcurl/opts/CURLOPT_CRLF.3 index abcdcefa4..b758f2985 100644 --- a/docs/libcurl/opts/CURLOPT_CRLF.3 +++ b/docs/libcurl/opts/CURLOPT_CRLF.3 @@ -43,13 +43,16 @@ This is a legacy option of questionable use. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/"); - curl_easy_setopt(curl, CURLOPT_CRLF, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/"); + curl_easy_setopt(curl, CURLOPT_CRLF, 1L); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CRLFILE.3 b/docs/libcurl/opts/CURLOPT_CRLFILE.3 index da6d639ea..30a6ad1ad 100644 --- a/docs/libcurl/opts/CURLOPT_CRLFILE.3 +++ b/docs/libcurl/opts/CURLOPT_CRLFILE.3 @@ -61,12 +61,16 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_CRLFILE, "/etc/certs/crl.pem"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_CRLFILE, "/etc/certs/crl.pem"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CURLU.3 b/docs/libcurl/opts/CURLOPT_CURLU.3 index 5b16f2115..34e9c53b4 100644 --- a/docs/libcurl/opts/CURLOPT_CURLU.3 +++ b/docs/libcurl/opts/CURLOPT_CURLU.3 @@ -49,19 +49,22 @@ The default value of this parameter is NULL. All .SH EXAMPLE .nf -CURL *handle = curl_easy_init(); -CURLU *urlp = curl_url(); -int res = 0; -if(curl) { +int main(void) +{ + CURL *curl = curl_easy_init(); + CURLU *urlp = curl_url(); + if(curl) { + CURLcode res; + CURLUcode ret; + ret = curl_url_set(urlp, CURLUPART_URL, "https://example.com", 0); - res = curl_url_set(urlp, CURLUPART_URL, "https://example.com", 0); + curl_easy_setopt(curl, CURLOPT_CURLU, urlp); - curl_easy_setopt(handle, CURLOPT_CURLU, urlp); + res = curl_easy_perform(curl); - ret = curl_easy_perform(handle); - - curl_url_cleanup(urlp); - curl_easy_cleanup(handle); + curl_url_cleanup(urlp); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.3 b/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.3 index 00132854e..6a1f0eeeb 100644 --- a/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.3 +++ b/docs/libcurl/opts/CURLOPT_CUSTOMREQUEST.3 @@ -39,6 +39,9 @@ When you change the request \fImethod\fP by setting libcurl behaves or acts in regards to the particular request method, it only changes the actual string sent in the request. +libcurl passes on the verbatim string in its request without any filter or +other safe guards. That includes white space and control characters. + Restore to the internal default by setting this to NULL. This option can be used to specify the request: @@ -93,16 +96,20 @@ NULL HTTP, FTP, IMAP, POP3 and SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* DELETE the given path */ - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + /* DELETE the given path */ + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DEBUGDATA.3 b/docs/libcurl/opts/CURLOPT_DEBUGDATA.3 index b7db29309..1b569e983 100644 --- a/docs/libcurl/opts/CURLOPT_DEBUGDATA.3 +++ b/docs/libcurl/opts/CURLOPT_DEBUGDATA.3 @@ -41,6 +41,20 @@ NULL All .SH EXAMPLE .nf +struct data { + void *custom; +}; + +static int my_trace(CURL *handle, curl_infotype type, + char *data, size_t size, + void *clientp) +{ + struct data *mine = clientp; + printf("our ptr: %p\\n", mine->custom); + + /* output debug info */ +} + int main(void) { CURL *curl; diff --git a/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 b/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 index c3a08f14f..78c9e76a3 100644 --- a/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 @@ -99,25 +99,25 @@ void dump(const char *text, { size_t i; size_t c; - unsigned int width=0x10; + unsigned int width = 0x10; fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\\n", text, (long)size, (long)size); - for(i=0; i= 0x20 && ptr[i+c] < 0x80) ? ptr[i+c] : '.'; + for(c = 0; (c < width) && (i + c < size); c++) { + char x = (ptr[i + c] >= 0x20 && ptr[i + c] < 0x80) ? ptr[i + c] : '.'; fputc(x, stream); } @@ -134,7 +134,7 @@ int my_trace(CURL *handle, curl_infotype type, (void)handle; /* prevent compiler warning */ (void)clientp; - switch (type) { + switch(type) { case CURLINFO_TEXT: fputs("== Info: ", stderr); fwrite(data, size, 1, stderr); diff --git a/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.3 b/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.3 index 60d79d1f0..ef7b24e96 100644 --- a/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.3 +++ b/docs/libcurl/opts/CURLOPT_DEFAULT_PROTOCOL.3 @@ -62,16 +62,19 @@ NULL (make a guess based on the host) All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - /* set a URL without a scheme */ - curl_easy_setopt(curl, CURLOPT_URL, "example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* set a URL without a scheme */ + curl_easy_setopt(curl, CURLOPT_URL, "example.com"); - /* set the default protocol (scheme) for schemeless URLs */ - curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); + /* set the default protocol (scheme) for schemeless URLs */ + curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DIRLISTONLY.3 b/docs/libcurl/opts/CURLOPT_DIRLISTONLY.3 index a301cf9a5..62dac240c 100644 --- a/docs/libcurl/opts/CURLOPT_DIRLISTONLY.3 +++ b/docs/libcurl/opts/CURLOPT_DIRLISTONLY.3 @@ -56,16 +56,20 @@ effectively breaks that feature. FTP, SFTP and POP3 .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/"); - /* list only */ - curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); + /* list only */ + curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DISALLOW_USERNAME_IN_URL.3 b/docs/libcurl/opts/CURLOPT_DISALLOW_USERNAME_IN_URL.3 index e21cbe6b1..077fbd8db 100644 --- a/docs/libcurl/opts/CURLOPT_DISALLOW_USERNAME_IN_URL.3 +++ b/docs/libcurl/opts/CURLOPT_DISALLOW_USERNAME_IN_URL.3 @@ -44,13 +44,16 @@ This is the equivalent to the \fICURLU_DISALLOW_USER\fP flag for the Several .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_DISALLOW_USERNAME_IN_URL, 1L); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_DISALLOW_USERNAME_IN_URL, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_CACHE_TIMEOUT.3 b/docs/libcurl/opts/CURLOPT_DNS_CACHE_TIMEOUT.3 index e14eb7407..2cdb3967a 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_CACHE_TIMEOUT.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_CACHE_TIMEOUT.3 @@ -60,20 +60,24 @@ Since version 8.1.0, libcurl prunes entries from the DNS cache if it exceeds All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* only reuse addresses for a short time */ - curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 2L); + /* only reuse addresses for a short time */ + curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 2L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - /* in this second request, the cache is not be used if more than - two seconds have passed since the previous name resolve */ - ret = curl_easy_perform(curl); + /* in this second request, the cache is not be used if more than + two seconds have passed since the previous name resolve */ + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.3 b/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.3 index 4f8d3106e..dfeabb386 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_INTERFACE.3 @@ -45,12 +45,16 @@ NULL All protocols except file:// - protocols that resolve host names. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_DNS_INTERFACE, "eth0"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_DNS_INTERFACE, "eth0"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.3 b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.3 index 210e37fbf..6f8ad2cf8 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP4.3 @@ -45,12 +45,16 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_DNS_LOCAL_IP4, "192.168.0.14"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_DNS_LOCAL_IP4, "192.168.0.14"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.3 b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.3 index 4f993998b..78ffbf95b 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_LOCAL_IP6.3 @@ -45,12 +45,16 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_DNS_LOCAL_IP6, "fe80::a9ff:fe46:b619"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_DNS_LOCAL_IP6, "fe80::a9ff:fe46:b619"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_SERVERS.3 b/docs/libcurl/opts/CURLOPT_DNS_SERVERS.3 index 53f7319a9..c8e160a7d 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_SERVERS.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_SERVERS.3 @@ -49,12 +49,17 @@ NULL - use system default All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_DNS_SERVERS, "192.168.1.100:53,192.168.1.101"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_DNS_SERVERS, + "192.168.1.100:53,192.168.1.101"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_SHUFFLE_ADDRESSES.3 b/docs/libcurl/opts/CURLOPT_DNS_SHUFFLE_ADDRESSES.3 index ebf0b9aab..cc6934d1d 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_SHUFFLE_ADDRESSES.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_SHUFFLE_ADDRESSES.3 @@ -54,15 +54,18 @@ performance impacts and may cause IPv4 to be used before IPv6 or vice versa. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_DNS_SHUFFLE_ADDRESSES, 1L); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_DNS_SHUFFLE_ADDRESSES, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* always cleanup */ - curl_easy_cleanup(curl); + /* always cleanup */ + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DNS_USE_GLOBAL_CACHE.3 b/docs/libcurl/opts/CURLOPT_DNS_USE_GLOBAL_CACHE.3 index 3de886119..184147b49 100644 --- a/docs/libcurl/opts/CURLOPT_DNS_USE_GLOBAL_CACHE.3 +++ b/docs/libcurl/opts/CURLOPT_DNS_USE_GLOBAL_CACHE.3 @@ -47,15 +47,19 @@ share DNS cache between transfers. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* switch off the use of a global, thread unsafe, cache */ - curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* switch off the use of a global, thread unsafe, cache */ + curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0L); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } + .fi .SH AVAILABILITY Deprecated since 7.11.1. Function removed in 7.62.0. diff --git a/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYHOST.3 b/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYHOST.3 index fa49d38f2..0bcd87b71 100644 --- a/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYHOST.3 +++ b/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYHOST.3 @@ -62,16 +62,20 @@ of the DoH server certificate. DoH .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_DOH_URL, "https://cloudflare-dns.com/dns-query"); + curl_easy_setopt(curl, CURLOPT_DOH_URL, + "https://cloudflare-dns.com/dns-query"); - /* Disable host name verification of the DoH server */ - curl_easy_setopt(curl, CURLOPT_DOH_SSL_VERIFYHOST, 0L); + /* Disable host name verification of the DoH server */ + curl_easy_setopt(curl, CURLOPT_DOH_SSL_VERIFYHOST, 0L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYPEER.3 b/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYPEER.3 index 0e2f5172a..d894871d4 100644 --- a/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYPEER.3 +++ b/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYPEER.3 @@ -73,16 +73,20 @@ the correct end-point. DoH .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_DOH_URL, "https://cloudflare-dns.com/dns-query"); + curl_easy_setopt(curl, CURLOPT_DOH_URL, + "https://cloudflare-dns.com/dns-query"); - /* Disable certificate verification of the DoH server */ - curl_easy_setopt(curl, CURLOPT_DOH_SSL_VERIFYPEER, 0L); + /* Disable certificate verification of the DoH server */ + curl_easy_setopt(curl, CURLOPT_DOH_SSL_VERIFYPEER, 0L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.3 b/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.3 index acf8bcb39..cde868e36 100644 --- a/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.3 +++ b/docs/libcurl/opts/CURLOPT_DOH_SSL_VERIFYSTATUS.3 @@ -50,16 +50,20 @@ the verification fails. DoH .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_DOH_URL, "https://cloudflare-dns.com/dns-query"); + curl_easy_setopt(curl, CURLOPT_DOH_URL, + "https://cloudflare-dns.com/dns-query"); - /* Ask for OCSP stapling when verifying the DoH server */ - curl_easy_setopt(curl, CURLOPT_DOH_SSL_VERIFYSTATUS, 1L); + /* Ask for OCSP stapling when verifying the DoH server */ + curl_easy_setopt(curl, CURLOPT_DOH_SSL_VERIFYSTATUS, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_DOH_URL.3 b/docs/libcurl/opts/CURLOPT_DOH_URL.3 index cfe4a574d..35dbed04a 100644 --- a/docs/libcurl/opts/CURLOPT_DOH_URL.3 +++ b/docs/libcurl/opts/CURLOPT_DOH_URL.3 @@ -70,11 +70,14 @@ the default name resolver. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_DOH_URL, "https://dns.example.com"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_DOH_URL, "https://dns.example.com"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_EGDSOCKET.3 b/docs/libcurl/opts/CURLOPT_EGDSOCKET.3 index f36469b2b..099acd8c5 100644 --- a/docs/libcurl/opts/CURLOPT_EGDSOCKET.3 +++ b/docs/libcurl/opts/CURLOPT_EGDSOCKET.3 @@ -45,12 +45,16 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_EGDSOCKET, "/var/egd.socket"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_EGDSOCKET, "/var/egd.socket"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 index 136a11c3f..76180cba8 100644 --- a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 +++ b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 @@ -55,34 +55,38 @@ NULL All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - CURLcode res; - char errbuf[CURL_ERROR_SIZE]; +#include /* for strlen() */ +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + char errbuf[CURL_ERROR_SIZE]; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* provide a buffer to store errors in */ - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); + /* provide a buffer to store errors in */ + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); - /* set the error buffer as empty before performing a request */ - errbuf[0] = 0; + /* set the error buffer as empty before performing a request */ + errbuf[0] = 0; - /* perform the request */ - res = curl_easy_perform(curl); + /* perform the request */ + res = curl_easy_perform(curl); - /* if the request did not complete correctly, show the error - information. if no detailed error information was written to errbuf - show the more generic information from curl_easy_strerror instead. - */ - if(res != CURLE_OK) { - size_t len = strlen(errbuf); - fprintf(stderr, "\\nlibcurl: (%d) ", res); - if(len) - fprintf(stderr, "%s%s", errbuf, - ((errbuf[len - 1] != '\\n') ? "\\n" : "")); - else - fprintf(stderr, "%s\\n", curl_easy_strerror(res)); + /* if the request did not complete correctly, show the error + information. if no detailed error information was written to errbuf + show the more generic information from curl_easy_strerror instead. + */ + if(res != CURLE_OK) { + size_t len = strlen(errbuf); + fprintf(stderr, "\\nlibcurl: (%d) ", res); + if(len) + fprintf(stderr, "%s%s", errbuf, + ((errbuf[len - 1] != '\\n') ? "\\n" : "")); + else + fprintf(stderr, "%s\\n", curl_easy_strerror(res)); + } } } .fi diff --git a/docs/libcurl/opts/CURLOPT_EXPECT_100_TIMEOUT_MS.3 b/docs/libcurl/opts/CURLOPT_EXPECT_100_TIMEOUT_MS.3 index 7aea1c2ed..987092232 100644 --- a/docs/libcurl/opts/CURLOPT_EXPECT_100_TIMEOUT_MS.3 +++ b/docs/libcurl/opts/CURLOPT_EXPECT_100_TIMEOUT_MS.3 @@ -43,14 +43,17 @@ sent anyway. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* wait 3 seconds for 100-continue */ - curl_easy_setopt(curl, CURLOPT_EXPECT_100_TIMEOUT_MS, 3000L); + /* wait 3 seconds for 100-continue */ + curl_easy_setopt(curl, CURLOPT_EXPECT_100_TIMEOUT_MS, 3000L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FAILONERROR.3 b/docs/libcurl/opts/CURLOPT_FAILONERROR.3 index c62250352..539517125 100644 --- a/docs/libcurl/opts/CURLOPT_FAILONERROR.3 +++ b/docs/libcurl/opts/CURLOPT_FAILONERROR.3 @@ -52,14 +52,17 @@ get closed and \fICURLE_HTTP_RETURNED_ERROR\fP is returned. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); - ret = curl_easy_perform(curl); - if(ret == CURLE_HTTP_RETURNED_ERROR) { - /* an HTTP response error problem */ +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + ret = curl_easy_perform(curl); + if(ret == CURLE_HTTP_RETURNED_ERROR) { + /* an HTTP response error problem */ + } } } .fi diff --git a/docs/libcurl/opts/CURLOPT_FILETIME.3 b/docs/libcurl/opts/CURLOPT_FILETIME.3 index 05f484a2f..39ce7a25b 100644 --- a/docs/libcurl/opts/CURLOPT_FILETIME.3 +++ b/docs/libcurl/opts/CURLOPT_FILETIME.3 @@ -43,21 +43,26 @@ transfer to extract the received time (if any). HTTP(S), FTP(S), SFTP, FILE, SMB(S) .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, url); - /* Ask for filetime */ - curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); - res = curl_easy_perform(curl); - if(CURLE_OK == res) { - res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); - if((CURLE_OK == res) && (filetime >= 0)) { - time_t file_time = (time_t)filetime; - printf("filetime %s: %s", filename, ctime(&file_time)); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/path.html"); + /* Ask for filetime */ + curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); + res = curl_easy_perform(curl); + if(CURLE_OK == res) { + long filetime; + res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime); + if((CURLE_OK == res) && (filetime >= 0)) { + time_t file_time = (time_t)filetime; + printf("filetime: %s", ctime(&file_time)); + } } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FNMATCH_DATA.3 b/docs/libcurl/opts/CURLOPT_FNMATCH_DATA.3 index e8d9feaa5..89ca2d039 100644 --- a/docs/libcurl/opts/CURLOPT_FNMATCH_DATA.3 +++ b/docs/libcurl/opts/CURLOPT_FNMATCH_DATA.3 @@ -40,22 +40,36 @@ NULL FTP .SH EXAMPLE .nf +extern int string_match(const char *s1, const char *s2); + +struct local_stuff { + void *custom; +}; + static int my_fnmatch(void *clientp, const char *pattern, const char *string) { - struct local_stuff *data = (struct local_stuff *)clientp; + struct local_stuff *my = clientp; + printf("my ptr: %p\\n", my->custom); + if(string_match(pattern, string)) return CURL_FNMATCHFUNC_MATCH; else return CURL_FNMATCHFUNC_NOMATCH; } +int main(void) { struct local_stuff local_data; - curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/file*"); - curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); - curl_easy_setopt(curl, CURLOPT_FNMATCH_FUNCTION, my_fnmatch); - curl_easy_setopt(curl, CURLOPT_FNMATCH_DATA, &local_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/file*"); + curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); + curl_easy_setopt(curl, CURLOPT_FNMATCH_FUNCTION, my_fnmatch); + curl_easy_setopt(curl, CURLOPT_FNMATCH_DATA, &local_data); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FNMATCH_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_FNMATCH_FUNCTION.3 index 43466b3ec..7dc835766 100644 --- a/docs/libcurl/opts/CURLOPT_FNMATCH_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_FNMATCH_FUNCTION.3 @@ -50,22 +50,33 @@ NULL == an internal function for wildcard matching. FTP .SH EXAMPLE .nf +extern int string_match(const char *s1, const char *s2); + +struct local_stuff { + void *custom; +}; static int my_fnmatch(void *clientp, const char *pattern, const char *string) { - struct local_stuff *data = (struct local_stuff *)clientp; + struct local_stuff *data = clientp; + printf("my pointer: %p\\n", data->custom); if(string_match(pattern, string)) return CURL_FNMATCHFUNC_MATCH; else return CURL_FNMATCHFUNC_NOMATCH; } +int main(void) { struct local_stuff local_data; - curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/file*"); - curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); - curl_easy_setopt(curl, CURLOPT_FNMATCH_FUNCTION, my_fnmatch); - curl_easy_setopt(curl, CURLOPT_FNMATCH_DATA, &local_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/file*"); + curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); + curl_easy_setopt(curl, CURLOPT_FNMATCH_FUNCTION, my_fnmatch); + curl_easy_setopt(curl, CURLOPT_FNMATCH_DATA, &local_data); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.3 b/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.3 index f86e9655a..a78ea3305 100644 --- a/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.3 +++ b/docs/libcurl/opts/CURLOPT_FOLLOWLOCATION.3 @@ -68,14 +68,17 @@ would otherwise select internally. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* example.com is redirected, so we tell libcurl to follow redirection */ - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + /* example.com is redirected, so we tell libcurl to follow redirection */ + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FORBID_REUSE.3 b/docs/libcurl/opts/CURLOPT_FORBID_REUSE.3 index aa2948295..52d800d67 100644 --- a/docs/libcurl/opts/CURLOPT_FORBID_REUSE.3 +++ b/docs/libcurl/opts/CURLOPT_FORBID_REUSE.3 @@ -46,13 +46,19 @@ Set to 0 to have libcurl keep the connection open for possible later reuse Most .SH EXAMPLE .nf +int main(void) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L); - curl_easy_perform(curl); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1L); + curl_easy_perform(curl); - /* this second transfer may not reuse the same connection */ - curl_easy_perform(curl); + /* this second transfer may not reuse the same connection */ + curl_easy_perform(curl); + + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FRESH_CONNECT.3 b/docs/libcurl/opts/CURLOPT_FRESH_CONNECT.3 index f9e53ab62..00e4addf9 100644 --- a/docs/libcurl/opts/CURLOPT_FRESH_CONNECT.3 +++ b/docs/libcurl/opts/CURLOPT_FRESH_CONNECT.3 @@ -48,11 +48,16 @@ Set \fIfresh\fP to 0 to have libcurl attempt reusing an existing connection Most .SH EXAMPLE .nf +int main(void) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L); - /* this transfer must use a new connection, not reuse an existing */ - curl_easy_perform(curl); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1L); + /* this transfer must use a new connection, not reuse an existing */ + curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTPPORT.3 b/docs/libcurl/opts/CURLOPT_FTPPORT.3 index 9dff88526..ad7f2be53 100644 --- a/docs/libcurl/opts/CURLOPT_FTPPORT.3 +++ b/docs/libcurl/opts/CURLOPT_FTPPORT.3 @@ -78,12 +78,17 @@ NULL FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/old-server/file.txt"); - curl_easy_setopt(curl, CURLOPT_FTPPORT, "-"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/old-server/file.txt"); + curl_easy_setopt(curl, CURLOPT_FTPPORT, "-"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTPSSLAUTH.3 b/docs/libcurl/opts/CURLOPT_FTPSSLAUTH.3 index 35a233840..96b6e9d7f 100644 --- a/docs/libcurl/opts/CURLOPT_FTPSSLAUTH.3 +++ b/docs/libcurl/opts/CURLOPT_FTPSSLAUTH.3 @@ -49,14 +49,18 @@ CURLFTPAUTH_DEFAULT FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); - curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); - /* funny server, ask for SSL before TLS */ - curl_easy_setopt(curl, CURLOPT_FTPSSLAUTH, (long)CURLFTPAUTH_SSL); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); + /* funny server, ask for SSL before TLS */ + curl_easy_setopt(curl, CURLOPT_FTPSSLAUTH, (long)CURLFTPAUTH_SSL); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.3 b/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.3 index 545689d6a..0b0513c5c 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_ACCOUNT.3 @@ -44,15 +44,19 @@ NULL FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_FTP_ACCOUNT, "human-resources"); + curl_easy_setopt(curl, CURLOPT_FTP_ACCOUNT, "human-resources"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_ALTERNATIVE_TO_USER.3 b/docs/libcurl/opts/CURLOPT_FTP_ALTERNATIVE_TO_USER.3 index a0c684afd..d89a13ac6 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_ALTERNATIVE_TO_USER.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_ALTERNATIVE_TO_USER.3 @@ -45,15 +45,17 @@ NULL FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, "two users"); + res = curl_easy_perform(curl); - curl_easy_setopt(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER, "two users"); - - ret = curl_easy_perform(curl); - - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_CREATE_MISSING_DIRS.3 b/docs/libcurl/opts/CURLOPT_FTP_CREATE_MISSING_DIRS.3 index 1693eecb2..4d4142967 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_CREATE_MISSING_DIRS.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_CREATE_MISSING_DIRS.3 @@ -62,15 +62,20 @@ CURLFTP_CREATE_DIR_NONE (0) FTP and SFTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/non-existing/new.txt"); - curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, - (long)CURLFTP_CREATE_DIR_RETRY); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/non-existing/new.txt"); + curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, + (long)CURLFTP_CREATE_DIR_RETRY); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_FILEMETHOD.3 b/docs/libcurl/opts/CURLOPT_FTP_FILEMETHOD.3 index 14f0842f7..afd3a00da 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_FILEMETHOD.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_FILEMETHOD.3 @@ -57,15 +57,19 @@ CURLFTPMETHOD_MULTICWD FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/1/2/3/4/new.txt"); - curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, - (long)CURLFTPMETHOD_SINGLECWD); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/1/2/3/4/new.txt"); + curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, + (long)CURLFTPMETHOD_SINGLECWD); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 index 829b39b12..9b6453bdc 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 @@ -50,15 +50,19 @@ This option has no effect if PORT, EPRT or EPSV is used instead of PASV. FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); - /* please ignore the IP in the PASV response */ - curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, 1L); - ret = curl_easy_perform(curl); + /* please ignore the IP in the PASV response */ + curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, 1L); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_SSL_CCC.3 b/docs/libcurl/opts/CURLOPT_FTP_SSL_CCC.3 index c47b89842..a8d39881c 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_SSL_CCC.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_SSL_CCC.3 @@ -50,14 +50,18 @@ CURLFTPSSL_CCC_NONE FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); - curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_CONTROL); - /* go back to clear-text FTP after authenticating */ - curl_easy_setopt(curl, CURLOPT_FTP_SSL_CCC, (long)CURLFTPSSL_CCC_ACTIVE); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_CONTROL); + /* go back to clear-text FTP after authenticating */ + curl_easy_setopt(curl, CURLOPT_FTP_SSL_CCC, (long)CURLFTPSSL_CCC_ACTIVE); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_USE_EPRT.3 b/docs/libcurl/opts/CURLOPT_FTP_USE_EPRT.3 index 9753043db..8731bd6c5 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_USE_EPRT.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_USE_EPRT.3 @@ -50,19 +50,23 @@ then. .SH PROTOCOLS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); - /* contact us back, aka "active" FTP */ - curl_easy_setopt(curl, CURLOPT_FTPPORT, "-"); + /* contact us back, aka "active" FTP */ + curl_easy_setopt(curl, CURLOPT_FTPPORT, "-"); - /* FTP the way the neanderthals did it */ - curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, 0L); + /* FTP the way the neanderthals did it */ + curl_easy_setopt(curl, CURLOPT_FTP_USE_EPRT, 0L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_USE_EPSV.3 b/docs/libcurl/opts/CURLOPT_FTP_USE_EPSV.3 index 8c49874a2..af5d4ace9 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_USE_EPSV.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_USE_EPSV.3 @@ -50,16 +50,21 @@ If the server is an IPv6 host, this option has no effect. FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/old-server/file.txt"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/old-server/file.txt"); - /* let's shut off this modern feature */ - curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); + /* let's shut off this modern feature */ + curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_FTP_USE_PRET.3 b/docs/libcurl/opts/CURLOPT_FTP_USE_PRET.3 index 634250754..c4538bda8 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_USE_PRET.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_USE_PRET.3 @@ -42,16 +42,21 @@ no effect when using the active FTP transfers mode. FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/old-server/file.txt"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/old-server/file.txt"); - /* a drftpd server, do it! */ - curl_easy_setopt(curl, CURLOPT_FTP_USE_PRET, 1L); + /* a drftpd server, do it! */ + curl_easy_setopt(curl, CURLOPT_FTP_USE_PRET, 1L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_GSSAPI_DELEGATION.3 b/docs/libcurl/opts/CURLOPT_GSSAPI_DELEGATION.3 index 055e316c8..2a711b8fa 100644 --- a/docs/libcurl/opts/CURLOPT_GSSAPI_DELEGATION.3 +++ b/docs/libcurl/opts/CURLOPT_GSSAPI_DELEGATION.3 @@ -45,14 +45,17 @@ CURLGSSAPI_DELEGATION_NONE HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* delegate if okayed by policy */ - curl_easy_setopt(curl, CURLOPT_GSSAPI_DELEGATION, - (long)CURLGSSAPI_DELEGATION_POLICY_FLAG); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* delegate if okayed by policy */ + curl_easy_setopt(curl, CURLOPT_GSSAPI_DELEGATION, + (long)CURLGSSAPI_DELEGATION_POLICY_FLAG); + ret = curl_easy_perform(curl); + } } .fi diff --git a/docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 b/docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 index 2057fbe5c..5e3865f12 100644 --- a/docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 +++ b/docs/libcurl/opts/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 @@ -49,15 +49,18 @@ CURL_HET_DEFAULT (currently defined as 200L) All except FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, 300L); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, 300L); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* always cleanup */ - curl_easy_cleanup(curl); + /* always cleanup */ + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 b/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 index dab0a1f09..5c3b079d8 100644 --- a/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 +++ b/docs/libcurl/opts/CURLOPT_HAPROXYPROTOCOL.3 @@ -47,12 +47,15 @@ Most applications do not need this option. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.3 b/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.3 index 04d8621f5..a2c9b2ff4 100644 --- a/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.3 +++ b/docs/libcurl/opts/CURLOPT_HAPROXY_CLIENT_IP.3 @@ -45,12 +45,15 @@ NULL, no HAProxy header is sent HTTP, HAProxy PROTOCOL .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_HAPROXY_CLIENT_IP, "1.1.1.1"); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_HAPROXY_CLIENT_IP, "1.1.1.1"); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HEADER.3 b/docs/libcurl/opts/CURLOPT_HEADER.3 index 7decc88aa..193cdf1a5 100644 --- a/docs/libcurl/opts/CURLOPT_HEADER.3 +++ b/docs/libcurl/opts/CURLOPT_HEADER.3 @@ -57,13 +57,16 @@ custom HTTP headers! Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_HEADER, 1L); + curl_easy_setopt(curl, CURLOPT_HEADER, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HEADERDATA.3 b/docs/libcurl/opts/CURLOPT_HEADERDATA.3 index e040a6998..20e696e49 100644 --- a/docs/libcurl/opts/CURLOPT_HEADERDATA.3 +++ b/docs/libcurl/opts/CURLOPT_HEADERDATA.3 @@ -58,24 +58,27 @@ struct my_info { static size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) { - struct my_info *i = (struct my_info *)userdata; - + struct my_info *i = userdata; + printf("shoe size: %d\\n", i->shoesize); /* now this callback can access the my_info struct */ return nitems * size; } -CURL *curl = curl_easy_init(); -if(curl) { - struct my_info my = { 10, "the cookies are in the cupboard" }; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct my_info my = { 10, "the cookies are in the cupboard" }; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); - /* pass in custom data to the callback */ - curl_easy_setopt(curl, CURLOPT_HEADERDATA, &my); + /* pass in custom data to the callback */ + curl_easy_setopt(curl, CURLOPT_HEADERDATA, &my); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HEADERFUNCTION.3 b/docs/libcurl/opts/CURLOPT_HEADERFUNCTION.3 index 0b5ac28c1..03051b193 100644 --- a/docs/libcurl/opts/CURLOPT_HEADERFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_HEADERFUNCTION.3 @@ -110,13 +110,16 @@ static size_t header_callback(char *buffer, size_t size, return nitems * size; } -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HEADEROPT.3 b/docs/libcurl/opts/CURLOPT_HEADEROPT.3 index 085938f60..000f2035f 100644 --- a/docs/libcurl/opts/CURLOPT_HEADEROPT.3 +++ b/docs/libcurl/opts/CURLOPT_HEADEROPT.3 @@ -52,23 +52,26 @@ CURLHEADER_SEPARATE (changed in 7.42.1, used CURLHEADER_UNIFIED before then) HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - struct curl_slist *list; - list = curl_slist_append(NULL, "Shoesize: 10"); - list = curl_slist_append(list, "Accept:"); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + struct curl_slist *list; + list = curl_slist_append(NULL, "Shoesize: 10"); + list = curl_slist_append(list, "Accept:"); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); - /* HTTPS over a proxy makes a separate CONNECT to the proxy, so tell - libcurl to not send the custom headers to the proxy. Keep them - separate! */ - curl_easy_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE); - ret = curl_easy_perform(curl); - curl_slist_free_all(list); - curl_easy_cleanup(curl); + /* HTTPS over a proxy makes a separate CONNECT to the proxy, so tell + libcurl to not send the custom headers to the proxy. Keep them + separate! */ + curl_easy_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE); + ret = curl_easy_perform(curl); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HSTS.3 b/docs/libcurl/opts/CURLOPT_HSTS.3 index 6c3a39576..30d3f3753 100644 --- a/docs/libcurl/opts/CURLOPT_HSTS.3 +++ b/docs/libcurl/opts/CURLOPT_HSTS.3 @@ -64,10 +64,13 @@ NULL, no file name HTTPS and HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_HSTS, "/home/user/.hsts-cache"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_HSTS, "/home/user/.hsts-cache"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3 b/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3 index 26bead41d..3097fbda8 100644 --- a/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3 +++ b/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3 @@ -44,16 +44,23 @@ NULL This feature is only used for HTTP(S) transfer. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -struct MyData this; -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); +struct MyData { + void *custom; +}; - /* pass pointer that gets passed in to the - CURLOPT_HSTSREADFUNCTION callback */ - curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &this); +int main(void) +{ + CURL *curl = curl_easy_init(); + struct MyData this; + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); - curl_easy_perform(curl); + /* pass pointer that gets passed in to the + CURLOPT_HSTSREADFUNCTION callback */ + curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &this); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3 b/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3 index 3dc9244f7..9fcd04645 100644 --- a/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3 @@ -69,14 +69,32 @@ NULL - no callback. This feature is only used for HTTP(S) transfer. .SH EXAMPLE .nf +struct priv { + void *custom; +}; + +static CURLSTScode hsts_cb(CURL *easy, struct curl_hstsentry *sts, + void *clientp) +{ + /* populate the struct as documented */ + return CURLSTS_OK; +} + +int main(void) { - /* set HSTS read callback */ - curl_easy_setopt(curl, CURLOPT_HSTSREADFUNCTION, hstsread); + CURL *curl = curl_easy_init(); + if(curl) { + struct priv my_stuff; + CURLcode res; + + /* set HSTS read callback */ + curl_easy_setopt(curl, CURLOPT_HSTSREADFUNCTION, hsts_cb); - /* pass in suitable argument to the callback */ - curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &hstspreload[0]); + /* pass in suitable argument to the callback */ + curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &my_stuff); - result = curl_easy_perform(curl); + res = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3 b/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3 index aba5cb2cc..04b7d383e 100644 --- a/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3 +++ b/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3 @@ -44,16 +44,23 @@ NULL This feature is only used for HTTP(S) transfer. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -struct MyData this; -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); +struct MyData { + void *custom; +}; - /* pass pointer that gets passed in to the - CURLOPT_HSTSWRITEFUNCTION callback */ - curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &this); +int main(void) +{ + CURL *curl = curl_easy_init(); + struct MyData this; + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); - curl_easy_perform(curl); + /* pass pointer that gets passed in to the + CURLOPT_HSTSWRITEFUNCTION callback */ + curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &this); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3 b/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3 index f7b44faf7..e5b3a950b 100644 --- a/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3 @@ -73,14 +73,32 @@ NULL - no callback. This feature is only used for HTTP(S) transfer. .SH EXAMPLE .nf +struct priv { + void *custom; +}; + +static CURLSTScode hswr_cb(CURL *easy, struct curl_hstsentry *sts, + struct curl_index *count, void *clientp) +{ + /* save the passed in HSTS data somewhere */ + return CURLSTS_OK; +} + +int main(void) { - /* set HSTS read callback */ - curl_easy_setopt(curl, CURLOPT_HSTSWRITEFUNCTION, hstswrite); + CURL *curl = curl_easy_init(); + if(curl) { + struct priv my_stuff; + CURLcode res; + + /* set HSTS read callback */ + curl_easy_setopt(curl, CURLOPT_HSTSWRITEFUNCTION, hswr_cb); - /* pass in suitable argument to the callback */ - curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &hstspreload[0]); + /* pass in suitable argument to the callback */ + curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &my_stuff); - result = curl_easy_perform(curl); + res = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3 b/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3 index ebf336e5f..2747ccdd7 100644 --- a/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3 +++ b/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3 @@ -55,10 +55,13 @@ to the file when closing the handle. HTTPS and HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_HSTS_CTRL, (long)CURLHSTS_ENABLE); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_HSTS_CTRL, (long)CURLHSTS_ENABLE); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3 b/docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3 index da1cc7928..af8f26bae 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3 +++ b/docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3 @@ -46,12 +46,15 @@ responses. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_HTTP09_ALLOWED, 1L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_HTTP09_ALLOWED, 1L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.3 b/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.3 index 86554fcf7..05a0e3ac3 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.3 +++ b/docs/libcurl/opts/CURLOPT_HTTP200ALIASES.3 @@ -51,17 +51,20 @@ NULL HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_slist *list; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct curl_slist *list; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - list = curl_slist_append(NULL, "ICY 200 OK"); - list = curl_slist_append(list, "WEIRDO 99 FINE"); + list = curl_slist_append(NULL, "ICY 200 OK"); + list = curl_slist_append(list, "WEIRDO 99 FINE"); - curl_easy_setopt(curl, CURLOPT_HTTP200ALIASES, list); - curl_easy_perform(curl); - curl_slist_free_all(list); /* free the list again */ + curl_easy_setopt(curl, CURLOPT_HTTP200ALIASES, list); + curl_easy_perform(curl); + curl_slist_free_all(list); /* free the list again */ + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTPAUTH.3 b/docs/libcurl/opts/CURLOPT_HTTPAUTH.3 index f91c548f5..661f52942 100644 --- a/docs/libcurl/opts/CURLOPT_HTTPAUTH.3 +++ b/docs/libcurl/opts/CURLOPT_HTTPAUTH.3 @@ -108,14 +108,17 @@ CURLAUTH_BASIC HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* allow whatever auth the server speaks */ - curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); - curl_easy_setopt(curl, CURLOPT_USERPWD, "james:bond"); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* allow whatever auth the server speaks */ + curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); + curl_easy_setopt(curl, CURLOPT_USERPWD, "james:bond"); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTPGET.3 b/docs/libcurl/opts/CURLOPT_HTTPGET.3 index 25c3bd734..9a3af4d7c 100644 --- a/docs/libcurl/opts/CURLOPT_HTTPGET.3 +++ b/docs/libcurl/opts/CURLOPT_HTTPGET.3 @@ -48,15 +48,18 @@ reset a handle to default method, consider \fIcurl_easy_reset(3)\fP. HTTP(S) .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* use a GET to fetch this */ - curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); + /* use a GET to fetch this */ + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 index 05b028572..a750b9810 100644 --- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 +++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 @@ -55,7 +55,9 @@ semicolon). The headers included in the linked list \fBmust not\fP be CRLF-terminated, because libcurl adds CRLF after each header item itself. Failure to comply -with this might result in strange behavior. +with this might result in strange behavior. libcurl passes on the verbatim +strings you give it, without any filter or other safe guards. That includes +white space and control characters. The first line in an HTTP request (containing the method, usually a GET or POST) is not a header and cannot be replaced using this option. Only the lines @@ -100,7 +102,7 @@ MIME mail is only composed of alternative representations of the same data (i.e.: HTML and plain text), this header must be set to "multipart/alternative". In all cases the value must be of the form "multipart/*" to respect the document structure and may not include the "boundary=" parameter. -.P + Other specific headers that do not have a libcurl default value but are strongly desired by mail delivery and user agents should also be included. These are "From:", "To:", "Date:" and "Subject:" among others and their @@ -134,21 +136,24 @@ NULL HTTP, IMAP and SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); +int main(void) +{ + CURL *curl = curl_easy_init(); -struct curl_slist *list = NULL; + struct curl_slist *list = NULL; -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - list = curl_slist_append(list, "Shoesize: 10"); - list = curl_slist_append(list, "Accept:"); + list = curl_slist_append(list, "Shoesize: 10"); + list = curl_slist_append(list, "Accept:"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); - curl_easy_perform(curl); + curl_easy_perform(curl); - curl_slist_free_all(list); /* free the list */ + curl_slist_free_all(list); /* free the list */ + } } .fi diff --git a/docs/libcurl/opts/CURLOPT_HTTPPOST.3 b/docs/libcurl/opts/CURLOPT_HTTPPOST.3 index 0cdef31ab..f86db4ee7 100644 --- a/docs/libcurl/opts/CURLOPT_HTTPPOST.3 +++ b/docs/libcurl/opts/CURLOPT_HTTPPOST.3 @@ -52,27 +52,41 @@ NULL HTTP .SH EXAMPLE .nf -/* Fill in the file upload field. This makes libcurl load data from - the given file name when curl_easy_perform() is called. */ -curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "sendfile", - CURLFORM_FILE, "postit2.c", - CURLFORM_END); +int main(void) +{ + struct curl_httppost *formpost; + struct curl_httppost *lastptr; -/* Fill in the filename field */ -curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "filename", - CURLFORM_COPYCONTENTS, "postit2.c", - CURLFORM_END); + /* Fill in the file upload field. This makes libcurl load data from + the given file name when curl_easy_perform() is called. */ + curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "sendfile", + CURLFORM_FILE, "postit2.c", + CURLFORM_END); -/* Fill in the submit field too, even if this is rarely needed */ -curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "submit", - CURLFORM_COPYCONTENTS, "send", - CURLFORM_END); + /* Fill in the filename field */ + curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "filename", + CURLFORM_COPYCONTENTS, "postit2.c", + CURLFORM_END); + + /* Fill in the submit field too, even if this is rarely needed */ + curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "submit", + CURLFORM_COPYCONTENTS, "send", + CURLFORM_END); + + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + curl_easy_perform(curl); + curl_easy_cleanup(curl); + } + curl_formfree(formpost); +} .fi .SH AVAILABILITY As long as HTTP is enabled. Deprecated in 7.56.0. diff --git a/docs/libcurl/opts/CURLOPT_HTTPPROXYTUNNEL.3 b/docs/libcurl/opts/CURLOPT_HTTPPROXYTUNNEL.3 index 63ad09adc..542eefe6c 100644 --- a/docs/libcurl/opts/CURLOPT_HTTPPROXYTUNNEL.3 +++ b/docs/libcurl/opts/CURLOPT_HTTPPROXYTUNNEL.3 @@ -56,12 +56,15 @@ rarely works through the proxy anyway). All network protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1:80"); - curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/file.txt"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1:80"); + curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTP_CONTENT_DECODING.3 b/docs/libcurl/opts/CURLOPT_HTTP_CONTENT_DECODING.3 index ab1fdd9fc..7d6dabee3 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP_CONTENT_DECODING.3 +++ b/docs/libcurl/opts/CURLOPT_HTTP_CONTENT_DECODING.3 @@ -42,12 +42,15 @@ default content decoding but requires you to use HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 0L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 0L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTP_TRANSFER_DECODING.3 b/docs/libcurl/opts/CURLOPT_HTTP_TRANSFER_DECODING.3 index 2aa0185d8..a00fb1a1d 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP_TRANSFER_DECODING.3 +++ b/docs/libcurl/opts/CURLOPT_HTTP_TRANSFER_DECODING.3 @@ -41,12 +41,15 @@ does chunked transfer decoding by default unless this option is set to zero. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_HTTP_TRANSFER_DECODING, 0L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_HTTP_TRANSFER_DECODING, 0L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_HTTP_VERSION.3 b/docs/libcurl/opts/CURLOPT_HTTP_VERSION.3 index bbccda304..87b133b88 100644 --- a/docs/libcurl/opts/CURLOPT_HTTP_VERSION.3 +++ b/docs/libcurl/opts/CURLOPT_HTTP_VERSION.3 @@ -80,15 +80,18 @@ Before that: CURL_HTTP_VERSION_1_1 HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, - (long)CURL_HTTP_VERSION_2TLS); - ret = curl_easy_perform(curl); - if(ret == CURLE_HTTP_RETURNED_ERROR) { - /* an HTTP response error problem */ +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, + (long)CURL_HTTP_VERSION_2TLS); + ret = curl_easy_perform(curl); + if(ret == CURLE_HTTP_RETURNED_ERROR) { + /* an HTTP response error problem */ + } } } .fi diff --git a/docs/libcurl/opts/CURLOPT_IGNORE_CONTENT_LENGTH.3 b/docs/libcurl/opts/CURLOPT_IGNORE_CONTENT_LENGTH.3 index c6364b43b..2512b665f 100644 --- a/docs/libcurl/opts/CURLOPT_IGNORE_CONTENT_LENGTH.3 +++ b/docs/libcurl/opts/CURLOPT_IGNORE_CONTENT_LENGTH.3 @@ -51,14 +51,17 @@ Only use this option if strictly necessary. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* we know the server is silly, ignore content-length */ - curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L); + /* we know the server is silly, ignore content-length */ + curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_INFILESIZE.3 b/docs/libcurl/opts/CURLOPT_INFILESIZE.3 index 9661c0256..a26e46302 100644 --- a/docs/libcurl/opts/CURLOPT_INFILESIZE.3 +++ b/docs/libcurl/opts/CURLOPT_INFILESIZE.3 @@ -57,17 +57,24 @@ Unset Many .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - long uploadsize = FILE_SIZE; - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/destination.tar.gz"); +#define FILE_SIZE 12345L - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + long uploadsize = FILE_SIZE; - curl_easy_setopt(curl, CURLOPT_INFILESIZE, uploadsize); + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/destination.tar.gz"); - curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + curl_easy_setopt(curl, CURLOPT_INFILESIZE, uploadsize); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_INFILESIZE_LARGE.3 b/docs/libcurl/opts/CURLOPT_INFILESIZE_LARGE.3 index fedd9438b..5cac91089 100644 --- a/docs/libcurl/opts/CURLOPT_INFILESIZE_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_INFILESIZE_LARGE.3 @@ -53,17 +53,23 @@ Unset Many .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_off_t uploadsize = FILE_SIZE; +#define FILE_SIZE 123456 - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/destination.tar.gz"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_off_t uploadsize = FILE_SIZE; - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/destination.tar.gz"); - curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadsize); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadsize); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_INTERFACE.3 b/docs/libcurl/opts/CURLOPT_INTERFACE.3 index 921a682a0..676f8ba7c 100644 --- a/docs/libcurl/opts/CURLOPT_INTERFACE.3 +++ b/docs/libcurl/opts/CURLOPT_INTERFACE.3 @@ -60,15 +60,19 @@ NULL, use whatever the TCP stack finds suitable All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_INTERFACE, "eth0"); + curl_easy_setopt(curl, CURLOPT_INTERFACE, "eth0"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_INTERLEAVEDATA.3 b/docs/libcurl/opts/CURLOPT_INTERLEAVEDATA.3 index b5a6caaaf..adc54f694 100644 --- a/docs/libcurl/opts/CURLOPT_INTERLEAVEDATA.3 +++ b/docs/libcurl/opts/CURLOPT_INTERLEAVEDATA.3 @@ -42,16 +42,27 @@ NULL RTSP .SH EXAMPLE .nf -static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *user) +struct local { + void *custom; +}; +static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *userp) { - struct local *l = (struct local *)user; + struct local *l = userp; + printf("my pointer: %p\\n", l->custom); /* take care of the packet in 'ptr', then return... */ return size * nmemb; } + +int main(void) { struct local rtp_data; - curl_easy_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write); - curl_easy_setopt(curl, CURLOPT_INTERLEAVEDATA, &rtp_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write); + curl_easy_setopt(curl, CURLOPT_INTERLEAVEDATA, &rtp_data); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_INTERLEAVEFUNCTION.3 b/docs/libcurl/opts/CURLOPT_INTERLEAVEFUNCTION.3 index a117c8821..b2fa947dd 100644 --- a/docs/libcurl/opts/CURLOPT_INTERLEAVEFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_INTERLEAVEFUNCTION.3 @@ -72,16 +72,26 @@ NULL, the interleave data is then passed to the regular write function: RTSP .SH EXAMPLE .nf -static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *user) +struct local { + void *custom; +}; + +static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *userp) { - struct local *l = (struct local *)user; + struct local *l = userp; + printf("our ptr: %p\\n", l->custom); /* take care of the packet in 'ptr', then return... */ return size * nmemb; } + +int main(void) { struct local rtp_data; - curl_easy_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write); - curl_easy_setopt(curl, CURLOPT_INTERLEAVEDATA, &rtp_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write); + curl_easy_setopt(curl, CURLOPT_INTERLEAVEDATA, &rtp_data); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_IOCTLDATA.3 b/docs/libcurl/opts/CURLOPT_IOCTLDATA.3 index 41de13c9b..93742c75e 100644 --- a/docs/libcurl/opts/CURLOPT_IOCTLDATA.3 +++ b/docs/libcurl/opts/CURLOPT_IOCTLDATA.3 @@ -40,20 +40,29 @@ By default, the value of this parameter is NULL. Used with HTTP .SH EXAMPLE .nf +#include /* for lseek */ + +struct data { + int fd; /* our file descriptor */ +}; + static curlioerr ioctl_callback(CURL *handle, int cmd, void *clientp) { struct data *io = (struct data *)clientp; if(cmd == CURLIOCMD_RESTARTREAD) { - lseek(fd, 0, SEEK_SET); - current_offset = 0; + lseek(io->fd, 0, SEEK_SET); return CURLIOE_OK; } return CURLIOE_UNKNOWNCMD; } +int main(void) { struct data ioctl_data; - curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback); - curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &ioctl_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback); + curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &ioctl_data); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_IOCTLFUNCTION.3 b/docs/libcurl/opts/CURLOPT_IOCTLFUNCTION.3 index 5eb2a17c6..981051472 100644 --- a/docs/libcurl/opts/CURLOPT_IOCTLFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_IOCTLFUNCTION.3 @@ -70,20 +70,29 @@ By default, this parameter is set to NULL. Not used. Used with HTTP .SH EXAMPLE .nf +#include /* for lseek */ + +struct data { + int fd; /* our file descriptor */ +}; + static curlioerr ioctl_callback(CURL *handle, int cmd, void *clientp) { struct data *io = (struct data *)clientp; if(cmd == CURLIOCMD_RESTARTREAD) { - lseek(fd, 0, SEEK_SET); - current_offset = 0; + lseek(io->fd, 0, SEEK_SET); return CURLIOE_OK; } return CURLIOE_UNKNOWNCMD; } +int main(void) { struct data ioctl_data; - curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback); - curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &ioctl_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback); + curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &ioctl_data); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_IPRESOLVE.3 b/docs/libcurl/opts/CURLOPT_IPRESOLVE.3 index c5970686f..499aed513 100644 --- a/docs/libcurl/opts/CURLOPT_IPRESOLVE.3 +++ b/docs/libcurl/opts/CURLOPT_IPRESOLVE.3 @@ -53,19 +53,22 @@ CURL_IPRESOLVE_WHATEVER All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - /* of all addresses example.com resolves to, only IPv6 ones are used */ - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + /* of all addresses example.com resolves to, only IPv6 ones are used */ + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi - .SH AVAILABILITY Always .SH RETURN VALUE diff --git a/docs/libcurl/opts/CURLOPT_ISSUERCERT.3 b/docs/libcurl/opts/CURLOPT_ISSUERCERT.3 index 9ac3d2eef..a0c2f5f79 100644 --- a/docs/libcurl/opts/CURLOPT_ISSUERCERT.3 +++ b/docs/libcurl/opts/CURLOPT_ISSUERCERT.3 @@ -56,12 +56,16 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_ISSUERCERT, "/etc/certs/cacert.pem"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_ISSUERCERT, "/etc/certs/cacert.pem"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_ISSUERCERT_BLOB.3 b/docs/libcurl/opts/CURLOPT_ISSUERCERT_BLOB.3 index f9b56057c..858987e9b 100644 --- a/docs/libcurl/opts/CURLOPT_ISSUERCERT_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_ISSUERCERT_BLOB.3 @@ -62,16 +62,24 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - blob.data = certificateData; - blob.len = filesize; - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_ISSUERCERT_BLOB, &blob); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); + +extern char *certificateData; +extern size_t filesize; + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + blob.data = certificateData; + blob.len = filesize; + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_ISSUERCERT_BLOB, &blob); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 b/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 index b25af4679..466436095 100644 --- a/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 +++ b/docs/libcurl/opts/CURLOPT_KEEP_SENDING_ON_ERROR.3 @@ -48,13 +48,16 @@ Most applications do not need this option. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "sending data"); - curl_easy_setopt(curl, CURLOPT_KEEP_SENDING_ON_ERROR, 1L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "sending data"); + curl_easy_setopt(curl, CURLOPT_KEEP_SENDING_ON_ERROR, 1L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_KEYPASSWD.3 b/docs/libcurl/opts/CURLOPT_KEYPASSWD.3 index 4d69a3c88..119f26cd1 100644 --- a/docs/libcurl/opts/CURLOPT_KEYPASSWD.3 +++ b/docs/libcurl/opts/CURLOPT_KEYPASSWD.3 @@ -45,14 +45,18 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "superman"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "superman"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_KRBLEVEL.3 b/docs/libcurl/opts/CURLOPT_KRBLEVEL.3 index 9a1f4ae92..7be711e1d 100644 --- a/docs/libcurl/opts/CURLOPT_KRBLEVEL.3 +++ b/docs/libcurl/opts/CURLOPT_KRBLEVEL.3 @@ -46,12 +46,16 @@ NULL FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_KRBLEVEL, "private"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_KRBLEVEL, "private"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_LOCALPORT.3 b/docs/libcurl/opts/CURLOPT_LOCALPORT.3 index 267a1c87a..e5bddf1c1 100644 --- a/docs/libcurl/opts/CURLOPT_LOCALPORT.3 +++ b/docs/libcurl/opts/CURLOPT_LOCALPORT.3 @@ -42,14 +42,18 @@ this option is set. Valid port numbers are 1 - 65535. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_LOCALPORT, 49152L); - /* and try 20 more ports following that */ - curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 20L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_LOCALPORT, 49152L); + /* and try 20 more ports following that */ + curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 20L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_LOCALPORTRANGE.3 b/docs/libcurl/opts/CURLOPT_LOCALPORTRANGE.3 index 1e54f43ed..71934e323 100644 --- a/docs/libcurl/opts/CURLOPT_LOCALPORTRANGE.3 +++ b/docs/libcurl/opts/CURLOPT_LOCALPORTRANGE.3 @@ -46,14 +46,18 @@ setup failures. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_LOCALPORT, 49152L); - /* and try 20 more ports following that */ - curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 20L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_LOCALPORT, 49152L); + /* and try 20 more ports following that */ + curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 20L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.3 index aacf18695..5410bbdce 100644 --- a/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_LOGIN_OPTIONS.3 @@ -57,12 +57,16 @@ NULL Only IMAP, LDAP, POP3 and SMTP support login options. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); - curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=*"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); + curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=*"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_LOW_SPEED_LIMIT.3 b/docs/libcurl/opts/CURLOPT_LOW_SPEED_LIMIT.3 index a28ec6bc3..d491e655b 100644 --- a/docs/libcurl/opts/CURLOPT_LOW_SPEED_LIMIT.3 +++ b/docs/libcurl/opts/CURLOPT_LOW_SPEED_LIMIT.3 @@ -43,18 +43,22 @@ slow and abort. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, url); - /* abort if slower than 30 bytes/sec during 60 seconds */ - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60L); - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 30L); - res = curl_easy_perform(curl); - if(CURLE_OPERATION_TIMEDOUT == res) { - printf("Timeout!\\n"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + /* abort if slower than 30 bytes/sec during 60 seconds */ + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60L); + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 30L); + res = curl_easy_perform(curl); + if(CURLE_OPERATION_TIMEDOUT == res) { + printf("Timeout!\\n"); + } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_LOW_SPEED_TIME.3 b/docs/libcurl/opts/CURLOPT_LOW_SPEED_TIME.3 index 013cc916d..507ac4528 100644 --- a/docs/libcurl/opts/CURLOPT_LOW_SPEED_TIME.3 +++ b/docs/libcurl/opts/CURLOPT_LOW_SPEED_TIME.3 @@ -42,18 +42,22 @@ library to consider it too slow and abort. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, url); - /* abort if slower than 30 bytes/sec during 60 seconds */ - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60L); - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 30L); - res = curl_easy_perform(curl); - if(CURLE_OPERATION_TIMEDOUT == res) { - printf("Timeout!\\n"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + /* abort if slower than 30 bytes/sec during 60 seconds */ + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60L); + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 30L); + res = curl_easy_perform(curl); + if(CURLE_OPERATION_TIMEDOUT == res) { + printf("Timeout!\\n"); + } + /* always cleanup */ + curl_easy_cleanup(curl); } - /* always cleanup */ - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAIL_AUTH.3 b/docs/libcurl/opts/CURLOPT_MAIL_AUTH.3 index 403c1b6b7..340d801d8 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_AUTH.3 +++ b/docs/libcurl/opts/CURLOPT_MAIL_AUTH.3 @@ -56,12 +56,16 @@ NULL SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); - curl_easy_setopt(curl, CURLOPT_MAIL_AUTH, ""); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); + curl_easy_setopt(curl, CURLOPT_MAIL_AUTH, ""); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAIL_FROM.3 b/docs/libcurl/opts/CURLOPT_MAIL_FROM.3 index b0b130ea8..b76455c61 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_FROM.3 +++ b/docs/libcurl/opts/CURLOPT_MAIL_FROM.3 @@ -49,12 +49,16 @@ blank SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); - curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "president@example.com"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); + curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "president@example.com"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAIL_RCPT.3 b/docs/libcurl/opts/CURLOPT_MAIL_RCPT.3 index 60a68dc04..5a47e3d9a 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_RCPT.3 +++ b/docs/libcurl/opts/CURLOPT_MAIL_RCPT.3 @@ -56,16 +56,20 @@ NULL SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_slist *list; - list = curl_slist_append(NULL, "root@localhost"); - list = curl_slist_append(list, "person@example.com"); - curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); - curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, list); - ret = curl_easy_perform(curl); - curl_slist_free_all(list); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_slist *list; + list = curl_slist_append(NULL, "root@localhost"); + list = curl_slist_append(list, "person@example.com"); + curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); + curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, list); + res = curl_easy_perform(curl); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAIL_RCPT_ALLOWFAILS.3 b/docs/libcurl/opts/CURLOPT_MAIL_RCPT_ALLOWFAILS.3 index 8d8c9c7bb..bef151485 100644 --- a/docs/libcurl/opts/CURLOPT_MAIL_RCPT_ALLOWFAILS.3 +++ b/docs/libcurl/opts/CURLOPT_MAIL_RCPT_ALLOWFAILS.3 @@ -51,20 +51,24 @@ RCPT TO command. SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_slist *list; +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct curl_slist *list; + CURLcode res; - /* Adding one valid and one invalid email address */ - list = curl_slist_append(NULL, "person@example.com"); - list = curl_slist_append(list, "invalidemailaddress"); + /* Adding one valid and one invalid email address */ + list = curl_slist_append(NULL, "person@example.com"); + list = curl_slist_append(list, "invalidemailaddress"); - curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); - curl_easy_setopt(curl, CURLOPT_MAIL_RCPT_ALLOWFAILS, 1L); + curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); + curl_easy_setopt(curl, CURLOPT_MAIL_RCPT_ALLOWFAILS, 1L); - ret = curl_easy_perform(curl); - curl_slist_free_all(list); - curl_easy_cleanup(curl); + res = curl_easy_perform(curl); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAXAGE_CONN.3 b/docs/libcurl/opts/CURLOPT_MAXAGE_CONN.3 index acfab2d78..652792857 100644 --- a/docs/libcurl/opts/CURLOPT_MAXAGE_CONN.3 +++ b/docs/libcurl/opts/CURLOPT_MAXAGE_CONN.3 @@ -49,14 +49,17 @@ Default maximum age is set to 118 seconds. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* only allow 30 seconds idle time */ - curl_easy_setopt(curl, CURLOPT_MAXAGE_CONN, 30L); + /* only allow 30 seconds idle time */ + curl_easy_setopt(curl, CURLOPT_MAXAGE_CONN, 30L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAXCONNECTS.3 b/docs/libcurl/opts/CURLOPT_MAXCONNECTS.3 index eb09ff8fb..bb1c40398 100644 --- a/docs/libcurl/opts/CURLOPT_MAXCONNECTS.3 +++ b/docs/libcurl/opts/CURLOPT_MAXCONNECTS.3 @@ -54,13 +54,16 @@ acknowledged, and you must instead use \fIcurl_multi_setopt(3)\fP and the Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* limit the connection cache for this handle to no more than 3 */ - curl_easy_setopt(curl, CURLOPT_MAXCONNECTS, 3L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* limit the connection cache for this handle to no more than 3 */ + curl_easy_setopt(curl, CURLOPT_MAXCONNECTS, 3L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAXFILESIZE.3 b/docs/libcurl/opts/CURLOPT_MAXFILESIZE.3 index 88f4d61a7..ed970b29e 100644 --- a/docs/libcurl/opts/CURLOPT_MAXFILESIZE.3 +++ b/docs/libcurl/opts/CURLOPT_MAXFILESIZE.3 @@ -50,13 +50,16 @@ None FTP, HTTP and MQTT .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* refuse to download if larger than 1000 bytes! */ - curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 1000L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* refuse to download if larger than 1000 bytes! */ + curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 1000L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAXFILESIZE_LARGE.3 b/docs/libcurl/opts/CURLOPT_MAXFILESIZE_LARGE.3 index 79dadafc5..209701c4e 100644 --- a/docs/libcurl/opts/CURLOPT_MAXFILESIZE_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_MAXFILESIZE_LARGE.3 @@ -49,14 +49,17 @@ None FTP, HTTP and MQTT .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_off_t ridiculous = 1 << 48; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* refuse to download if larger than ridiculous */ - curl_easy_setopt(curl, CURLOPT_MAXFILESIZE_LARGE, ridiculous); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_off_t ridiculous = (curl_off_t)1 << 48; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* refuse to download if larger than ridiculous */ + curl_easy_setopt(curl, CURLOPT_MAXFILESIZE_LARGE, ridiculous); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAXLIFETIME_CONN.3 b/docs/libcurl/opts/CURLOPT_MAXLIFETIME_CONN.3 index 8cbf5e922..c3ec8aab9 100644 --- a/docs/libcurl/opts/CURLOPT_MAXLIFETIME_CONN.3 +++ b/docs/libcurl/opts/CURLOPT_MAXLIFETIME_CONN.3 @@ -51,14 +51,17 @@ Default \fImaxlifetime\fP is 0 seconds (i.e., disabled). All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* only allow each connection to be reused for 30 seconds */ - curl_easy_setopt(curl, CURLOPT_MAXLIFETIME_CONN, 30L); + /* only allow each connection to be reused for 30 seconds */ + curl_easy_setopt(curl, CURLOPT_MAXLIFETIME_CONN, 30L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAXREDIRS.3 b/docs/libcurl/opts/CURLOPT_MAXREDIRS.3 index 38a4e3fed..763425a07 100644 --- a/docs/libcurl/opts/CURLOPT_MAXREDIRS.3 +++ b/docs/libcurl/opts/CURLOPT_MAXREDIRS.3 @@ -47,18 +47,21 @@ to get stuck in never-ending redirect loops. HTTP(S) .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* enable redirect following */ - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + /* enable redirect following */ + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - /* allow three redirects */ - curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L); + /* allow three redirects */ + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 b/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 index 0fdad4ba3..9f0a5ac92 100644 --- a/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_MAX_RECV_SPEED_LARGE.3 @@ -49,13 +49,16 @@ This option does not affect transfer speeds done with FILE:// URLs. All but file:// .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* cap the download speed to 31415 bytes/sec */ - curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t)31415); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* cap the download speed to 31415 bytes/sec */ + curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t)31415); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 b/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 index 57ef15059..364baed31 100644 --- a/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_MAX_SEND_SPEED_LARGE.3 @@ -51,14 +51,17 @@ This option does not affect transfer speeds done with FILE:// URLs. All except file:// .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* cap the upload speed to 1000 bytes/sec */ - curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t)1000); - /* (set some upload options as well!) */ - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* cap the upload speed to 1000 bytes/sec */ + curl_easy_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE, (curl_off_t)1000); + /* (set some upload options as well!) */ + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_MIMEPOST.3 b/docs/libcurl/opts/CURLOPT_MIMEPOST.3 index a5fb508a9..02a5a0a7f 100644 --- a/docs/libcurl/opts/CURLOPT_MIMEPOST.3 +++ b/docs/libcurl/opts/CURLOPT_MIMEPOST.3 @@ -48,23 +48,30 @@ is reset to GET. Instead you should set a desired request method explicitly. HTTP, SMTP, IMAP. .SH EXAMPLE .nf - curl_mime *multipart = curl_mime_init(handle); - curl_mimepart *part = curl_mime_addpart(multipart); - curl_mime_name(part, "name"); - curl_mime_data(part, "daniel", CURL_ZERO_TERMINATED); - part = curl_mime_addpart(multipart); - curl_mime_name(part, "project"); - curl_mime_data(part, "curl", CURL_ZERO_TERMINATED); - part = curl_mime_addpart(multipart); - curl_mime_name(part, "logotype-image"); - curl_mime_filedata(part, "curl.png"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_mime *multipart = curl_mime_init(curl); + if(multipart) { + curl_mimepart *part = curl_mime_addpart(multipart); + curl_mime_name(part, "name"); + curl_mime_data(part, "daniel", CURL_ZERO_TERMINATED); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "project"); + curl_mime_data(part, "curl", CURL_ZERO_TERMINATED); + part = curl_mime_addpart(multipart); + curl_mime_name(part, "logotype-image"); + curl_mime_filedata(part, "curl.png"); - /* Set the form info */ - curl_easy_setopt(handle, CURLOPT_MIMEPOST, multipart); + /* Set the form info */ + curl_easy_setopt(curl, CURLOPT_MIMEPOST, multipart); - curl_easy_perform(handle); /* post away! */ - - curl_mime_free(multipart); /* free the post data */ + curl_easy_perform(curl); /* post away! */ + curl_mime_free(multipart); /* free the post data */ + } + } +} .fi .SH AVAILABILITY Added in 7.56.0 diff --git a/docs/libcurl/opts/CURLOPT_MIME_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_MIME_OPTIONS.3 index bcef3c5c8..3f7282351 100644 --- a/docs/libcurl/opts/CURLOPT_MIME_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_MIME_OPTIONS.3 @@ -60,29 +60,32 @@ When the containing multipart form is sent, this is normally transmitted as HTTP, IMAP, SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -curl_mime *form = NULL; +int main(void) +{ + CURL *curl = curl_easy_init(); + curl_mime *form = NULL; -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_MIME_OPTIONS, CURLMIMEOPT_FORMESCAPE); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_MIME_OPTIONS, CURLMIMEOPT_FORMESCAPE); - form = curl_mime_init(curl); - if(form) { - curl_mimepart *part = curl_mime_addpart(form); + form = curl_mime_init(curl); + if(form) { + curl_mimepart *part = curl_mime_addpart(form); - if(part) { - curl_mime_filedata(part, "strange\\\\file\\\\name"); - curl_mime_name(part, "strange\\"field\\"name"); - curl_easy_setopt(curl, CURLOPT_MIMEPOST, form); + if(part) { + curl_mime_filedata(part, "strange\\\\file\\\\name"); + curl_mime_name(part, "strange\\"field\\"name"); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, form); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } - } - curl_easy_cleanup(curl); - curl_mime_free(mime); + curl_easy_cleanup(curl); + curl_mime_free(form); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NETRC.3 b/docs/libcurl/opts/CURLOPT_NETRC.3 index b9809de8b..3f04fccf7 100644 --- a/docs/libcurl/opts/CURLOPT_NETRC.3 +++ b/docs/libcurl/opts/CURLOPT_NETRC.3 @@ -105,12 +105,15 @@ CURL_NETRC_IGNORED Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/"); - curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/"); + curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NETRC_FILE.3 b/docs/libcurl/opts/CURLOPT_NETRC_FILE.3 index e960813d8..ff0bb5050 100644 --- a/docs/libcurl/opts/CURLOPT_NETRC_FILE.3 +++ b/docs/libcurl/opts/CURLOPT_NETRC_FILE.3 @@ -45,13 +45,16 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/"); - curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); - curl_easy_setopt(curl, CURLOPT_NETRC_FILE, "/tmp/magic-netrc"); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/"); + curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); + curl_easy_setopt(curl, CURLOPT_NETRC_FILE, "/tmp/magic-netrc"); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NEW_DIRECTORY_PERMS.3 b/docs/libcurl/opts/CURLOPT_NEW_DIRECTORY_PERMS.3 index ac2141fc7..97282225a 100644 --- a/docs/libcurl/opts/CURLOPT_NEW_DIRECTORY_PERMS.3 +++ b/docs/libcurl/opts/CURLOPT_NEW_DIRECTORY_PERMS.3 @@ -42,13 +42,17 @@ this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP. SFTP, SCP and FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "sftp://upload.example.com/newdir/file.zip"); - curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); - curl_easy_setopt(curl, CURLOPT_NEW_DIRECTORY_PERMS, 0644L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, + "sftp://upload.example.com/newdir/file.zip"); + curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); + curl_easy_setopt(curl, CURLOPT_NEW_DIRECTORY_PERMS, 0644L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NEW_FILE_PERMS.3 b/docs/libcurl/opts/CURLOPT_NEW_FILE_PERMS.3 index 07de59dca..b81041d16 100644 --- a/docs/libcurl/opts/CURLOPT_NEW_FILE_PERMS.3 +++ b/docs/libcurl/opts/CURLOPT_NEW_FILE_PERMS.3 @@ -42,12 +42,15 @@ this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP. SFTP, SCP and FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "sftp://upload.example.com/file.txt"); - curl_easy_setopt(curl, CURLOPT_NEW_FILE_PERMS, 0664L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://upload.example.com/file.txt"); + curl_easy_setopt(curl, CURLOPT_NEW_FILE_PERMS, 0664L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NOBODY.3 b/docs/libcurl/opts/CURLOPT_NOBODY.3 index 971b9c7e1..a21a825a3 100644 --- a/docs/libcurl/opts/CURLOPT_NOBODY.3 +++ b/docs/libcurl/opts/CURLOPT_NOBODY.3 @@ -54,15 +54,18 @@ URL you request). Most .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* get us the resource without a body - use HEAD! */ - curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); + /* get us the resource without a body - use HEAD! */ + curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NOPROGRESS.3 b/docs/libcurl/opts/CURLOPT_NOPROGRESS.3 index 91b20c2b9..fd4e07f32 100644 --- a/docs/libcurl/opts/CURLOPT_NOPROGRESS.3 +++ b/docs/libcurl/opts/CURLOPT_NOPROGRESS.3 @@ -42,15 +42,18 @@ getting called. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* enable progress meter */ - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); + /* enable progress meter */ + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NOPROXY.3 b/docs/libcurl/opts/CURLOPT_NOPROXY.3 index dd76e78ab..1a5b07570 100644 --- a/docs/libcurl/opts/CURLOPT_NOPROXY.3 +++ b/docs/libcurl/opts/CURLOPT_NOPROXY.3 @@ -66,15 +66,18 @@ NULL Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - /* accept various URLs */ - curl_easy_setopt(curl, CURLOPT_URL, input); - /* use this proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80"); - /* ... but make sure this host name is not proxied */ - curl_easy_setopt(curl, CURLOPT_NOPROXY, "www.example.com"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* accept various URLs */ + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* use this proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80"); + /* ... but make sure this host name is not proxied */ + curl_easy_setopt(curl, CURLOPT_NOPROXY, "www.example.com"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_NOSIGNAL.3 b/docs/libcurl/opts/CURLOPT_NOSIGNAL.3 index 2ab15c2b6..290f44e42 100644 --- a/docs/libcurl/opts/CURLOPT_NOSIGNAL.3 +++ b/docs/libcurl/opts/CURLOPT_NOSIGNAL.3 @@ -57,15 +57,19 @@ raised. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_OPENSOCKETDATA.3 b/docs/libcurl/opts/CURLOPT_OPENSOCKETDATA.3 index 816941136..e4c227a89 100644 --- a/docs/libcurl/opts/CURLOPT_OPENSOCKETDATA.3 +++ b/docs/libcurl/opts/CURLOPT_OPENSOCKETDATA.3 @@ -61,21 +61,27 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, return CURL_SOCKOPT_ALREADY_CONNECTED; } -curl = curl_easy_init(); -if(curl) { - /* libcurl thinks that you connect to the host - * and port that you specify in the URL option. */ - curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); - /* call this function to get a socket */ - curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); - curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + extern int sockfd; /* the already connected one */ + + /* libcurl thinks that you connect to the host + * and port that you specify in the URL option. */ + curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); + /* call this function to get a socket */ + curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); + curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); - /* call this function to set options for the socket */ - curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + /* call this function to set options for the socket */ + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_OPENSOCKETFUNCTION.3 b/docs/libcurl/opts/CURLOPT_OPENSOCKETFUNCTION.3 index 86c122404..f2f8628b4 100644 --- a/docs/libcurl/opts/CURLOPT_OPENSOCKETFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_OPENSOCKETFUNCTION.3 @@ -101,21 +101,26 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, return CURL_SOCKOPT_ALREADY_CONNECTED; } -curl = curl_easy_init(); -if(curl) { - /* libcurl thinks that you connect to the host - * and port that you specify in the URL option. */ - curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); - /* call this function to get a socket */ - curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); - curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + extern int sockfd; /* the already connected one */ + /* libcurl thinks that you connect to the host + * and port that you specify in the URL option. */ + curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); + /* call this function to get a socket */ + curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); + curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); - /* call this function to set options for the socket */ - curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + /* call this function to set options for the socket */ + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PASSWORD.3 b/docs/libcurl/opts/CURLOPT_PASSWORD.3 index 3816f78a7..73d8627c0 100644 --- a/docs/libcurl/opts/CURLOPT_PASSWORD.3 +++ b/docs/libcurl/opts/CURLOPT_PASSWORD.3 @@ -46,15 +46,19 @@ blank Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PASSWORD, "qwerty"); + curl_easy_setopt(curl, CURLOPT_PASSWORD, "qwerty"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PATH_AS_IS.3 b/docs/libcurl/opts/CURLOPT_PATH_AS_IS.3 index 8ffa1d855..5bfa0ccdc 100644 --- a/docs/libcurl/opts/CURLOPT_PATH_AS_IS.3 +++ b/docs/libcurl/opts/CURLOPT_PATH_AS_IS.3 @@ -53,13 +53,17 @@ The corresponding flag for the \fIcurl_url_set(3)\fP function is called All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/../../etc/password"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, + "https://example.com/../../etc/password"); - curl_easy_setopt(curl, CURLOPT_PATH_AS_IS, 1L); + curl_easy_setopt(curl, CURLOPT_PATH_AS_IS, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 index aa082af70..9a72fa85f 100644 --- a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 +++ b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 @@ -56,16 +56,22 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, "/etc/publickey.der"); - /* OR - curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, "sha256//YhKJKSzoTt2b5FP18fvpHo7fJYqQCjAa3HWY3tvRMwE=;sha256//t62CeU2tQiqkexU74Gxa2eg7fRbEgoChTociMee9wno="); - */ - - /* Perform the request */ - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, "/etc/publickey.der"); + /* OR + curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, + "sha256//YhKJKSzoTt2b5FP18fvpHo7fJYqQCjAa3HWY3" + "tvRMwE=;sha256//t62CeU2tQiqkexU74Gxa2eg7fRbEg" + "oChTociMee9wno="); + */ + + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH PUBLIC KEY EXTRACTION diff --git a/docs/libcurl/opts/CURLOPT_PIPEWAIT.3 b/docs/libcurl/opts/CURLOPT_PIPEWAIT.3 index 593149edd..645f788f9 100644 --- a/docs/libcurl/opts/CURLOPT_PIPEWAIT.3 +++ b/docs/libcurl/opts/CURLOPT_PIPEWAIT.3 @@ -58,12 +58,15 @@ and support level. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L); - /* now add this easy handle to the multi handle */ + /* now add this easy handle to the multi handle */ + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PORT.3 b/docs/libcurl/opts/CURLOPT_PORT.3 index f29d33ce8..4b6667ba8 100644 --- a/docs/libcurl/opts/CURLOPT_PORT.3 +++ b/docs/libcurl/opts/CURLOPT_PORT.3 @@ -52,12 +52,16 @@ impossible to set with this API. Used for all protocols that speak to a port number. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PORT, 8080L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_PORT, 8080L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_POST.3 b/docs/libcurl/opts/CURLOPT_POST.3 index 6f8100feb..182b59cb8 100644 --- a/docs/libcurl/opts/CURLOPT_POST.3 +++ b/docs/libcurl/opts/CURLOPT_POST.3 @@ -78,16 +78,20 @@ Instead you should set a new request type explicitly as described above. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_POST, 1L); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_POST, 1L); - /* set up the read callback with CURLOPT_READFUNCTION */ + /* set up the read callback with CURLOPT_READFUNCTION */ - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_POSTFIELDS.3 b/docs/libcurl/opts/CURLOPT_POSTFIELDS.3 index 08946f286..c42cd65fb 100644 --- a/docs/libcurl/opts/CURLOPT_POSTFIELDS.3 +++ b/docs/libcurl/opts/CURLOPT_POSTFIELDS.3 @@ -77,46 +77,49 @@ HTTP .SH EXAMPLE .nf /* send an application/x-www-form-urlencoded POST */ -CURL *curl = curl_easy_init(); -if(curl) { - const char *data = "data to send"; +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + const char *data = "data to send"; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* size of the POST data if strlen() is not good enough */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L); + /* size of the POST data if strlen() is not good enough */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L); - /* pass in a pointer to the data - libcurl does not copy */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + /* pass in a pointer to the data - libcurl does not copy */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); - curl_easy_perform(curl); -} + curl_easy_perform(curl); + } -/* send an application/json POST */ -CURL *curl = curl_easy_init(); -if(curl) { - const char *json = "{\"name\": \"daniel\"}"; - struct curl_slist *slist1 = NULL; - slist1 = curl_slist_append(slist1, "Content-Type: application/json"); - slist1 = curl_slist_append(slist1, "Accept: application/json"); + /* send an application/json POST */ + curl = curl_easy_init(); + if(curl) { + const char *json = "{\"name\": \"daniel\"}"; + struct curl_slist *slist1 = NULL; + slist1 = curl_slist_append(slist1, "Content-Type: application/json"); + slist1 = curl_slist_append(slist1, "Accept: application/json"); - /* set custom headers */ - curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1); + /* set custom headers */ + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* pass in a pointer to the data - libcurl does not copy */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json); + /* pass in a pointer to the data - libcurl does not copy */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } - .fi .SH AVAILABILITY Always .SH RETURN VALUE Returns CURLE_OK .SH "SEE ALSO" +.BR CURLOPT_COPYPOSTFIELDS (3), .BR CURLOPT_MIMEPOST (3), .BR CURLOPT_POSTFIELDSIZE (3), .BR CURLOPT_READFUNCTION (3), diff --git a/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE.3 b/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE.3 index e519dd7ac..75ec05291 100644 --- a/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE.3 +++ b/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE.3 @@ -45,18 +45,23 @@ If you post more than 2GB, use \fICURLOPT_POSTFIELDSIZE_LARGE(3)\fP. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - const char *data = "data to send"; +#include /* for strlen */ - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + const char *data = "data to send"; - /* size of the POST data */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(data)); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + /* size of the POST data */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(data)); - curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE_LARGE.3 b/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE_LARGE.3 index 22dabf31a..c09feea9a 100644 --- a/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_POSTFIELDSIZE_LARGE.3 @@ -43,19 +43,24 @@ this size is set to -1, libcurl uses strlen() to get the size or relies on the HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - const char *data = large_chunk; - curl_off_t length_of_data; /* set somehow */ +extern char *large_chunk; /* pointer to somewhere */ - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + const char *data = large_chunk; + curl_off_t length_of_data; /* set somehow */ - /* size of the POST data */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, length_of_data); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + /* size of the POST data */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, length_of_data); - curl_easy_perform(curl); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_POSTQUOTE.3 b/docs/libcurl/opts/CURLOPT_POSTQUOTE.3 index 556895669..33c46c7a5 100644 --- a/docs/libcurl/opts/CURLOPT_POSTQUOTE.3 +++ b/docs/libcurl/opts/CURLOPT_POSTQUOTE.3 @@ -45,20 +45,24 @@ NULL SFTP and FTP .SH EXAMPLE .nf -struct curl_slist *cmdlist = NULL; -cmdlist = curl_slist_append(cmdlist, "RNFR source-name"); -cmdlist = curl_slist_append(cmdlist, "RNTO new-name"); +int main(void) +{ + struct curl_slist *cmdlist = NULL; + cmdlist = curl_slist_append(cmdlist, "RNFR source-name"); + cmdlist = curl_slist_append(cmdlist, "RNTO new-name"); -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); - /* pass in the FTP commands to run after the transfer */ - curl_easy_setopt(curl, CURLOPT_POSTQUOTE, cmdlist); + /* pass in the FTP commands to run after the transfer */ + curl_easy_setopt(curl, CURLOPT_POSTQUOTE, cmdlist); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_POSTREDIR.3 b/docs/libcurl/opts/CURLOPT_POSTREDIR.3 index 38b9e8c95..da7d826d7 100644 --- a/docs/libcurl/opts/CURLOPT_POSTREDIR.3 +++ b/docs/libcurl/opts/CURLOPT_POSTREDIR.3 @@ -52,18 +52,21 @@ when setting \fICURLOPT_FOLLOWLOCATION(3)\fP. HTTP(S) .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* a silly POST example */ - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "data=true"); + /* a silly POST example */ + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "data=true"); - /* example.com is redirected, so we tell libcurl to send POST on 301, 302 and - 303 HTTP response codes */ - curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); + /* example.com is redirected, so we tell libcurl to send POST on 301, + 302 and 303 HTTP response codes */ + curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PREQUOTE.3 b/docs/libcurl/opts/CURLOPT_PREQUOTE.3 index b216e9e67..fd5ba0467 100644 --- a/docs/libcurl/opts/CURLOPT_PREQUOTE.3 +++ b/docs/libcurl/opts/CURLOPT_PREQUOTE.3 @@ -50,19 +50,23 @@ NULL FTP .SH EXAMPLE .nf -struct curl_slist *cmdlist = NULL; -cmdlist = curl_slist_append(cmdlist, "SYST"); +int main(void) +{ + struct curl_slist *cmdlist = NULL; + cmdlist = curl_slist_append(cmdlist, "SYST"); -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); - /* pass in the FTP commands to run */ - curl_easy_setopt(curl, CURLOPT_PREQUOTE, cmdlist); + /* pass in the FTP commands to run */ + curl_easy_setopt(curl, CURLOPT_PREQUOTE, cmdlist); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PREREQDATA.3 b/docs/libcurl/opts/CURLOPT_PREREQDATA.3 index 617ecf07b..2d9c4e12c 100644 --- a/docs/libcurl/opts/CURLOPT_PREREQDATA.3 +++ b/docs/libcurl/opts/CURLOPT_PREREQDATA.3 @@ -40,20 +40,29 @@ NULL All .SH EXAMPLE .nf +struct priv { + void *custom; +}; + static int prereq_callback(void *clientp, char *conn_primary_ip, char *conn_local_ip, int conn_primary_port, int conn_local_port) { - printf("Connection made to %s:%s\\n", conn_primary_ip, conn_primary_port); + printf("Connection made to %s:%d\\n", conn_primary_ip, conn_primary_port); return CURL_PREREQFUNC_OK; } +int main(void) { - struct data prereq_data; - curl_easy_setopt(CURL *handle, CURLOPT_PREREQFUNCTION, prereq_callback); - curl_easy_setopt(CURL *handle, CURLOPT_PREREQDATA, &prereq_data); + struct priv prereq_data; + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_PREREQFUNCTION, prereq_callback); + curl_easy_setopt(curl, CURLOPT_PREREQDATA, &prereq_data); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PREREQFUNCTION.3 b/docs/libcurl/opts/CURLOPT_PREREQFUNCTION.3 index 4d13a5491..a2e3dd38f 100644 --- a/docs/libcurl/opts/CURLOPT_PREREQFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_PREREQFUNCTION.3 @@ -81,20 +81,29 @@ By default, this is NULL and unused. ALL .SH EXAMPLE .nf +struct priv { + void *custom; +}; + static int prereq_callback(void *clientp, char *conn_primary_ip, char *conn_local_ip, int conn_primary_port, int conn_local_port) { - printf("Connection made to %s:%s\\n", conn_primary_ip, conn_primary_port); + printf("Connection made to %s:%d\\n", conn_primary_ip, conn_primary_port); return CURL_PREREQFUNC_OK; } +int main(void) { - struct data prereq_data; - curl_easy_setopt(CURL *handle, CURLOPT_PREREQFUNCTION, prereq_callback); - curl_easy_setopt(CURL *handle, CURLOPT_PREREQDATA, &prereq_data); + struct priv prereq_data; + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_PREREQFUNCTION, prereq_callback); + curl_easy_setopt(curl, CURLOPT_PREREQDATA, &prereq_data); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PRE_PROXY.3 b/docs/libcurl/opts/CURLOPT_PRE_PROXY.3 index 6e06ab822..044d60c0c 100644 --- a/docs/libcurl/opts/CURLOPT_PRE_PROXY.3 +++ b/docs/libcurl/opts/CURLOPT_PRE_PROXY.3 @@ -66,12 +66,15 @@ single port number used widely for proxies. Specify it! All except file://. Note that some protocols do not work well over proxy. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt"); - curl_easy_setopt(curl, CURLOPT_PRE_PROXY, "socks4://socks-proxy:1080"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt"); + curl_easy_setopt(curl, CURLOPT_PRE_PROXY, "socks4://socks-proxy:1080"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PRIVATE.3 b/docs/libcurl/opts/CURLOPT_PRIVATE.3 index 20da94775..273ba1df6 100644 --- a/docs/libcurl/opts/CURLOPT_PRIVATE.3 +++ b/docs/libcurl/opts/CURLOPT_PRIVATE.3 @@ -42,19 +42,26 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -struct private secrets; -if(curl) { - struct private *extracted; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +struct private { + void *custom; +}; - /* store a pointer to our private struct */ - curl_easy_setopt(curl, CURLOPT_PRIVATE, &secrets); +int main(void) +{ + CURL *curl = curl_easy_init(); + struct private secrets; + if(curl) { + struct private *extracted; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_perform(curl); + /* store a pointer to our private struct */ + curl_easy_setopt(curl, CURLOPT_PRIVATE, &secrets); - /* we can extract the private pointer again too */ - curl_easy_getinfo(curl, CURLINFO_PRIVATE, &extracted); + curl_easy_perform(curl); + + /* we can extract the private pointer again too */ + curl_easy_getinfo(curl, CURLINFO_PRIVATE, &extracted); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROGRESSDATA.3 b/docs/libcurl/opts/CURLOPT_PROGRESSDATA.3 index b83c1d923..8d1fef100 100644 --- a/docs/libcurl/opts/CURLOPT_PROGRESSDATA.3 +++ b/docs/libcurl/opts/CURLOPT_PROGRESSDATA.3 @@ -40,30 +40,38 @@ The default value of this parameter is NULL. All .SH EXAMPLE .nf - struct progress { - char *private; - size_t size; - }; +struct progress { + char *private; + size_t size; +}; - static size_t progress_callback(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow) - { - struct memory *progress = (struct progress *)clientp; +static size_t progress_callback(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + struct progress *memory = clientp; + printf("private: %p\\n", memory->private); - /* use the values */ + /* use the values */ - return 0; /* all is good */ - } + return 0; /* all is good */ +} - struct progress data; +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct progress data; - /* pass struct to callback */ - curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, &data); + /* pass struct to callback */ + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &data); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); - curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, progress_callback); + curl_easy_perform(curl); + } +} .fi .SH AVAILABILITY Always diff --git a/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.3 b/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.3 index 809cf387d..5682900d5 100644 --- a/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_PROGRESSFUNCTION.3 @@ -84,30 +84,38 @@ users. All .SH EXAMPLE .nf - struct progress { - char *private; - size_t size; - }; - - static size_t progress_callback(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow) - { - struct progress *memory = (struct progress *)clientp; - - /* use the values */ - - return 0; /* all is good */ - } - - struct progress data; - - /* pass struct to callback */ - curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, &data); - - curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, progress_callback); +struct progress { + char *private; + size_t size; +}; + +static size_t progress_callback(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + struct progress *memory = clientp; + printf("private: %p\\n", memory->private); + + /* use the values */ + + return 0; /* all is good */ +} + +int main(void) +{ + struct progress data; + + CURL *curl = curl_easy_init(); + if(curl) { + /* pass struct to callback */ + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &data); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + + curl_easy_perform(curl); + } +} .fi .SH AVAILABILITY Deprecated since 7.32.0. diff --git a/docs/libcurl/opts/CURLOPT_PROTOCOLS.3 b/docs/libcurl/opts/CURLOPT_PROTOCOLS.3 index f252e98d4..29538d660 100644 --- a/docs/libcurl/opts/CURLOPT_PROTOCOLS.3 +++ b/docs/libcurl/opts/CURLOPT_PROTOCOLS.3 @@ -80,17 +80,20 @@ All protocols built-in. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - /* pass in the URL from an external source */ - curl_easy_setopt(curl, CURLOPT_URL, argv[1]); +int main(int argc, char **argv) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* pass in the URL from an external source */ + curl_easy_setopt(curl, CURLOPT_URL, argv[1]); - /* only allow HTTP, TFTP and SFTP */ - curl_easy_setopt(curl, CURLOPT_PROTOCOLS, - CURLPROTO_HTTP | CURLPROTO_TFTP | CURLPROTO_SFTP); + /* only allow HTTP, TFTP and SFTP */ + curl_easy_setopt(curl, CURLOPT_PROTOCOLS, + CURLPROTO_HTTP | CURLPROTO_TFTP | CURLPROTO_SFTP); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.3 b/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.3 index 561020fd7..8af32244d 100644 --- a/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.3 +++ b/docs/libcurl/opts/CURLOPT_PROTOCOLS_STR.3 @@ -61,16 +61,19 @@ All protocols built-in All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - /* pass in the URL from an external source */ - curl_easy_setopt(curl, CURLOPT_URL, argv[1]); +int main(int argc, char **argv) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* pass in the URL from an external source */ + curl_easy_setopt(curl, CURLOPT_URL, argv[1]); - /* only allow HTTP, TFTP and SFTP */ - curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,tftp,sftp"); + /* only allow HTTP, TFTP and SFTP */ + curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,tftp,sftp"); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY.3 b/docs/libcurl/opts/CURLOPT_PROXY.3 index c645af539..a3a36152a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY.3 @@ -109,11 +109,14 @@ single port number used widely for proxies. Specify it! All except file://. Note that some protocols do not work well over proxy. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80"); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80"); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYAUTH.3 b/docs/libcurl/opts/CURLOPT_PROXYAUTH.3 index 309d3699e..db48dd1fb 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYAUTH.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYAUTH.3 @@ -48,18 +48,21 @@ CURLAUTH_BASIC HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* use this proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "http://local.example.com:1080"); - /* allow whatever auth the proxy speaks */ - curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); - /* set the proxy credentials */ - curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "james:007"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* use this proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "http://local.example.com:1080"); + /* allow whatever auth the proxy speaks */ + curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + /* set the proxy credentials */ + curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "james:007"); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYHEADER.3 b/docs/libcurl/opts/CURLOPT_PROXYHEADER.3 index 439008201..1bc17e9e8 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYHEADER.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYHEADER.3 @@ -51,22 +51,25 @@ NULL HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); +int main(void) +{ + CURL *curl = curl_easy_init(); -struct curl_slist *list; + struct curl_slist *list; -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy.example.com:80"); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy.example.com:80"); - list = curl_slist_append(NULL, "Shoesize: 10"); - list = curl_slist_append(list, "Accept:"); + list = curl_slist_append(NULL, "Shoesize: 10"); + list = curl_slist_append(list, "Accept:"); - curl_easy_setopt(curl, CURLOPT_PROXYHEADER, list); + curl_easy_setopt(curl, CURLOPT_PROXYHEADER, list); - curl_easy_perform(curl); + curl_easy_perform(curl); - curl_slist_free_all(list); /* free the list again */ + curl_slist_free_all(list); /* free the list again */ + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.3 b/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.3 index 766e0b2ad..921caf329 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYPASSWORD.3 @@ -46,14 +46,18 @@ blank Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); - curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, "mrsmith"); - curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, "qwerty"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); + curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, "mrsmith"); + curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, "qwerty"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYPORT.3 b/docs/libcurl/opts/CURLOPT_PROXYPORT.3 index 1b369ca0a..04a20a7bb 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYPORT.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYPORT.3 @@ -46,13 +46,17 @@ than 65535. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PROXY, "localhost"); - curl_easy_setopt(curl, CURLOPT_PROXYPORT, 8080L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_PROXY, "localhost"); + curl_easy_setopt(curl, CURLOPT_PROXYPORT, 8080L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYTYPE.3 b/docs/libcurl/opts/CURLOPT_PROXYTYPE.3 index 3399e2c20..91f3b5a9a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYTYPE.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYTYPE.3 @@ -65,15 +65,18 @@ CURLPROXY_HTTP Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "local.example.com:1080"); - /* set the proxy type */ - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "local.example.com:1080"); + /* set the proxy type */ + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYUSERNAME.3 b/docs/libcurl/opts/CURLOPT_PROXYUSERNAME.3 index c594ca2ea..7a0e54ee2 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYUSERNAME.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYUSERNAME.3 @@ -48,14 +48,18 @@ blank Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); - curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, "mrsmith"); - curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, "qwerty"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); + curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, "mrsmith"); + curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, "qwerty"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.3 b/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.3 index 76f8bbf20..e6bdcf956 100644 --- a/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.3 +++ b/docs/libcurl/opts/CURLOPT_PROXYUSERPWD.3 @@ -48,13 +48,17 @@ This is NULL by default. Used with all protocols that can use a proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); - curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "clark%20kent:superman"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080"); + curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "clark%20kent:superman"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 index fb2c6dca9..4b64353e6 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO.3 @@ -60,14 +60,18 @@ Built-in system specific Used with HTTPS proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* using an HTTPS proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); - curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO, "/etc/certs/cabundle.pem"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* using an HTTPS proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); + curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO, "/etc/certs/cabundle.pem"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO_BLOB.3 b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO_BLOB.3 index b2e8be037..80c03f354 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CAINFO_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_CAINFO_BLOB.3 @@ -39,6 +39,10 @@ Pass a pointer to a curl_blob structure, which contains information (pointer and size) about a memory block with binary data of PEM encoded content holding one or more certificates to verify the HTTPS proxy with. +If the blob is initialized with the flags member of struct curl_blob set to +CURL_BLOB_COPY, the application does not have to keep the buffer around after +setting this. + If \fICURLOPT_PROXY_SSL_VERIFYPEER(3)\fP is zero and you avoid verifying the server's certificate, \fICURLOPT_PROXY_CAINFO_BLOB(3)\fP is not needed. @@ -49,19 +53,25 @@ NULL Used with HTTPS proxy .SH EXAMPLE .nf -char *strpem; /* strpem must point to a PEM string */ -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* using an HTTPS proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); - blob.data = strpem; - blob.len = strlen(strpem); - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO_BLOB, &blob); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +#include /* for strlen */ + +extern char *strpem; /* strpem must point to a PEM string */ +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* using an HTTPS proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); + blob.data = strpem; + blob.len = strlen(strpem); + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_PROXY_CAINFO_BLOB, &blob); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 b/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 index 2db652ead..fd55b0918 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_CAPATH.3 @@ -48,14 +48,18 @@ NULL Everything used over an HTTPS proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* using an HTTPS proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); - curl_easy_setopt(curl, CURLOPT_PROXY_CAPATH, "/etc/cert-dir"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* using an HTTPS proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); + curl_easy_setopt(curl, CURLOPT_PROXY_CAPATH, "/etc/cert-dir"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 b/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 index 40fd1cd9d..80891666a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_CRLFILE.3 @@ -60,13 +60,17 @@ NULL Used with HTTPS proxy. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:80"); - curl_easy_setopt(curl, CURLOPT_PROXY_CRLFILE, "/etc/certs/crl.pem"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:80"); + curl_easy_setopt(curl, CURLOPT_PROXY_CRLFILE, "/etc/certs/crl.pem"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.3 b/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.3 index af0621ca6..5ddbc712c 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT.3 @@ -57,14 +57,18 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* using an HTTPS proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); - curl_easy_setopt(curl, CURLOPT_PROXY_ISSUERCERT, "/etc/certs/cacert.pem"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* using an HTTPS proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); + curl_easy_setopt(curl, CURLOPT_PROXY_ISSUERCERT, "/etc/certs/cacert.pem"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT_BLOB.3 b/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT_BLOB.3 index 32af0cc8e..4f94d2eb0 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_ISSUERCERT_BLOB.3 @@ -63,18 +63,26 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* using an HTTPS proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); - blob.data = certificateData; - blob.len = filesize; - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_PROXY_ISSUERCERT_BLOB, &blob); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); + +extern char *certificateData; /* point to the data */ +size_t filesize; /* size of the data */ + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* using an HTTPS proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost:443"); + blob.data = certificateData; + blob.len = filesize; + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_PROXY_ISSUERCERT_BLOB, &blob); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 b/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 index 083665fef..8d0ba91a0 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_KEYPASSWD.3 @@ -47,13 +47,17 @@ NULL Used with HTTPS proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "superman"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "superman"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 index 05f76515f..9a9ce119c 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 @@ -52,15 +52,20 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); - curl_easy_setopt(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, - "sha256//YhKJKSzoTt2b5FP18fvpHo7fJYqQCjAa3HWY3tvRMwE=;sha256//t62CeU2tQiqkexU74Gxa2eg7fRbEgoChTociMee9wno="); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); + curl_easy_setopt(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, + "sha256//YhKJKSzoTt2b5FP18fvpHo7fJYqQCjA" + "a3HWY3tvRMwE=;sha256//t62CeU2tQiqkexU74" + "Gxa2eg7fRbEgoChTociMee9wno="); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH PUBLIC KEY EXTRACTION diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.3 b/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.3 index 31f7805fa..712836f60 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SERVICE_NAME.3 @@ -45,12 +45,15 @@ See above All network protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY_SERVICE_NAME, "custom"); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY_SERVICE_NAME, "custom"); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 index 0a1c45eb0..54e6f545b 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT.3 @@ -55,15 +55,19 @@ NULL Used with HTTPS proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 index c1ef518c2..380595c7e 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERTTYPE.3 @@ -48,16 +48,20 @@ option. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERTTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERTTYPE, "PEM"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT_BLOB.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT_BLOB.3 index 3b8412626..a033193d1 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLCERT_BLOB.3 @@ -51,19 +51,27 @@ NULL Used with HTTPS proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - blob.data = certificateData; - blob.len = filesize; - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT_BLOB, &blob); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); + +extern char *certificateData; /* point to data */ +extern size_t filesize; /* size of the data */ + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + blob.data = certificateData; + blob.len = filesize; + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT_BLOB, &blob); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 index e24e0cd3b..82a5bf9c2 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY.3 @@ -49,15 +49,19 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 index c30e832eb..dfa6ce6d4 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEYTYPE.3 @@ -43,16 +43,20 @@ option. Used with HTTPS proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEYTYPE, "PEM"); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY_BLOB.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY_BLOB.3 index 9b2385d07..034e1fe0e 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLKEY_BLOB.3 @@ -47,23 +47,34 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - blob.data = certificateData; - blob.len = filesize; - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT_BLOB, &blob); - curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERTTYPE, "PEM"); - blob.data = privateKeyData; - blob.len = privateKeySize; - curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY_BLOB, &blob); - curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +extern char *certificateData; /* point to data */ +extern size_t filesize; /* size of data */ + +extern char *privateKeyData; /* point to data */ +extern size_t privateKeySize; /* size */ + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + blob.data = certificateData; + blob.len = filesize; + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERT_BLOB, &blob); + curl_easy_setopt(curl, CURLOPT_PROXY_SSLCERTTYPE, "PEM"); + + blob.data = privateKeyData; + blob.len = privateKeySize; + curl_easy_setopt(curl, CURLOPT_PROXY_SSLKEY_BLOB, &blob); + curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 index abc173557..3c3fe0289 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSLVERSION.3 @@ -85,15 +85,18 @@ CURL_SSLVERSION_DEFAULT All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* ask libcurl to use TLS version 1.0 or later */ - curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); + /* ask libcurl to use TLS version 1.0 or later */ + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 index 6539a2a9a..5677c655a 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.3 @@ -65,13 +65,17 @@ NULL, use internal default All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost"); - curl_easy_setopt(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, "TLSv1"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://localhost"); + curl_easy_setopt(curl, CURLOPT_PROXY_SSL_CIPHER_LIST, "TLSv1"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 index 3611dbc8c..b64285afc 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_OPTIONS.3 @@ -62,12 +62,13 @@ library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes precedence. (Added in 7.70.0) .IP CURLSSLOPT_NATIVE_CA Tell libcurl to use the operating system's native CA store for certificate -verification. Works only on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora, -RHEL), macOS, Android and iOS when built to use wolfSSL (since 8.3.0) or on -Windows when built to use OpenSSL. If you set this option and also set a CA -certificate file or directory then during verification those certificates -are searched in addition to the native CA store. -(Added in 7.71.0) +verification. If you set this option and also set a CA certificate file or +directory then during verification those certificates are searched in addition +to the native CA store. + +Works with wolfSSL on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora, RHEL), +macOS, Android and iOS (added in 8.3.0), with GnuTLS (added in 8.5.0) or on +Windows when built to use OpenSSL (Added in 7.71.0). .IP CURLSSLOPT_AUTO_CLIENT_CERT Tell libcurl to automatically locate and use a client certificate for authentication, when requested by the server. This option is only supported @@ -82,15 +83,19 @@ could be a privacy violation and unexpected. All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - /* weaken TLS only for use with silly proxies */ - curl_easy_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST | - CURLSSLOPT_NO_REVOKE); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + /* weaken TLS only for use with silly proxies */ + curl_easy_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST | + CURLSSLOPT_NO_REVOKE); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 index 83962d7c2..42a96b6c2 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYHOST.3 @@ -68,14 +68,17 @@ of the proxy certificate. All protocols when used over an HTTPS proxy. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Set the default value: strict name check please */ - curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 2L); + /* Set the default value: strict name check please */ + curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 2L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 index c6d46029a..866f07c9f 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_VERIFYPEER.3 @@ -72,14 +72,17 @@ the correct end-point. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Set the default value: strict certificate check please */ - curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L); + /* Set the default value: strict certificate check please */ + curl_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.3 index f34f37ccf..d64d17ccc 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLS13_CIPHERS.3 @@ -54,13 +54,17 @@ NULL, use internal default All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLS13_CIPHERS, - "TLS_CHACHA20_POLY1305_SHA256"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLS13_CIPHERS, + "TLS_CHACHA20_POLY1305_SHA256"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 index f5990dd4d..327b92a81 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_PASSWORD.3 @@ -46,15 +46,19 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_TYPE, "SRP"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, "user"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, "secret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_TYPE, "SRP"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, "user"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, "secret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 index 0b4154422..c4fe02c85 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_TYPE.3 @@ -52,15 +52,19 @@ blank All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_TYPE, "SRP"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, "user"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, "secret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_TYPE, "SRP"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, "user"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, "secret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 index 8cc73fe7a..e8362fa2f 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_TLSAUTH_USERNAME.3 @@ -46,15 +46,19 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_TYPE, "SRP"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, "user"); - curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, "secret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_TYPE, "SRP"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_USERNAME, "user"); + curl_easy_setopt(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD, "secret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_PROXY_TRANSFER_MODE.3 b/docs/libcurl/opts/CURLOPT_PROXY_TRANSFER_MODE.3 index 495133e7f..f948613a8 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_TRANSFER_MODE.3 +++ b/docs/libcurl/opts/CURLOPT_PROXY_TRANSFER_MODE.3 @@ -44,14 +44,19 @@ doing FTP via a proxy. Beware that not all proxies support this feature. FTP over proxy .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/old-server/file.txt"); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:80"); - curl_easy_setopt(curl, CURLOPT_PROXY_TRANSFER_MODE, 1L); - curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, + "ftp://example.com/old-server/file.txt"); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:80"); + curl_easy_setopt(curl, CURLOPT_PROXY_TRANSFER_MODE, 1L); + curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY @@ -60,7 +65,7 @@ Added in 7.18.0 Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if the enabled value is not supported. .SH "SEE ALSO" -.BN CURLOPT_CRLF (3), -.BN CURLOPT_TRANSFERTEXT (3), +.BR CURLOPT_CRLF (3), +.BR CURLOPT_TRANSFERTEXT (3), .BR CURLOPT_HTTPPROXYTUNNEL (3), .BR CURLOPT_PROXY (3) diff --git a/docs/libcurl/opts/CURLOPT_PUT.3 b/docs/libcurl/opts/CURLOPT_PUT.3 index 0330878f8..fb4e4c9be 100644 --- a/docs/libcurl/opts/CURLOPT_PUT.3 +++ b/docs/libcurl/opts/CURLOPT_PUT.3 @@ -44,25 +44,41 @@ This option is \fBdeprecated\fP since version 7.12.1. Use HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - /* we want to use our own read function */ - curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); +static size_t read_cb(char *ptr, size_t size, size_t nmemb, void *userdata) +{ + FILE *src = userdata; + /* copy as much data as possible into the 'ptr' buffer, but no more than + 'size' * 'nmemb' bytes! */ + size_t retcode = fread(ptr, size, nmemb, src); - /* enable PUT */ - curl_easy_setopt(curl, CURLOPT_PUT, 1L); + return retcode; +} + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + FILE *src = fopen("local-file", "r"); + curl_off_t fsize; /* set this to the size of the input file */ + + /* we want to use our own read function */ + curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb); + + /* enable PUT */ + curl_easy_setopt(curl, CURLOPT_PUT, 1L); - /* specify target */ - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/to/newfile"); + /* specify target */ + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/to/newfile"); - /* now specify which pointer to pass to our callback */ - curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); + /* now specify which pointer to pass to our callback */ + curl_easy_setopt(curl, CURLOPT_READDATA, src); - /* Set the size of the file to upload */ - curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); + /* Set the size of the file to upload */ + curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); - /* Now run off and do what you have been told! */ - curl_easy_perform(curl); + /* Now run off and do what you have been told! */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_QUICK_EXIT.3 b/docs/libcurl/opts/CURLOPT_QUICK_EXIT.3 index 11fa0edcb..f34e771ac 100644 --- a/docs/libcurl/opts/CURLOPT_QUICK_EXIT.3 +++ b/docs/libcurl/opts/CURLOPT_QUICK_EXIT.3 @@ -44,11 +44,14 @@ possible (though short-lived) leak of associated resources. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_QUICK_EXIT, 1L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_QUICK_EXIT, 1L); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_QUOTE.3 b/docs/libcurl/opts/CURLOPT_QUOTE.3 index 83f2c50fb..29e0154cd 100644 --- a/docs/libcurl/opts/CURLOPT_QUOTE.3 +++ b/docs/libcurl/opts/CURLOPT_QUOTE.3 @@ -102,20 +102,24 @@ NULL SFTP and FTP .SH EXAMPLE .nf -struct curl_slist *cmdlist = NULL; -cmdlist = curl_slist_append(cmdlist, "RNFR source-name"); -cmdlist = curl_slist_append(cmdlist, "RNTO new-name"); +int main(void) +{ + struct curl_slist *cmdlist = NULL; + cmdlist = curl_slist_append(cmdlist, "RNFR source-name"); + cmdlist = curl_slist_append(cmdlist, "RNTO new-name"); -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/foo.bin"); - /* pass in the FTP commands to run before the transfer */ - curl_easy_setopt(curl, CURLOPT_QUOTE, cmdlist); + /* pass in the FTP commands to run before the transfer */ + curl_easy_setopt(curl, CURLOPT_QUOTE, cmdlist); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RANDOM_FILE.3 b/docs/libcurl/opts/CURLOPT_RANDOM_FILE.3 index da5196d1d..b226d15a0 100644 --- a/docs/libcurl/opts/CURLOPT_RANDOM_FILE.3 +++ b/docs/libcurl/opts/CURLOPT_RANDOM_FILE.3 @@ -45,12 +45,16 @@ NULL, not used All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_RANDOM_FILE, "junk.txt"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_RANDOM_FILE, "junk.txt"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RANGE.3 b/docs/libcurl/opts/CURLOPT_RANGE.3 index 3b20a5206..90ad66696 100644 --- a/docs/libcurl/opts/CURLOPT_RANGE.3 +++ b/docs/libcurl/opts/CURLOPT_RANGE.3 @@ -60,15 +60,18 @@ NULL HTTP, FTP, FILE, RTSP and SFTP. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* get the first 200 bytes */ - curl_easy_setopt(curl, CURLOPT_RANGE, "0-199"); + /* get the first 200 bytes */ + curl_easy_setopt(curl, CURLOPT_RANGE, "0-199"); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_READDATA.3 b/docs/libcurl/opts/CURLOPT_READDATA.3 index f8ab7940a..db0dcfc60 100644 --- a/docs/libcurl/opts/CURLOPT_READDATA.3 +++ b/docs/libcurl/opts/CURLOPT_READDATA.3 @@ -48,16 +48,23 @@ By default, this is a FILE * to stdin. This is used for all protocols when sending data. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -struct MyData this; -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +struct MyData { + void *custom; +}; - /* pass pointer that gets passed in to the - CURLOPT_READFUNCTION callback */ - curl_easy_setopt(curl, CURLOPT_READDATA, &this); +int main(void) +{ + CURL *curl = curl_easy_init(); + struct MyData this; + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_perform(curl); + /* pass pointer that gets passed in to the + CURLOPT_READFUNCTION callback */ + curl_easy_setopt(curl, CURLOPT_READDATA, &this); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_READFUNCTION.3 b/docs/libcurl/opts/CURLOPT_READFUNCTION.3 index 4aeb6dee0..de689fbdc 100644 --- a/docs/libcurl/opts/CURLOPT_READFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_READFUNCTION.3 @@ -94,18 +94,21 @@ size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userdata) return retcode; } -void setup(char *uploadthis) +int main(int argc, char **argv) { - FILE *file = fopen(uploadthis, "rb"); + FILE *file = fopen(argv[1], "rb"); CURLcode result; - /* set callback to use */ - curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); + CURL *curl = curl_easy_init(); + if(curl) { + /* set callback to use */ + curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); - /* pass in suitable argument to callback */ - curl_easy_setopt(curl, CURLOPT_READDATA, (void *)file); + /* pass in suitable argument to callback */ + curl_easy_setopt(curl, CURLOPT_READDATA, (void *)file); - result = curl_easy_perform(curl); + result = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 index a0cfb0df4..c45583d79 100644 --- a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 +++ b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS.3 @@ -89,17 +89,20 @@ SMB and SMBS. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - /* pass in the URL from an external source */ - curl_easy_setopt(curl, CURLOPT_URL, argv[1]); +int main(int argc, char **argv) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* pass in the URL from an external source */ + curl_easy_setopt(curl, CURLOPT_URL, argv[1]); - /* only allow redirects to HTTP and HTTPS URLs */ - curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, - CURLPROTO_HTTP | CURLPROTO_HTTPS); + /* only allow redirects to HTTP and HTTPS URLs */ + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, + CURLPROTO_HTTP | CURLPROTO_HTTPS); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.3 b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.3 index 0ddb6ff02..db243ad1d 100644 --- a/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.3 +++ b/docs/libcurl/opts/CURLOPT_REDIR_PROTOCOLS_STR.3 @@ -67,16 +67,19 @@ SMB and SMBS. All .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - /* pass in the URL from an external source */ - curl_easy_setopt(curl, CURLOPT_URL, argv[1]); +int main(int argc, char **argv) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* pass in the URL from an external source */ + curl_easy_setopt(curl, CURLOPT_URL, argv[1]); - /* only allow redirects to HTTP and HTTPS URLs */ - curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"); + /* only allow redirects to HTTP and HTTPS URLs */ + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_REFERER.3 b/docs/libcurl/opts/CURLOPT_REFERER.3 index f294bdaf7..38d931b9f 100644 --- a/docs/libcurl/opts/CURLOPT_REFERER.3 +++ b/docs/libcurl/opts/CURLOPT_REFERER.3 @@ -44,14 +44,17 @@ NULL HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* tell it where we found the link to this place */ - curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.com/aboutme.html"); + /* tell it where we found the link to this place */ + curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.org/me.html"); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.3 b/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.3 index bd26a95b6..f7a21feda 100644 --- a/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.3 +++ b/docs/libcurl/opts/CURLOPT_REQUEST_TARGET.3 @@ -34,22 +34,28 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_REQUEST_TARGET, string); .SH DESCRIPTION Pass a char * to string which libcurl uses in the upcoming request instead of the path as extracted from the URL. + +libcurl passes on the verbatim string in its request without any filter or +other safe guards. That includes white space and control characters. .SH DEFAULT NULL .SH PROTOCOLS HTTP .SH EXAMPLE .nf -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/*"); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "OPTIONS"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/*"); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "OPTIONS"); - /* issue an OPTIONS * request (no leading slash) */ - curl_easy_setopt(curl, CURLOPT_REQUEST_TARGET, "*"); + /* issue an OPTIONS * request (no leading slash) */ + curl_easy_setopt(curl, CURLOPT_REQUEST_TARGET, "*"); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RESOLVE.3 b/docs/libcurl/opts/CURLOPT_RESOLVE.3 index 670089e8b..b0aa0e778 100644 --- a/docs/libcurl/opts/CURLOPT_RESOLVE.3 +++ b/docs/libcurl/opts/CURLOPT_RESOLVE.3 @@ -79,22 +79,25 @@ NULL All .SH EXAMPLE .nf -CURL *curl; -struct curl_slist *host = NULL; -host = curl_slist_append(NULL, "example.com:443:127.0.0.1"); +int main(void) +{ + CURL *curl; + struct curl_slist *host = NULL; + host = curl_slist_append(NULL, "example.com:443:127.0.0.1"); -curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_RESOLVE, host); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_RESOLVE, host); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* always cleanup */ - curl_easy_cleanup(curl); -} + /* always cleanup */ + curl_easy_cleanup(curl); + } -curl_slist_free_all(host); + curl_slist_free_all(host); +} .fi .SH AVAILABILITY Added in 7.21.3. Removal support added in 7.42.0. diff --git a/docs/libcurl/opts/CURLOPT_RESOLVER_START_DATA.3 b/docs/libcurl/opts/CURLOPT_RESOLVER_START_DATA.3 index 2344de908..84bc081a6 100644 --- a/docs/libcurl/opts/CURLOPT_RESOLVER_START_DATA.3 +++ b/docs/libcurl/opts/CURLOPT_RESOLVER_START_DATA.3 @@ -51,13 +51,16 @@ static int resolver_start_cb(void *resolver_state, void *reserved, return 0; } -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, resolver_start_cb); - curl_easy_setopt(curl, CURLOPT_RESOLVER_START_DATA, curl); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, resolver_start_cb); + curl_easy_setopt(curl, CURLOPT_RESOLVER_START_DATA, curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RESOLVER_START_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_RESOLVER_START_FUNCTION.3 index 96e726ae0..bd2c1189f 100644 --- a/docs/libcurl/opts/CURLOPT_RESOLVER_START_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_RESOLVER_START_FUNCTION.3 @@ -59,8 +59,8 @@ NULL (No callback) All .SH EXAMPLE .nf -static int resolver_start_cb(void *resolver_state, void *reserved, - void *userdata) +static int start_cb(void *resolver_state, void *reserved, + void *userdata) { (void)reserved; printf("Received resolver_state=%p userdata=%p\\n", @@ -68,13 +68,16 @@ static int resolver_start_cb(void *resolver_state, void *reserved, return 0; } -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, resolver_start_cb); - curl_easy_setopt(curl, CURLOPT_RESOLVER_START_DATA, curl); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, start_cb); + curl_easy_setopt(curl, CURLOPT_RESOLVER_START_DATA, curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RESUME_FROM.3 b/docs/libcurl/opts/CURLOPT_RESUME_FROM.3 index 3254f7c12..30c7fea9e 100644 --- a/docs/libcurl/opts/CURLOPT_RESUME_FROM.3 +++ b/docs/libcurl/opts/CURLOPT_RESUME_FROM.3 @@ -50,21 +50,26 @@ If you need to resume a transfer beyond the 2GB limit, use HTTP, FTP, SFTP, FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + long size_of_file; - /* resume upload at byte index 200 */ - curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 200L); + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com"); - /* ask for upload */ - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + /* resume upload at byte index 200 */ + curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 200L); - /* set total data amount to expect */ - curl_easy_setopt(curl, CURLOPT_INFILESIZE, size_of_file); + /* ask for upload */ + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - /* Perform the request */ - curl_easy_perform(curl); + /* set total data amount to expect */ + curl_easy_setopt(curl, CURLOPT_INFILESIZE, size_of_file); + + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RESUME_FROM_LARGE.3 b/docs/libcurl/opts/CURLOPT_RESUME_FROM_LARGE.3 index d4fae3d44..e5d91bb89 100644 --- a/docs/libcurl/opts/CURLOPT_RESUME_FROM_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_RESUME_FROM_LARGE.3 @@ -47,24 +47,27 @@ file to the remote target file. HTTP, FTP, SFTP, FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_off_t resume_position = GET_IT_SOMEHOW; - curl_off_t file_size = GET_IT_SOMEHOW_AS_WELL; +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_off_t resume_position; /* get it somehow */ + curl_off_t file_size; /* get it somehow as well */ - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com"); + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com"); - /* resuming upload at this position, possibly beyond 2GB */ - curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, resume_position); + /* resuming upload at this position, possibly beyond 2GB */ + curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, resume_position); - /* ask for upload */ - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + /* ask for upload */ + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - /* set total data amount to expect */ - curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size); + /* set total data amount to expect */ + curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RTSP_CLIENT_CSEQ.3 b/docs/libcurl/opts/CURLOPT_RTSP_CLIENT_CSEQ.3 index 625641170..4faf8020a 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_CLIENT_CSEQ.3 +++ b/docs/libcurl/opts/CURLOPT_RTSP_CLIENT_CSEQ.3 @@ -41,12 +41,16 @@ increments from this new number henceforth. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); - curl_easy_setopt(curl, CURLOPT_RTSP_CLIENT_CSEQ, 1234L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + curl_easy_setopt(curl, CURLOPT_RTSP_CLIENT_CSEQ, 1234L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RTSP_REQUEST.3 b/docs/libcurl/opts/CURLOPT_RTSP_REQUEST.3 index 3a8ddb200..d62cf1d18 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_REQUEST.3 +++ b/docs/libcurl/opts/CURLOPT_RTSP_REQUEST.3 @@ -100,13 +100,17 @@ application a chance to run. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); - /* ask for options! */ - curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + /* ask for options! */ + curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RTSP_SERVER_CSEQ.3 b/docs/libcurl/opts/CURLOPT_RTSP_SERVER_CSEQ.3 index cadf21cc2..5c75bd149 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_SERVER_CSEQ.3 +++ b/docs/libcurl/opts/CURLOPT_RTSP_SERVER_CSEQ.3 @@ -41,12 +41,16 @@ unimplemented. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); - curl_easy_setopt(curl, CURLOPT_RTSP_SERVER_CSEQ, 1234L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + curl_easy_setopt(curl, CURLOPT_RTSP_SERVER_CSEQ, 1234L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.3 b/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.3 index 3eaae0324..acb8e3611 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.3 +++ b/docs/libcurl/opts/CURLOPT_RTSP_SESSION_ID.3 @@ -46,13 +46,17 @@ NULL RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - char *prev_id; /* saved from before somehow */ - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); - curl_easy_setopt(curl, CURLOPT_RTSP_SESSION_ID, prev_id); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + char *prev_id; /* saved from before somehow */ + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + curl_easy_setopt(curl, CURLOPT_RTSP_SESSION_ID, prev_id); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.3 b/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.3 index f6eea3047..d2c7a49da 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.3 +++ b/docs/libcurl/opts/CURLOPT_RTSP_STREAM_URI.3 @@ -51,14 +51,17 @@ option. RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - char *prev_id; /* saved from before somehow */ - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); - curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, - "rtsp://foo.example.com/twister/video"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, + "rtsp://foo.example.com/twister/video"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_RTSP_TRANSPORT.3 b/docs/libcurl/opts/CURLOPT_RTSP_TRANSPORT.3 index f276cc2b6..9017f9154 100644 --- a/docs/libcurl/opts/CURLOPT_RTSP_TRANSPORT.3 +++ b/docs/libcurl/opts/CURLOPT_RTSP_TRANSPORT.3 @@ -45,14 +45,18 @@ NULL RTSP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); - curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); - curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, - "RTP/AVP;unicast;client_port=4588-4589"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "rtsp://example.com/"); + curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); + curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, + "RTP/AVP;unicast;client_port=4588-4589"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3 b/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3 index d0b73f923..c06a665e2 100644 --- a/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3 +++ b/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3 @@ -50,14 +50,18 @@ blank IMAP, LDAP, POP3 and SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "imap://example.com/"); - curl_easy_setopt(curl, CURLOPT_USERNAME, "Kurt"); - curl_easy_setopt(curl, CURLOPT_PASSWORD, "xipj3plmq"); - curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "Ursel"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "imap://example.com/"); + curl_easy_setopt(curl, CURLOPT_USERNAME, "Kurt"); + curl_easy_setopt(curl, CURLOPT_PASSWORD, "xipj3plmq"); + curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "Ursel"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SASL_IR.3 b/docs/libcurl/opts/CURLOPT_SASL_IR.3 index 7c3a7a4ba..50ec074a0 100644 --- a/docs/libcurl/opts/CURLOPT_SASL_IR.3 +++ b/docs/libcurl/opts/CURLOPT_SASL_IR.3 @@ -52,12 +52,16 @@ SASL-IR CAPABILITY. IMAP, POP3 and SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); - curl_easy_setopt(curl, CURLOPT_SASL_IR, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "smtp://example.com/"); + curl_easy_setopt(curl, CURLOPT_SASL_IR, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SEEKDATA.3 b/docs/libcurl/opts/CURLOPT_SEEKDATA.3 index 8810115a3..eed02af19 100644 --- a/docs/libcurl/opts/CURLOPT_SEEKDATA.3 +++ b/docs/libcurl/opts/CURLOPT_SEEKDATA.3 @@ -40,6 +40,12 @@ If you do not set this, NULL is passed to the callback. HTTP, FTP, SFTP .SH EXAMPLE .nf +#include /* for lseek() */ + +struct data { + int our_fd; +}; + static int seek_cb(void *clientp, curl_off_t offset, int origin) { struct data *d = (struct data *)clientp; @@ -47,10 +53,14 @@ static int seek_cb(void *clientp, curl_off_t offset, int origin) return CURL_SEEKFUNC_OK; } +int main(void) { struct data seek_data; - curl_easy_setopt(CURL *handle, CURLOPT_SEEKFUNCTION, seek_cb); - curl_easy_setopt(CURL *handle, CURLOPT_SEEKDATA, &seek_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_cb); + curl_easy_setopt(curl, CURLOPT_SEEKDATA, &seek_data); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SEEKFUNCTION.3 b/docs/libcurl/opts/CURLOPT_SEEKFUNCTION.3 index 1e000bd8a..649eb2ae2 100644 --- a/docs/libcurl/opts/CURLOPT_SEEKFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_SEEKFUNCTION.3 @@ -70,17 +70,26 @@ By default, this is NULL and unused. HTTP, FTP, SFTP .SH EXAMPLE .nf +#include /* for lseek */ + +struct data { + int our_fd; +}; static int seek_cb(void *clientp, curl_off_t offset, int origin) { struct data *d = (struct data *)clientp; - lseek(our_fd, offset, origin); + lseek(d->our_fd, offset, origin); return CURL_SEEKFUNC_OK; } +int main(void) { struct data seek_data; - curl_easy_setopt(CURL *handle, CURLOPT_SEEKFUNCTION, seek_cb); - curl_easy_setopt(CURL *handle, CURLOPT_SEEKDATA, &seek_data); + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_cb); + curl_easy_setopt(curl, CURLOPT_SEEKDATA, &seek_data); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SERVER_RESPONSE_TIMEOUT.3 b/docs/libcurl/opts/CURLOPT_SERVER_RESPONSE_TIMEOUT.3 index 0628b374c..72b2a6264 100644 --- a/docs/libcurl/opts/CURLOPT_SERVER_RESPONSE_TIMEOUT.3 +++ b/docs/libcurl/opts/CURLOPT_SERVER_RESPONSE_TIMEOUT.3 @@ -48,14 +48,18 @@ None FTP, IMAP, POP3, SMTP, and SSH .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/slow.txt"); - /* wait no more than 23 seconds */ - curl_easy_setopt(curl, CURLOPT_SERVER_RESPONSE_TIMEOUT, 23L); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/slow.txt"); + /* wait no more than 23 seconds */ + curl_easy_setopt(curl, CURLOPT_SERVER_RESPONSE_TIMEOUT, 23L); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SERVICE_NAME.3 b/docs/libcurl/opts/CURLOPT_SERVICE_NAME.3 index 2c3f70f2d..02d18494d 100644 --- a/docs/libcurl/opts/CURLOPT_SERVICE_NAME.3 +++ b/docs/libcurl/opts/CURLOPT_SERVICE_NAME.3 @@ -45,12 +45,15 @@ See above HTTP, FTP, IMAP, LDAP, POP3 and SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SERVICE_NAME, "custom"); - ret = curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SERVICE_NAME, "custom"); + ret = curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SHARE.3 b/docs/libcurl/opts/CURLOPT_SHARE.3 index ec481e561..22a662ac6 100644 --- a/docs/libcurl/opts/CURLOPT_SHARE.3 +++ b/docs/libcurl/opts/CURLOPT_SHARE.3 @@ -55,26 +55,30 @@ NULL All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -CURL *curl2 = curl_easy_init(); /* a second handle */ -if(curl) { - CURLSH *shobject = curl_share_init(); - curl_share_setopt(shobject, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); +int main(void) +{ + CURL *curl = curl_easy_init(); + CURL *curl2 = curl_easy_init(); /* a second handle */ + if(curl) { + CURLcode res; + CURLSH *shobject = curl_share_init(); + curl_share_setopt(shobject, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); - curl_easy_setopt(curl, CURLOPT_SHARE, shobject); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); + curl_easy_setopt(curl, CURLOPT_SHARE, shobject); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); - /* the second handle shares cookies from the first */ - curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/second"); - curl_easy_setopt(curl2, CURLOPT_COOKIEFILE, ""); - curl_easy_setopt(curl2, CURLOPT_SHARE, shobject); - ret = curl_easy_perform(curl2); - curl_easy_cleanup(curl2); + /* the second handle shares cookies from the first */ + curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/second"); + curl_easy_setopt(curl2, CURLOPT_COOKIEFILE, ""); + curl_easy_setopt(curl2, CURLOPT_SHARE, shobject); + res = curl_easy_perform(curl2); + curl_easy_cleanup(curl2); - curl_share_cleanup(shobject); + curl_share_cleanup(shobject); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SOCKOPTDATA.3 b/docs/libcurl/opts/CURLOPT_SOCKOPTDATA.3 index c63504a99..f671aa989 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKOPTDATA.3 +++ b/docs/libcurl/opts/CURLOPT_SOCKOPTDATA.3 @@ -44,23 +44,28 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, curlsocktype purpose) { int val = *(int *)clientp; - setsockopt(curldfd, SOL_SOCKET, SO_RCVBUF, (const char *)&val, sizeof(val)); + setsockopt((int)curlfd, SOL_SOCKET, SO_RCVBUF, + (const char *)&val, sizeof(val)); return CURL_SOCKOPT_OK; } -curl = curl_easy_init(); -if(curl) { - int recvbuffersize = 256 * 1024; +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + int recvbuffersize = 256 * 1024; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* call this function to set options for the socket */ - curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); - curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, &recvbuffersize); + /* call this function to set options for the socket */ + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, &recvbuffersize); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.3 b/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.3 index 107d68a6a..269490f85 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_SOCKOPTFUNCTION.3 @@ -100,21 +100,27 @@ static int sockopt_callback(void *clientp, curl_socket_t curlfd, return CURL_SOCKOPT_ALREADY_CONNECTED; } -curl = curl_easy_init(); -if(curl) { - /* libcurl thinks that you connect to the host - * and port that you specify in the URL option. */ - curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); - /* call this function to get a socket */ - curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); - curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + int sockfd; /* our custom file descriptor */ + /* libcurl thinks that you connect to the host + * and port that you specify in the URL option. */ + curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); + /* call this function to get a socket */ + curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); + curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); - /* call this function to set options for the socket */ - curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + /* call this function to set options for the socket */ + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); - res = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } +} .fi .SH AVAILABILITY Added in 7.16.0. The \fICURL_SOCKOPT_ALREADY_CONNECTED\fP return code was diff --git a/docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3 b/docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3 index 6ee8c30c1..d2276cffc 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3 +++ b/docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3 @@ -44,18 +44,21 @@ CURLAUTH_BASIC|CURLAUTH_GSSAPI All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* request to use a SOCKS5 proxy */ - curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://user:pass@myproxy.com"); + /* request to use a SOCKS5 proxy */ + curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://user:pass@myproxy.com"); - /* enable username/password authentication only */ - curl_easy_setopt(curl, CURLOPT_SOCKS5_AUTH, (long)CURLAUTH_BASIC); + /* enable username/password authentication only */ + curl_easy_setopt(curl, CURLOPT_SOCKS5_AUTH, (long)CURLAUTH_BASIC); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_NEC.3 b/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_NEC.3 index a8829a7ff..bc9ea693d 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_NEC.3 +++ b/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_NEC.3 @@ -43,13 +43,17 @@ negotiation. Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://proxy"); - curl_easy_setopt(curl, CURLOPT_SOCKS5_GSSAPI_NEC, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://proxy"); + curl_easy_setopt(curl, CURLOPT_SOCKS5_GSSAPI_NEC, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.3 b/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.3 index f22aa12fc..c5b32ec2a 100644 --- a/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.3 +++ b/docs/libcurl/opts/CURLOPT_SOCKS5_GSSAPI_SERVICE.3 @@ -47,13 +47,17 @@ See above All network protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://proxy"); - curl_easy_setopt(curl, CURLOPT_SOCKS5_GSSAPI_SERVICE, "rcmd-special"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://proxy"); + curl_easy_setopt(curl, CURLOPT_SOCKS5_GSSAPI_SERVICE, "rcmd-special"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_AUTH_TYPES.3 b/docs/libcurl/opts/CURLOPT_SSH_AUTH_TYPES.3 index e125429b5..a6c16c846 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_AUTH_TYPES.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_AUTH_TYPES.3 @@ -46,13 +46,17 @@ CURLSSH_AUTH_ANY (all available) SFTP and SCP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); - curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, - CURLSSH_AUTH_PUBLICKEY | CURLSSH_AUTH_KEYBOARD); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); + curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, + CURLSSH_AUTH_PUBLICKEY | CURLSSH_AUTH_KEYBOARD); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_COMPRESSION.3 b/docs/libcurl/opts/CURLOPT_SSH_COMPRESSION.3 index b440f7fb0..9a1fab01d 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_COMPRESSION.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_COMPRESSION.3 @@ -42,15 +42,18 @@ may or may not do it. All SSH based protocols: SCP, SFTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com"); - /* enable built-in compression */ - curl_easy_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L); + /* enable built-in compression */ + curl_easy_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYDATA.3 b/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYDATA.3 index ac13dc6a2..c0a5720c5 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYDATA.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYDATA.3 @@ -40,21 +40,31 @@ NULL SCP and SFTP .SH EXAMPLE .nf -int hostkeycb(void *clientp, /* passed with CURLOPT_SSH_HOSTKEYDATA */ - int keytype, /* CURLKHTYPE */ - const char * key, /* host key to check */ - size_t keylen); /* length of the key */ +struct mine { + void *custom; +}; + +static int hostkeycb(void *clientp, /* CURLOPT_SSH_HOSTKEYDATA */ + int keytype, /* CURLKHTYPE */ + const char *key, /* host key to check */ + size_t keylen) /* length of the key */ { /* 'clientp' points to the callback_data struct */ /* investigate the situation and return the correct value */ return CURLKHMATCH_OK; } + +int main(void) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); - curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYFUNCTION, hostkeycb); - curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYDATA, &callback_data); + CURL *curl = curl_easy_init(); + if(curl) { + struct mine callback_data; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); + curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYFUNCTION, hostkeycb); + curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYDATA, &callback_data); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYFUNCTION.3 b/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYFUNCTION.3 index 43fa94bf2..132e9e94d 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_HOSTKEYFUNCTION.3 @@ -61,21 +61,30 @@ NULL SCP and SFTP .SH EXAMPLE .nf +struct mine { + void *custom; +}; + int hostkeycb(void *clientp, /* passed with CURLOPT_SSH_HOSTKEYDATA */ int keytype, /* CURLKHTYPE */ - const char * key, /* host key to check */ - size_t keylen); /* length of the key */ + const char *key, /* host key to check */ + size_t keylen) /* length of the key */ { /* 'clientp' points to the callback_data struct */ /* investigate the situation and return the correct value */ return CURLKHMATCH_OK; } +int main(void) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); - curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYFUNCTION, hostkeycb); - curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYDATA, &callback_data); + struct mine callback_data; + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); + curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYFUNCTION, hostkeycb); + curl_easy_setopt(curl, CURLOPT_SSH_HOSTKEYDATA, &callback_data); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 index 30ed2ec16..e0b2586ed 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 @@ -47,13 +47,17 @@ NULL SCP and SFTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); - curl_easy_setopt(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, - "afe17cd62a0f3b61f1ab9cb22ba269a7"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); + curl_easy_setopt(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, + "afe17cd62a0f3b61f1ab9cb22ba269a7"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.3 b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.3 index 2798d14bd..266b7b0ac 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.3 @@ -42,13 +42,17 @@ NULL SCP and SFTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); - curl_easy_setopt(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, - "NDVkMTQxMGQ1ODdmMjQ3MjczYjAyOTY5MmRkMjVmNDQ="); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); + curl_easy_setopt(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, + "NDVkMTQxMGQ1ODdmMjQ3MjczYjAyOTY5MmRkMjVmNDQ="); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_KEYDATA.3 b/docs/libcurl/opts/CURLOPT_SSH_KEYDATA.3 index bfa7b7738..04ae0a557 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_KEYDATA.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_KEYDATA.3 @@ -40,6 +40,9 @@ NULL SFTP and SCP .SH EXAMPLE .nf +struct mine { + void *custom; +}; static int keycb(CURL *easy, const struct curl_khkey *knownkey, const struct curl_khkey *foundkey, @@ -50,13 +53,19 @@ static int keycb(CURL *easy, /* investigate the situation and return the correct value */ return CURLKHSTAT_FINE_ADD_TO_FILE; } + +int main(void) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); - curl_easy_setopt(curl, CURLOPT_SSH_KEYFUNCTION, keycb); - curl_easy_setopt(curl, CURLOPT_SSH_KEYDATA, &callback_data); - curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/home/user/known_hosts"); + CURL *curl = curl_easy_init(); + if(curl) { + struct mine callback_data; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); + curl_easy_setopt(curl, CURLOPT_SSH_KEYFUNCTION, keycb); + curl_easy_setopt(curl, CURLOPT_SSH_KEYDATA, &callback_data); + curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/home/user/known_hosts"); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3 b/docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3 index 7c2585195..1abe37d63 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_KEYFUNCTION.3 @@ -105,6 +105,10 @@ NULL SFTP and SCP .SH EXAMPLE .nf +struct mine { + void *custom; +}; + static int keycb(CURL *easy, const struct curl_khkey *knownkey, const struct curl_khkey *foundkey, @@ -115,13 +119,19 @@ static int keycb(CURL *easy, /* investigate the situation and return the correct value */ return CURLKHSTAT_FINE_ADD_TO_FILE; } + +int main(void) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); - curl_easy_setopt(curl, CURLOPT_SSH_KEYFUNCTION, keycb); - curl_easy_setopt(curl, CURLOPT_SSH_KEYDATA, &callback_data); - curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/home/user/known_hosts"); + CURL *curl = curl_easy_init(); + if(curl) { + struct mine callback_data; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); + curl_easy_setopt(curl, CURLOPT_SSH_KEYFUNCTION, keycb); + curl_easy_setopt(curl, CURLOPT_SSH_KEYDATA, &callback_data); + curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/home/user/known_hosts"); - curl_easy_perform(curl); + curl_easy_perform(curl); +} } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.3 b/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.3 index 419e63ec8..8984fedb7 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_KNOWNHOSTS.3 @@ -47,13 +47,17 @@ NULL SFTP and SCP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); - curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, - "/home/clarkkent/.ssh/known_hosts"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); + curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, + "/home/clarkkent/.ssh/known_hosts"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_PRIVATE_KEYFILE.3 b/docs/libcurl/opts/CURLOPT_SSH_PRIVATE_KEYFILE.3 index 384aae9b5..12cc5410d 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_PRIVATE_KEYFILE.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_PRIVATE_KEYFILE.3 @@ -48,14 +48,18 @@ As explained above SFTP and SCP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); - curl_easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, - "/home/clarkkent/.ssh/id_rsa"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "password"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); + curl_easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, + "/home/clarkkent/.ssh/id_rsa"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "password"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSH_PUBLIC_KEYFILE.3 b/docs/libcurl/opts/CURLOPT_SSH_PUBLIC_KEYFILE.3 index a97aa4c1f..93d9241e0 100644 --- a/docs/libcurl/opts/CURLOPT_SSH_PUBLIC_KEYFILE.3 +++ b/docs/libcurl/opts/CURLOPT_SSH_PUBLIC_KEYFILE.3 @@ -49,13 +49,17 @@ NULL SFTP and SCP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); - curl_easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, - "/home/clarkkent/.ssh/id_rsa.pub"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/file"); + curl_easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, + "/home/clarkkent/.ssh/id_rsa.pub"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLCERT.3 b/docs/libcurl/opts/CURLOPT_SSLCERT.3 index 2727498f4..d3ded42fa 100644 --- a/docs/libcurl/opts/CURLOPT_SSLCERT.3 +++ b/docs/libcurl/opts/CURLOPT_SSLCERT.3 @@ -65,14 +65,18 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.3 b/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.3 index 6c2abd003..e800c5cbd 100644 --- a/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.3 +++ b/docs/libcurl/opts/CURLOPT_SSLCERTTYPE.3 @@ -48,15 +48,19 @@ option. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); + curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.3 b/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.3 index 45510422e..37a53362e 100644 --- a/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.3 @@ -51,18 +51,26 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob stblob; - stblob.data = certificateData; - stblob.len = filesize; - stblob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLCERT_BLOB, &stblob); - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "P12"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); + +extern char *certificateData; /* point to data */ +extern size_t filesize; /* size of data */ + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob stblob; + stblob.data = certificateData; + stblob.len = filesize; + stblob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLCERT_BLOB, &stblob); + curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "P12"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLENGINE.3 b/docs/libcurl/opts/CURLOPT_SSLENGINE.3 index 839f59598..495841da9 100644 --- a/docs/libcurl/opts/CURLOPT_SSLENGINE.3 +++ b/docs/libcurl/opts/CURLOPT_SSLENGINE.3 @@ -43,12 +43,16 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLENGINE, "dynamic"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLENGINE, "dynamic"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLENGINE_DEFAULT.3 b/docs/libcurl/opts/CURLOPT_SSLENGINE_DEFAULT.3 index 00a69d26b..0e904c67f 100644 --- a/docs/libcurl/opts/CURLOPT_SSLENGINE_DEFAULT.3 +++ b/docs/libcurl/opts/CURLOPT_SSLENGINE_DEFAULT.3 @@ -42,13 +42,17 @@ None All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLENGINE, "dynamic"); - curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLENGINE, "dynamic"); + curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLKEY.3 b/docs/libcurl/opts/CURLOPT_SSLKEY.3 index ee85aaff2..7f54c4eaf 100644 --- a/docs/libcurl/opts/CURLOPT_SSLKEY.3 +++ b/docs/libcurl/opts/CURLOPT_SSLKEY.3 @@ -48,14 +48,18 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.3 b/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.3 index 6cb46d104..957d175ea 100644 --- a/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.3 +++ b/docs/libcurl/opts/CURLOPT_SSLKEYTYPE.3 @@ -48,15 +48,19 @@ option. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); - curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); + curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem"); + curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.3 b/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.3 index e43461d3f..8d3f21da3 100644 --- a/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.3 +++ b/docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.3 @@ -49,23 +49,34 @@ NULL All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_blob blob; - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - blob.data = certificateData; - blob.len = filesize; - blob.flags = CURL_BLOB_COPY; - curl_easy_setopt(curl, CURLOPT_SSLCERT_BLOB, &blob); - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); - blob.data = privateKeyData; - blob.len = privateKeySize; - curl_easy_setopt(curl, CURLOPT_SSLKEY_BLOB, &blob); - curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); - curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +extern char *certificateData; /* point to cert */ +extern size_t filesize; /* size of cert */ + +extern char *privateKeyData; /* point to key */ +extern size_t privateKeySize; /* size of key */ + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_blob blob; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + blob.data = certificateData; + blob.len = filesize; + blob.flags = CURL_BLOB_COPY; + curl_easy_setopt(curl, CURLOPT_SSLCERT_BLOB, &blob); + curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); + + blob.data = privateKeyData; + blob.len = privateKeySize; + curl_easy_setopt(curl, CURLOPT_SSLKEY_BLOB, &blob); + curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret"); + curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSLVERSION.3 b/docs/libcurl/opts/CURLOPT_SSLVERSION.3 index e504c0e18..2031b6803 100644 --- a/docs/libcurl/opts/CURLOPT_SSLVERSION.3 +++ b/docs/libcurl/opts/CURLOPT_SSLVERSION.3 @@ -94,15 +94,18 @@ CURL_SSLVERSION_DEFAULT All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* ask libcurl to use TLS version 1.0 or later */ - curl_easy_setopt(curl, CURLOPT_SSLVERSION, (long)CURL_SSLVERSION_TLSv1); + /* ask libcurl to use TLS version 1.0 or later */ + curl_easy_setopt(curl, CURLOPT_SSLVERSION, (long)CURL_SSLVERSION_TLSv1); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3 b/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3 index 87626feba..8196b5529 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.3 @@ -67,12 +67,16 @@ NULL, use internal default All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "TLSv1"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "TLSv1"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.3 b/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.3 index 5dcf059e7..6abe2a9bf 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_CTX_DATA.3 @@ -59,7 +59,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) * X509 structure that SSL can use */ PEM_read_bio_X509(bio, &cert, 0, NULL); - if(cert == NULL) + if(!cert) printf("PEM_read_bio_X509 failed...\\n"); /* get a pointer to the X509 certificate store (which may be empty) */ @@ -79,7 +79,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) int main(void) { - CURL * ch; + CURL *ch; CURLcode rv; char *mypem = /* example CA cert PEM - shortened */ "-----BEGIN CERTIFICATE-----\\n" diff --git a/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.3 b/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.3 index 220f1b992..3ec1c95e5 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_CTX_FUNCTION.3 @@ -101,7 +101,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) * X509 structure that SSL can use */ PEM_read_bio_X509(bio, &cert, 0, NULL); - if(cert == NULL) + if(!cert) printf("PEM_read_bio_X509 failed...\\n"); /* get a pointer to the X509 certificate store (which may be empty) */ @@ -121,7 +121,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm) int main(void) { - CURL * ch; + CURL *ch; CURLcode rv; char *mypem = /* example CA cert PEM - shortened */ "-----BEGIN CERTIFICATE-----\\n" diff --git a/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3 b/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3 index fab363226..65b5407d5 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3 @@ -41,12 +41,16 @@ the SSL backend libcurl is built to use supports it). HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSL_EC_CURVES, "X25519:P-521"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSL_EC_CURVES, "X25519:P-521"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_ENABLE_ALPN.3 b/docs/libcurl/opts/CURLOPT_SSL_ENABLE_ALPN.3 index 748cdb746..346ca32bf 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_ENABLE_ALPN.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_ENABLE_ALPN.3 @@ -41,12 +41,16 @@ is built to use supports it), which can be used to negotiate http2. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.3 b/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.3 index 04286c02c..69fd82671 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_ENABLE_NPN.3 @@ -43,12 +43,16 @@ is built to use supports it), which can be used to negotiate http2. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_SSL_ENABLE_NPN, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_SSL_ENABLE_NPN, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3 b/docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3 index 4d3339e53..34d6633fc 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_FALSESTART.3 @@ -44,11 +44,14 @@ when performing a full handshake. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_SSL_FALSESTART, 1L); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_SSL_FALSESTART, 1L); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 index fc6823875..d131ac5d6 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 @@ -61,12 +61,13 @@ library). If combined with \fICURLSSLOPT_NO_REVOKE\fP, the latter takes precedence. (Added in 7.70.0) .IP CURLSSLOPT_NATIVE_CA Tell libcurl to use the operating system's native CA store for certificate -verification. Works only on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora, -RHEL), macOS, Android and iOS when built to use wolfSSL (since 8.3.0) or on -Windows when built to use OpenSSL. If you set this option and also set a CA -certificate file or directory then during verification those certificates -are searched in addition to the native CA store. -(Added in 7.71.0) +verification. If you set this option and also set a CA certificate file or +directory then during verification those certificates are searched in addition +to the native CA store. + +Works with wolfSSL on Windows, Linux (Debian, Ubuntu, Gentoo, Fedora, RHEL), +macOS, Android and iOS (added in 8.3.0), with GnuTLS (added in 8.5.0) or on +Windows when built to use OpenSSL (Added in 7.71.0). .IP CURLSSLOPT_AUTO_CLIENT_CERT Tell libcurl to automatically locate and use a client certificate for authentication, when requested by the server. This option is only supported @@ -81,14 +82,18 @@ could be a privacy violation and unexpected. All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* weaken TLS only for use with silly servers */ - curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, (long)CURLSSLOPT_ALLOW_BEAST | - CURLSSLOPT_NO_REVOKE); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* weaken TLS only for use with silly servers */ + curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, (long)CURLSSLOPT_ALLOW_BEAST | + CURLSSLOPT_NO_REVOKE); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_SESSIONID_CACHE.3 b/docs/libcurl/opts/CURLOPT_SSL_SESSIONID_CACHE.3 index 3325f3b40..de2839098 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_SESSIONID_CACHE.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_SESSIONID_CACHE.3 @@ -43,13 +43,17 @@ wild that may require you to disable this in order for you to succeed. All TLS-based .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* switch off session-id use! */ - curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* switch off session-id use! */ + curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_VERIFYHOST.3 b/docs/libcurl/opts/CURLOPT_SSL_VERIFYHOST.3 index 1bff9305a..3bdf665de 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_VERIFYHOST.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_VERIFYHOST.3 @@ -90,14 +90,17 @@ may be inaccessible if SNI is not sent. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Set the default value: strict name check please */ - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + /* Set the default value: strict name check please */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_VERIFYPEER.3 b/docs/libcurl/opts/CURLOPT_SSL_VERIFYPEER.3 index e26233e84..a5ec49b0a 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_VERIFYPEER.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_VERIFYPEER.3 @@ -74,14 +74,17 @@ malicious servers. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Set the default value: strict certificate check please */ - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); + /* Set the default value: strict certificate check please */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3 b/docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3 index 8ae2f9b38..0bfe7da12 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3 +++ b/docs/libcurl/opts/CURLOPT_SSL_VERIFYSTATUS.3 @@ -45,13 +45,17 @@ extension, the verification fails. All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - /* ask for OCSP stapling! */ - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + /* ask for OCSP stapling! */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_STDERR.3 b/docs/libcurl/opts/CURLOPT_STDERR.3 index a1574be37..949841dda 100644 --- a/docs/libcurl/opts/CURLOPT_STDERR.3 +++ b/docs/libcurl/opts/CURLOPT_STDERR.3 @@ -45,13 +45,16 @@ stderr All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -FILE *filep = fopen("dump", "wb"); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_STDERR, filep); +int main(void) +{ + CURL *curl = curl_easy_init(); + FILE *filep = fopen("dump", "wb"); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_STDERR, filep); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.3 b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.3 index 9f8e5308b..48276467c 100644 --- a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.3 +++ b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.3 @@ -53,16 +53,19 @@ NULL HTTP/2 .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -CURL *curl2 = curl_easy_init(); /* a second handle */ -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/one"); +int main(void) +{ + CURL *curl = curl_easy_init(); + CURL *curl2 = curl_easy_init(); /* a second handle */ + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/one"); - /* the second depends on the first */ - curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/two"); - curl_easy_setopt(curl2, CURLOPT_STREAM_DEPENDS, curl); + /* the second depends on the first */ + curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/two"); + curl_easy_setopt(curl2, CURLOPT_STREAM_DEPENDS, curl); - /* then add both to a multi handle and transfer them! */ + /* then add both to a multi handle and transfer them! */ + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.3 b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.3 index c8b4cc13c..c84173d85 100644 --- a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.3 +++ b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.3 @@ -56,16 +56,19 @@ NULL HTTP/2 .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -CURL *curl2 = curl_easy_init(); /* a second handle */ -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/one"); +int main(void) +{ + CURL *curl = curl_easy_init(); + CURL *curl2 = curl_easy_init(); /* a second handle */ + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/one"); - /* the second depends on the first */ - curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/two"); - curl_easy_setopt(curl2, CURLOPT_STREAM_DEPENDS_E, curl); + /* the second depends on the first */ + curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/two"); + curl_easy_setopt(curl2, CURLOPT_STREAM_DEPENDS_E, curl); - /* then add both to a multi handle and transfer them! */ + /* then add both to a multi handle and transfer them! */ + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_STREAM_WEIGHT.3 b/docs/libcurl/opts/CURLOPT_STREAM_WEIGHT.3 index 9b3997576..7534d1d59 100644 --- a/docs/libcurl/opts/CURLOPT_STREAM_WEIGHT.3 +++ b/docs/libcurl/opts/CURLOPT_STREAM_WEIGHT.3 @@ -56,17 +56,20 @@ If nothing is set, the HTTP/2 protocol itself uses its own default which is HTTP/2 .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -CURL *curl2 = curl_easy_init(); /* a second handle */ -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/one"); - curl_easy_setopt(curl, CURLOPT_STREAM_WEIGHT, 10L); +int main(void) +{ + CURL *curl = curl_easy_init(); + CURL *curl2 = curl_easy_init(); /* a second handle */ + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/one"); + curl_easy_setopt(curl, CURLOPT_STREAM_WEIGHT, 10L); - /* the second has twice the weight */ - curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/two"); - curl_easy_setopt(curl2, CURLOPT_STREAM_WEIGHT, 20L); + /* the second has twice the weight */ + curl_easy_setopt(curl2, CURLOPT_URL, "https://example.com/two"); + curl_easy_setopt(curl2, CURLOPT_STREAM_WEIGHT, 20L); - /* then add both to a multi handle and transfer them! */ + /* then add both to a multi handle and transfer them! */ + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_SUPPRESS_CONNECT_HEADERS.3 b/docs/libcurl/opts/CURLOPT_SUPPRESS_CONNECT_HEADERS.3 index a47944d11..15b73917d 100644 --- a/docs/libcurl/opts/CURLOPT_SUPPRESS_CONNECT_HEADERS.3 +++ b/docs/libcurl/opts/CURLOPT_SUPPRESS_CONNECT_HEADERS.3 @@ -73,19 +73,22 @@ Content-Type: application/json All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_HEADER, 1L); - curl_easy_setopt(curl, CURLOPT_PROXY, "http://foo:3128"); - curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); - curl_easy_setopt(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS, 1L); + curl_easy_setopt(curl, CURLOPT_HEADER, 1L); + curl_easy_setopt(curl, CURLOPT_PROXY, "http://foo:3128"); + curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); + curl_easy_setopt(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS, 1L); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* always cleanup */ - curl_easy_cleanup(curl); + /* always cleanup */ + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3 b/docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3 index 06da3bf4c..53e0fc59d 100644 --- a/docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3 +++ b/docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3 @@ -46,11 +46,14 @@ Fast Open is also known to be problematic on or across certain networks. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TCP_KEEPALIVE.3 b/docs/libcurl/opts/CURLOPT_TCP_KEEPALIVE.3 index de7a4ce7d..04e3ecb58 100644 --- a/docs/libcurl/opts/CURLOPT_TCP_KEEPALIVE.3 +++ b/docs/libcurl/opts/CURLOPT_TCP_KEEPALIVE.3 @@ -43,20 +43,23 @@ disable keepalive probes All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* enable TCP keep-alive for this transfer */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + /* enable TCP keep-alive for this transfer */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); - /* keep-alive idle time to 120 seconds */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); + /* keep-alive idle time to 120 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); - /* interval time between keep-alive probes: 60 seconds */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); + /* interval time between keep-alive probes: 60 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TCP_KEEPIDLE.3 b/docs/libcurl/opts/CURLOPT_TCP_KEEPIDLE.3 index b99ecdbd2..f845b73c5 100644 --- a/docs/libcurl/opts/CURLOPT_TCP_KEEPIDLE.3 +++ b/docs/libcurl/opts/CURLOPT_TCP_KEEPIDLE.3 @@ -44,20 +44,23 @@ this amount. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* enable TCP keep-alive for this transfer */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + /* enable TCP keep-alive for this transfer */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); - /* set keep-alive idle time to 120 seconds */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); + /* set keep-alive idle time to 120 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); - /* interval time between keep-alive probes: 60 seconds */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); + /* interval time between keep-alive probes: 60 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TCP_KEEPINTVL.3 b/docs/libcurl/opts/CURLOPT_TCP_KEEPINTVL.3 index 86cc83e7e..e3bbbc24d 100644 --- a/docs/libcurl/opts/CURLOPT_TCP_KEEPINTVL.3 +++ b/docs/libcurl/opts/CURLOPT_TCP_KEEPINTVL.3 @@ -43,20 +43,23 @@ this amount. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* enable TCP keep-alive for this transfer */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + /* enable TCP keep-alive for this transfer */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); - /* set keep-alive idle time to 120 seconds */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); + /* set keep-alive idle time to 120 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); - /* interval time between keep-alive probes: 60 seconds */ - curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); + /* interval time between keep-alive probes: 60 seconds */ + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 b/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 index e0b79030e..6166f7847 100644 --- a/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 +++ b/docs/libcurl/opts/CURLOPT_TCP_NODELAY.3 @@ -52,12 +52,15 @@ overdone. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* leave Nagle enabled */ - curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 0); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + /* leave Nagle enabled */ + curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 0); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.3 b/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.3 index 480314ff5..f42e5a42a 100644 --- a/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_TELNETOPTIONS.3 @@ -43,16 +43,20 @@ NULL TELNET .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - struct curl_slist *options; - options = curl_slist_append(NULL, "TTTYPE=vt100"); - options = curl_slist_append(options, "USER=foobar"); - curl_easy_setopt(curl, CURLOPT_URL, "telnet://example.com/"); - curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, options); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); - curl_slist_free_all(options); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + struct curl_slist *options; + options = curl_slist_append(NULL, "TTTYPE=vt100"); + options = curl_slist_append(options, "USER=foobar"); + curl_easy_setopt(curl, CURLOPT_URL, "telnet://example.com/"); + curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, options); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + curl_slist_free_all(options); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TFTP_BLKSIZE.3 b/docs/libcurl/opts/CURLOPT_TFTP_BLKSIZE.3 index b6daf806f..dcd3ea79a 100644 --- a/docs/libcurl/opts/CURLOPT_TFTP_BLKSIZE.3 +++ b/docs/libcurl/opts/CURLOPT_TFTP_BLKSIZE.3 @@ -44,13 +44,17 @@ is used. TFTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "tftp://example.com/bootimage"); - /* try using larger blocks */ - curl_easy_setopt(curl, CURLOPT_TFTP_BLKSIZE, 2048L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "tftp://example.com/bootimage"); + /* try using larger blocks */ + curl_easy_setopt(curl, CURLOPT_TFTP_BLKSIZE, 2048L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TFTP_NO_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_TFTP_NO_OPTIONS.3 index fc3b3b3f8..70d4c3f44 100644 --- a/docs/libcurl/opts/CURLOPT_TFTP_NO_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_TFTP_NO_OPTIONS.3 @@ -49,24 +49,27 @@ size_t write_callback(char *ptr, size_t size, size_t nmemb, void *fp) return fwrite(ptr, size, nmemb, (FILE *)fp); } -CURL *curl = curl_easy_init(); -if(curl) { - FILE *fp = fopen("foo.bin", "wb"); - if(fp) { - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)fp); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + FILE *fp = fopen("foo.bin", "wb"); + if(fp) { + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)fp); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); - curl_easy_setopt(curl, CURLOPT_URL, "tftp://example.com/foo.bin"); + curl_easy_setopt(curl, CURLOPT_URL, "tftp://example.com/foo.bin"); - /* do not send TFTP options requests */ - curl_easy_setopt(curl, CURLOPT_TFTP_NO_OPTIONS, 1L); + /* do not send TFTP options requests */ + curl_easy_setopt(curl, CURLOPT_TFTP_NO_OPTIONS, 1L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); - fclose(fp); + fclose(fp); + } + curl_easy_cleanup(curl); } - curl_easy_cleanup(curl); } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TIMECONDITION.3 b/docs/libcurl/opts/CURLOPT_TIMECONDITION.3 index 4da79f5ef..14c901a16 100644 --- a/docs/libcurl/opts/CURLOPT_TIMECONDITION.3 +++ b/docs/libcurl/opts/CURLOPT_TIMECONDITION.3 @@ -47,19 +47,22 @@ CURL_TIMECOND_NONE (0) HTTP, FTP, RTSP, and FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* January 1, 2020 is 1577833200 */ - curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); + /* January 1, 2020 is 1577833200 */ + curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); - /* If-Modified-Since the above time stamp */ - curl_easy_setopt(curl, CURLOPT_TIMECONDITION, - (long)CURL_TIMECOND_IFMODSINCE); + /* If-Modified-Since the above time stamp */ + curl_easy_setopt(curl, CURLOPT_TIMECONDITION, + (long)CURL_TIMECOND_IFMODSINCE); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TIMEOUT.3 b/docs/libcurl/opts/CURLOPT_TIMEOUT.3 index c9fa4e05e..3d608bab4 100644 --- a/docs/libcurl/opts/CURLOPT_TIMEOUT.3 +++ b/docs/libcurl/opts/CURLOPT_TIMEOUT.3 @@ -67,14 +67,17 @@ Default timeout is 0 (zero) which means it never times out during transfer. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* complete within 20 seconds */ - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L); + /* complete within 20 seconds */ + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TIMEOUT_MS.3 b/docs/libcurl/opts/CURLOPT_TIMEOUT_MS.3 index 4c0936c0f..a829881eb 100644 --- a/docs/libcurl/opts/CURLOPT_TIMEOUT_MS.3 +++ b/docs/libcurl/opts/CURLOPT_TIMEOUT_MS.3 @@ -42,14 +42,17 @@ Default timeout is 0 (zero) which means it never times out during transfer. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* complete within 20000 milliseconds */ - curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 20000L); + /* complete within 20000 milliseconds */ + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 20000L); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TIMEVALUE.3 b/docs/libcurl/opts/CURLOPT_TIMEVALUE.3 index 9cca94228..cf899e0ca 100644 --- a/docs/libcurl/opts/CURLOPT_TIMEVALUE.3 +++ b/docs/libcurl/opts/CURLOPT_TIMEVALUE.3 @@ -45,18 +45,21 @@ instead. HTTP, FTP, RTSP, and FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* January 1, 2020 is 1577833200 */ - curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); + /* January 1, 2020 is 1577833200 */ + curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); - /* If-Modified-Since the above time stamp */ - curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); + /* If-Modified-Since the above time stamp */ + curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TIMEVALUE_LARGE.3 b/docs/libcurl/opts/CURLOPT_TIMEVALUE_LARGE.3 index 75c58a0a3..e3b7759d5 100644 --- a/docs/libcurl/opts/CURLOPT_TIMEVALUE_LARGE.3 +++ b/docs/libcurl/opts/CURLOPT_TIMEVALUE_LARGE.3 @@ -46,18 +46,21 @@ to be used to set dates beyond the year 2038. HTTP, FTP, RTSP, and FILE .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* January 1, 2020 is 1577833200 */ - curl_easy_setopt(curl, CURLOPT_TIMEVALUE_LARGE, (curl_off_t)1577833200); + /* January 1, 2020 is 1577833200 */ + curl_easy_setopt(curl, CURLOPT_TIMEVALUE_LARGE, (curl_off_t)1577833200); - /* If-Modified-Since the above time stamp */ - curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); + /* If-Modified-Since the above time stamp */ + curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.3 b/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.3 index 7e6ec19b0..d7450e154 100644 --- a/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.3 +++ b/docs/libcurl/opts/CURLOPT_TLS13_CIPHERS.3 @@ -53,13 +53,17 @@ NULL, use internal default All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_TLS13_CIPHERS, - "TLS_CHACHA20_POLY1305_SHA256"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_TLS13_CIPHERS, + "TLS_CHACHA20_POLY1305_SHA256"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.3 b/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.3 index 6e77e80ef..3170bff2d 100644 --- a/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.3 +++ b/docs/libcurl/opts/CURLOPT_TLSAUTH_PASSWORD.3 @@ -47,14 +47,18 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_TYPE, "SRP"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "user"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "secret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_TYPE, "SRP"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "user"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "secret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.3 b/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.3 index c69185fbc..ec743c372 100644 --- a/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.3 +++ b/docs/libcurl/opts/CURLOPT_TLSAUTH_TYPE.3 @@ -52,14 +52,18 @@ blank All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_TYPE, "SRP"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "user"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "secret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_TYPE, "SRP"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "user"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "secret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.3 b/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.3 index 47593e923..a604c1ef0 100644 --- a/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.3 +++ b/docs/libcurl/opts/CURLOPT_TLSAUTH_USERNAME.3 @@ -47,14 +47,18 @@ NULL All TLS-based protocols .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_TYPE, "SRP"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "user"); - curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "secret"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_TYPE, "SRP"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "user"); + curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "secret"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TRAILERDATA.3 b/docs/libcurl/opts/CURLOPT_TRAILERDATA.3 index fd7830de5..d35523239 100644 --- a/docs/libcurl/opts/CURLOPT_TRAILERDATA.3 +++ b/docs/libcurl/opts/CURLOPT_TRAILERDATA.3 @@ -39,11 +39,18 @@ NULL HTTP .SH EXAMPLE .nf -/* Assuming we have a CURL handle in the hndl variable. */ +struct MyData { + void *custom; +}; -struct MyData data; - -curl_easy_setopt(hndl, CURLOPT_TRAILERDATA, &data); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct MyData data; + curl_easy_setopt(curl, CURLOPT_TRAILERDATA, &data); + } +} .fi A more complete example can be found in examples/http_trailers.html diff --git a/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.3 b/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.3 index 6c70b5e9c..020bfec9e 100644 --- a/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.3 +++ b/docs/libcurl/opts/CURLOPT_TRANSFERTEXT.3 @@ -47,12 +47,16 @@ simply sets the mode to ASCII and performs a standard transfer. FTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/textfile"); - curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/textfile"); + curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_TRANSFER_ENCODING.3 b/docs/libcurl/opts/CURLOPT_TRANSFER_ENCODING.3 index 9795174b9..c472b7a88 100644 --- a/docs/libcurl/opts/CURLOPT_TRANSFER_ENCODING.3 +++ b/docs/libcurl/opts/CURLOPT_TRANSFER_ENCODING.3 @@ -51,11 +51,14 @@ by both HTTP clients and HTTP servers. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 index 8b988f390..534ae813b 100644 --- a/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 +++ b/docs/libcurl/opts/CURLOPT_UNIX_SOCKET_PATH.3 @@ -56,16 +56,21 @@ Default is NULL, meaning that no Unix domain sockets are used. All protocols except for FILE and FTP are supported in theory. HTTP, IMAP, POP3 and SMTP should in particular work (including their SSL/TLS variants). .SH EXAMPLE -Given that you have an HTTP server running listening on /tmp/httpd.sock, you -can request an HTTP resource with: - .nf - curl_easy_setopt(curl_handle, CURLOPT_UNIX_SOCKET_PATH, "/tmp/httpd.sock"); - curl_easy_setopt(curl_handle, CURLOPT_URL, "http://localhost/"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, "/tmp/httpd.sock"); + curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/"); + + curl_easy_perform(curl); + } +} .fi If you are on Linux and somehow have a need for paths larger than 107 bytes, -you could use the proc filesystem to bypass the limitation: +you can use the proc filesystem to bypass the limitation: .nf int dirfd = open(long_directory_path_to_socket, O_DIRECTORY | O_RDONLY); diff --git a/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.3 b/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.3 index 64fac48e3..d16f4eab5 100644 --- a/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.3 +++ b/docs/libcurl/opts/CURLOPT_UNRESTRICTED_AUTH.3 @@ -57,12 +57,15 @@ redirecting to new hosts. HTTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L); - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_UPKEEP_INTERVAL_MS.3 b/docs/libcurl/opts/CURLOPT_UPKEEP_INTERVAL_MS.3 index 9b3519464..9af2e03ba 100644 --- a/docs/libcurl/opts/CURLOPT_UPKEEP_INTERVAL_MS.3 +++ b/docs/libcurl/opts/CURLOPT_UPKEEP_INTERVAL_MS.3 @@ -51,27 +51,30 @@ CURL_UPKEEP_INTERVAL_DEFAULT (currently defined as 60000L, which is 60 seconds) All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - /* Make a connection to an HTTP/2 server. */ - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* Make a connection to an HTTP/2 server. */ + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* Set the interval to 30000ms / 30s */ - curl_easy_setopt(curl, CURLOPT_UPKEEP_INTERVAL_MS, 30000L); + /* Set the interval to 30000ms / 30s */ + curl_easy_setopt(curl, CURLOPT_UPKEEP_INTERVAL_MS, 30000L); - curl_easy_perform(curl); + curl_easy_perform(curl); - /* Perform more work here. */ + /* Perform more work here. */ - /* While the connection is being held open, curl_easy_upkeep() can be - called. If curl_easy_upkeep() is called and the time since the last - upkeep exceeds the interval, then an HTTP/2 PING is sent. */ - curl_easy_upkeep(curl); + /* While the connection is being held open, curl_easy_upkeep() can be + called. If curl_easy_upkeep() is called and the time since the last + upkeep exceeds the interval, then an HTTP/2 PING is sent. */ + curl_easy_upkeep(curl); - /* Perform more work here. */ + /* Perform more work here. */ - /* always cleanup */ - curl_easy_cleanup(curl); + /* always cleanup */ + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_UPLOAD.3 b/docs/libcurl/opts/CURLOPT_UPLOAD.3 index 14c67d496..e02295e70 100644 --- a/docs/libcurl/opts/CURLOPT_UPLOAD.3 +++ b/docs/libcurl/opts/CURLOPT_UPLOAD.3 @@ -52,25 +52,41 @@ transfer, you must specify the size of the data with Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - /* we want to use our own read function */ - curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); +static size_t read_cb(char *ptr, size_t size, size_t nmemb, void *userdata) +{ + FILE *src = userdata; + /* copy as much data as possible into the 'ptr' buffer, but no more than + 'size' * 'nmemb' bytes! */ + size_t retcode = fread(ptr, size, nmemb, src); - /* enable uploading */ - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + return retcode; +} + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + FILE *src = fopen("local-file", "r"); + curl_off_t fsize; /* set this to the size of the input file */ + + /* we want to use our own read function */ + curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb); + + /* enable uploading */ + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - /* specify target */ - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/to/newfile"); + /* specify target */ + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/to/newfile"); - /* now specify which pointer to pass to our callback */ - curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); + /* now specify which pointer to pass to our callback */ + curl_easy_setopt(curl, CURLOPT_READDATA, src); - /* Set the size of the file to upload */ - curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); + /* Set the size of the file to upload */ + curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); - /* Now run off and do what you have been told! */ - curl_easy_perform(curl); + /* Now run off and do what you have been told! */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_UPLOAD_BUFFERSIZE.3 b/docs/libcurl/opts/CURLOPT_UPLOAD_BUFFERSIZE.3 index f57134680..521daaee1 100644 --- a/docs/libcurl/opts/CURLOPT_UPLOAD_BUFFERSIZE.3 +++ b/docs/libcurl/opts/CURLOPT_UPLOAD_BUFFERSIZE.3 @@ -56,16 +56,20 @@ transfer as that may lead to unintended consequences. All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/foo.bin"); - /* ask libcurl to allocate a larger upload buffer */ - curl_easy_setopt(curl, CURLOPT_UPLOAD_BUFFERSIZE, 120000L); + /* ask libcurl to allocate a larger upload buffer */ + curl_easy_setopt(curl, CURLOPT_UPLOAD_BUFFERSIZE, 120000L); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_URL.3 b/docs/libcurl/opts/CURLOPT_URL.3 index b53025b6d..9ef6913d8 100644 --- a/docs/libcurl/opts/CURLOPT_URL.3 +++ b/docs/libcurl/opts/CURLOPT_URL.3 @@ -113,11 +113,14 @@ User provided URLs can also be made to point to sites that redirect further on All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - - curl_easy_perform(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); + + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_USERAGENT.3 b/docs/libcurl/opts/CURLOPT_USERAGENT.3 index b8955aaec..bcb6a3c63 100644 --- a/docs/libcurl/opts/CURLOPT_USERAGENT.3 +++ b/docs/libcurl/opts/CURLOPT_USERAGENT.3 @@ -44,13 +44,16 @@ NULL, no User-Agent: header is used by default. HTTP, HTTPS .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "Dark Secret Ninja/1.0"); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "Dark Secret Ninja/1.0"); - curl_easy_perform(curl); + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_USERNAME.3 b/docs/libcurl/opts/CURLOPT_USERNAME.3 index d72741e85..a7e25e90b 100644 --- a/docs/libcurl/opts/CURLOPT_USERNAME.3 +++ b/docs/libcurl/opts/CURLOPT_USERNAME.3 @@ -66,15 +66,19 @@ blank Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_USERNAME, "clark"); + curl_easy_setopt(curl, CURLOPT_USERNAME, "clark"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_USERPWD.3 b/docs/libcurl/opts/CURLOPT_USERPWD.3 index cbb1e00b2..c63a98cc1 100644 --- a/docs/libcurl/opts/CURLOPT_USERPWD.3 +++ b/docs/libcurl/opts/CURLOPT_USERPWD.3 @@ -74,15 +74,19 @@ NULL Most .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin"); - curl_easy_setopt(curl, CURLOPT_USERPWD, "clark:kent"); + curl_easy_setopt(curl, CURLOPT_USERPWD, "clark:kent"); - ret = curl_easy_perform(curl); + res = curl_easy_perform(curl); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_USE_SSL.3 b/docs/libcurl/opts/CURLOPT_USE_SSL.3 index 22465755e..837415ad7 100644 --- a/docs/libcurl/opts/CURLOPT_USE_SSL.3 +++ b/docs/libcurl/opts/CURLOPT_USE_SSL.3 @@ -54,15 +54,18 @@ CURLUSESSL_NONE FTP, SMTP, POP3, IMAP, LDAP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/file.ext"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/dir/file.ext"); - /* require use of SSL for this, or fail */ - curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); + /* require use of SSL for this, or fail */ + curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_VERBOSE.3 b/docs/libcurl/opts/CURLOPT_VERBOSE.3 index 003a5eb1e..db1a756a3 100644 --- a/docs/libcurl/opts/CURLOPT_VERBOSE.3 +++ b/docs/libcurl/opts/CURLOPT_VERBOSE.3 @@ -48,15 +48,18 @@ To also get all the protocol data sent and received, consider using the All .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); - /* ask libcurl to show us the verbose output */ - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + /* ask libcurl to show us the verbose output */ + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - /* Perform the request */ - curl_easy_perform(curl); + /* Perform the request */ + curl_easy_perform(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_WILDCARDMATCH.3 b/docs/libcurl/opts/CURLOPT_WILDCARDMATCH.3 index be1c465a4..75c5322f1 100644 --- a/docs/libcurl/opts/CURLOPT_WILDCARDMATCH.3 +++ b/docs/libcurl/opts/CURLOPT_WILDCARDMATCH.3 @@ -86,19 +86,26 @@ Using the rules above, a file name pattern can be constructed: This feature is only supported for FTP download. .SH EXAMPLE .nf -/* initialization of easy handle */ -handle = curl_easy_init(); -/* turn on wildcard matching */ -curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L); +extern long begin_cb(struct curl_fileinfo *, void *, int); +extern long end_cb(void *ptr); -/* callback is called before download of concrete file started */ -curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + /* turn on wildcard matching */ + curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); -/* callback is called after data from the file have been transferred */ -curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded); + /* callback is called before download of concrete file started */ + curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, begin_cb); -/* See more on https://curl.se/libcurl/c/ftp-wildcard.html */ + /* callback is called after data from the file have been transferred */ + curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, end_cb); + + /* See more on https://curl.se/libcurl/c/ftp-wildcard.html */ + } +} .fi .SH AVAILABILITY Added in 7.21.0 diff --git a/docs/libcurl/opts/CURLOPT_WRITEFUNCTION.3 b/docs/libcurl/opts/CURLOPT_WRITEFUNCTION.3 index 083b008b4..d992bde20 100644 --- a/docs/libcurl/opts/CURLOPT_WRITEFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_WRITEFUNCTION.3 @@ -63,7 +63,8 @@ that amount differs from the amount passed to your callback function, it signals an error condition to the library. This causes the transfer to get aborted and the libcurl function used returns \fICURLE_WRITE_ERROR\fP. -You can also abort the transfer by returning CURL_WRITEFUNC_ERROR. (7.87.0) +You can also abort the transfer by returning CURL_WRITEFUNC_ERROR (added in +7.87.0), which makes \fICURLE_WRITE_ERROR\fP get returned. If the callback function returns CURL_WRITEFUNC_PAUSE it pauses this transfer. See \fIcurl_easy_pause(3)\fP for further details. @@ -80,6 +81,9 @@ libcurl uses 'fwrite' as a callback by default. For all protocols .SH EXAMPLE .nf +#include /* for realloc */ +#include /* for memcpy */ + struct memory { char *response; size_t size; @@ -91,7 +95,7 @@ static size_t cb(void *data, size_t size, size_t nmemb, void *clientp) struct memory *mem = (struct memory *)clientp; char *ptr = realloc(mem->response, mem->size + realsize + 1); - if(ptr == NULL) + if(!ptr) return 0; /* out of memory! */ mem->response = ptr; @@ -102,25 +106,26 @@ static size_t cb(void *data, size_t size, size_t nmemb, void *clientp) return realsize; } -struct memory chunk = {0}; -CURLcode res; -CURL *curl_handle = curl_easy_init(); - -if (curl_handle) +int main(void) { - /* send all data to this function */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, cb); + struct memory chunk = {0}; + CURLcode res; + CURL *curl = curl_easy_init(); + if(curl) { + /* send all data to this function */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb); - /* we pass our 'chunk' struct to the callback function */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); + /* we pass our 'chunk' struct to the callback function */ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); - /* send a request */ - res = curl_easy_perform(curl_handle); + /* send a request */ + res = curl_easy_perform(curl); - /* remember to free the buffer */ - free(chunk.response); + /* remember to free the buffer */ + free(chunk.response); - curl_easy_cleanup(curl_handle); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_WS_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_WS_OPTIONS.3 index 8321ec66b..3031b9524 100644 --- a/docs/libcurl/opts/CURLOPT_WS_OPTIONS.3 +++ b/docs/libcurl/opts/CURLOPT_WS_OPTIONS.3 @@ -52,13 +52,17 @@ application. WebSocket .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "ws://example.com/"); - /* tell curl we deal with all the WebSocket magic ourselves */ - curl_easy_setopt(curl, CURLOPT_WS_OPTIONS, (long)CURLWS_RAW_MODE); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "ws://example.com/"); + /* tell curl we deal with all the WebSocket magic ourselves */ + curl_easy_setopt(curl, CURLOPT_WS_OPTIONS, (long)CURLWS_RAW_MODE); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLOPT_XFERINFODATA.3 b/docs/libcurl/opts/CURLOPT_XFERINFODATA.3 index 5f04f9671..4a03b9ccf 100644 --- a/docs/libcurl/opts/CURLOPT_XFERINFODATA.3 +++ b/docs/libcurl/opts/CURLOPT_XFERINFODATA.3 @@ -42,30 +42,35 @@ The default value of this parameter is NULL. All .SH EXAMPLE .nf - struct progress { - char *private; - size_t size; - }; +struct progress { + char *private; + size_t size; +}; - static size_t progress_callback(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow) - { - struct memory *progress = (struct progress *)clientp; +static size_t progress_cb(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow) +{ + struct progress *memory = clientp; + printf("private ptr: %p\\n", memory->private); + /* use the values */ - /* use the values */ + return 0; /* all is good */ +} - return 0; /* all is good */ - } +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct progress data; - struct progress data; - - /* pass struct to callback */ - curl_easy_setopt(curl_handle, CURLOPT_XFERINFODATA, &data); - - curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, progress_callback); + /* pass struct to callback */ + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &data); + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_cb); + } +} .fi .SH AVAILABILITY Added in 7.32.0 diff --git a/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.3 b/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.3 index f339eed81..61521f391 100644 --- a/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.3 +++ b/docs/libcurl/opts/CURLOPT_XFERINFOFUNCTION.3 @@ -81,30 +81,37 @@ users. All .SH EXAMPLE .nf - struct progress { - char *private; - size_t size; - }; - - static size_t progress_callback(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow) - { - struct progress *memory = (struct progress *)clientp; - - /* use the values */ - - return 0; /* all is good */ - } - - struct progress data; - - /* pass struct to callback */ - curl_easy_setopt(curl_handle, CURLOPT_XFERINFODATA, &data); - - curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, progress_callback); +struct progress { + char *private; + size_t size; +}; + +static size_t progress_callback(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow) +{ + struct progress *memory = clientp; + printf("my ptr: %p\\n", memory->private); + + /* use the values */ + + return 0; /* all is good */ +} + +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + struct progress data; + + /* pass struct to callback */ + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &data); + + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback); + } +} .fi .SH AVAILABILITY Added in 7.32.0. This callback replaces \fICURLOPT_PROGRESSFUNCTION(3)\fP diff --git a/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.3 b/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.3 index f495ac935..0dc5242fd 100644 --- a/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.3 +++ b/docs/libcurl/opts/CURLOPT_XOAUTH2_BEARER.3 @@ -47,12 +47,16 @@ NULL HTTP, IMAP, LDAP, POP3 and SMTP .SH EXAMPLE .nf -CURL *curl = curl_easy_init(); -if(curl) { - curl_easy_setopt(curl, CURLOPT_URL, "pop3://example.com/"); - curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "1ab9cb22ba269a7"); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); +int main(void) +{ + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode res; + curl_easy_setopt(curl, CURLOPT_URL, "pop3://example.com/"); + curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "1ab9cb22ba269a7"); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } } .fi .SH AVAILABILITY diff --git a/docs/libcurl/opts/CURLSHOPT_LOCKFUNC.3 b/docs/libcurl/opts/CURLSHOPT_LOCKFUNC.3 index 8d146eb67..174326cb1 100644 --- a/docs/libcurl/opts/CURLSHOPT_LOCKFUNC.3 +++ b/docs/libcurl/opts/CURLSHOPT_LOCKFUNC.3 @@ -55,11 +55,17 @@ This pointer is not used by libcurl itself. All .SH EXAMPLE .nf +extern void mutex_lock(CURL *handle, curl_lock_data data, + curl_lock_access access, void *clientp); + +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, mutex_lock); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/opts/CURLSHOPT_SHARE.3 b/docs/libcurl/opts/CURLSHOPT_SHARE.3 index d8f5dc87d..49f976040 100644 --- a/docs/libcurl/opts/CURLSHOPT_SHARE.3 +++ b/docs/libcurl/opts/CURLSHOPT_SHARE.3 @@ -86,11 +86,14 @@ Added in 7.88.0 All .SH EXAMPLE .nf +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/opts/CURLSHOPT_UNLOCKFUNC.3 b/docs/libcurl/opts/CURLSHOPT_UNLOCKFUNC.3 index 4b52ef3cb..1994b6fd9 100644 --- a/docs/libcurl/opts/CURLSHOPT_UNLOCKFUNC.3 +++ b/docs/libcurl/opts/CURLSHOPT_UNLOCKFUNC.3 @@ -51,11 +51,16 @@ This pointer is not used by libcurl itself. All .SH EXAMPLE .nf +extern void mutex_unlock(CURL *, curl_lock_data, void *); + +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, mutex_unlock); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/opts/CURLSHOPT_UNSHARE.3 b/docs/libcurl/opts/CURLSHOPT_UNSHARE.3 index d469920e1..e0d252bf3 100644 --- a/docs/libcurl/opts/CURLSHOPT_UNSHARE.3 +++ b/docs/libcurl/opts/CURLSHOPT_UNSHARE.3 @@ -55,11 +55,14 @@ The Public Suffix List is no longer shared. All .SH EXAMPLE .nf +int main(void) +{ CURLSHcode sh; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/opts/CURLSHOPT_USERDATA.3 b/docs/libcurl/opts/CURLSHOPT_USERDATA.3 index 8684fc3fd..cb5347fe9 100644 --- a/docs/libcurl/opts/CURLSHOPT_USERDATA.3 +++ b/docs/libcurl/opts/CURLSHOPT_USERDATA.3 @@ -38,12 +38,19 @@ the \fIclientp\fP argument to the callbacks set with All .SH EXAMPLE .nf +struct secrets { + void *custom; +}; + +int main(void) +{ CURLSHcode sh; struct secrets private_stuff; - share = curl_share_init(); + CURLSH *share = curl_share_init(); sh = curl_share_setopt(share, CURLSHOPT_USERDATA, &private_stuff); if(sh) printf("Error: %s\\n", curl_share_strerror(sh)); +} .fi .SH AVAILABILITY Added in 7.10 diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index 24a954ece..dc0e0629f 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -190,7 +190,7 @@ CURL_VERSION_ZSTD 7.72.0 CURL_WAIT_POLLIN 7.28.0 CURL_WAIT_POLLOUT 7.28.0 CURL_WAIT_POLLPRI 7.28.0 -CURL_WIN32 7.69.0 +CURL_WIN32 7.69.0 - 8.5.0 CURL_WRITEFUNC_ERROR 7.87.0 CURL_WRITEFUNC_PAUSE 7.18.0 CURL_ZERO_TERMINATED 7.56.0 @@ -212,12 +212,12 @@ CURLAUTH_NONE 7.10.6 CURLAUTH_NTLM 7.10.6 CURLAUTH_NTLM_WB 7.22.0 CURLAUTH_ONLY 7.21.3 -CURLCLOSEPOLICY_CALLBACK 7.7 -CURLCLOSEPOLICY_LEAST_RECENTLY_USED 7.7 -CURLCLOSEPOLICY_LEAST_TRAFFIC 7.7 -CURLCLOSEPOLICY_NONE 7.7 -CURLCLOSEPOLICY_OLDEST 7.7 -CURLCLOSEPOLICY_SLOWEST 7.7 +CURLCLOSEPOLICY_CALLBACK 7.7 7.16.1 +CURLCLOSEPOLICY_LEAST_RECENTLY_USED 7.7 7.16.1 +CURLCLOSEPOLICY_LEAST_TRAFFIC 7.7 7.16.1 +CURLCLOSEPOLICY_NONE 7.7 7.16.1 +CURLCLOSEPOLICY_OLDEST 7.7 7.16.1 +CURLCLOSEPOLICY_SLOWEST 7.7 7.16.1 CURLE_ABORTED_BY_CALLBACK 7.1 CURLE_AGAIN 7.18.2 CURLE_ALREADY_COMPLETE 7.7.2 7.8 diff --git a/include/curl/curl.h b/include/curl/curl.h index bf71d82fb..cc24c0506 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -53,28 +53,19 @@ #include "curlver.h" /* libcurl version defines */ #include "system.h" /* determine things run-time */ -/* - * Define CURL_WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \ - !defined(__SYMBIAN32__) -#define CURL_WIN32 -#endif - #include #include -#if (defined(__FreeBSD__) && (__FreeBSD__ >= 2)) || defined(__MidnightBSD__) +#if defined(__FreeBSD__) || defined(__MidnightBSD__) /* Needed for __FreeBSD_version or __MidnightBSD_version symbol definition */ -#include +#include #endif /* The include stuff here below is mainly for time_t! */ #include #include -#if defined(CURL_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) #if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) /* The check above prevents the winsock2 inclusion if winsock.h already was @@ -88,7 +79,7 @@ libc5-based Linux systems. Only include it on systems that are known to require it! */ #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(__minix) || defined(__INTEGRITY) || \ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \ @@ -97,11 +88,11 @@ #include #endif -#if !defined(CURL_WIN32) && !defined(_WIN32_WCE) +#if !defined(_WIN32) && !defined(_WIN32_WCE) #include #endif -#if !defined(CURL_WIN32) +#if !defined(_WIN32) #include #endif @@ -128,7 +119,7 @@ typedef void CURLSH; #ifdef CURL_STATICLIB # define CURL_EXTERN -#elif defined(CURL_WIN32) || defined(__SYMBIAN32__) || \ +#elif defined(_WIN32) || \ (__has_declspec_attribute(dllexport) && \ __has_declspec_attribute(dllimport)) # if defined(BUILDING_LIBCURL) @@ -144,7 +135,7 @@ typedef void CURLSH; #ifndef curl_socket_typedef /* socket typedef */ -#if defined(CURL_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +#if defined(_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) typedef SOCKET curl_socket_t; #define CURL_SOCKET_BAD INVALID_SOCKET #else @@ -3220,6 +3211,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); #include "options.h" #include "header.h" #include "websockets.h" +#include "mprintf.h" /* the typechecker doesn't work in C++ (yet) */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ diff --git a/include/curl/curlver.h b/include/curl/curlver.h index 618975fec..dcf19ae30 100644 --- a/include/curl/curlver.h +++ b/include/curl/curlver.h @@ -32,12 +32,12 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "8.4.0" +#define LIBCURL_VERSION "8.5.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 8 -#define LIBCURL_VERSION_MINOR 4 +#define LIBCURL_VERSION_MINOR 5 #define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier @@ -59,7 +59,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 0x080400 +#define LIBCURL_VERSION_NUM 0x080500 /* * This is the date and time when the full source package was created. The diff --git a/include/curl/system.h b/include/curl/system.h index 97e0d037a..f2554b4a9 100644 --- a/include/curl/system.h +++ b/include/curl/system.h @@ -141,29 +141,6 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T int # endif -#elif defined(__SYMBIAN32__) -# if defined(__EABI__) /* Treat all ARM compilers equally */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__CW32__) -# pragma longlong on -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__VC32__) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - #elif defined(macintosh) # include # if TYPE_LONGLONG @@ -201,9 +178,10 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T int #elif defined(__MINGW32__) +# include # define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_CURL_OFF_T PRId64 +# define CURL_FORMAT_CURL_OFF_TU PRIu64 # define CURL_SUFFIX_CURL_OFF_T LL # define CURL_SUFFIX_CURL_OFF_TU ULL # define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t @@ -370,7 +348,14 @@ /* ===================================== */ #elif defined(_MSC_VER) -# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# if (_MSC_VER >= 1800) +# include +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T PRId64 +# define CURL_FORMAT_CURL_OFF_TU PRIu64 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# elif (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) # define CURL_TYPEOF_CURL_OFF_T __int64 # define CURL_FORMAT_CURL_OFF_T "I64d" # define CURL_FORMAT_CURL_OFF_TU "I64u" diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 6f849199c..51d52578e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -47,20 +47,25 @@ if(USE_ARES) include_directories(${CARES_INCLUDE_DIR}) endif() -add_library( - curlu # special libcurlu library just for unittests - STATIC - EXCLUDE_FROM_ALL - ${HHEADERS} ${CSOURCES} -) -target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB) +if(BUILD_TESTING) + add_library( + curlu # special libcurlu library just for unittests + STATIC + EXCLUDE_FROM_ALL + ${HHEADERS} ${CSOURCES} + ) + target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB) +endif() if(ENABLE_CURLDEBUG) # We must compile these sources separately to avoid memdebug.h redefinitions # applying to them. set_source_files_properties(memdebug.c curl_multibyte.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) endif() -target_link_libraries(curlu PRIVATE ${CURL_LIBS}) + +if(BUILD_TESTING) + target_link_libraries(curlu PRIVATE ${CURL_LIBS}) +endif() transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake") include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake) diff --git a/lib/Makefile.am b/lib/Makefile.am index 3c0a70912..1237c8e99 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -110,7 +110,7 @@ libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING) endif libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) -libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS) +libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(CURL_LDFLAGS_LIB) $(LIBCURL_LIBS) libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS diff --git a/lib/Makefile.mk b/lib/Makefile.mk index 5071600b5..1513cafef 100644 --- a/lib/Makefile.mk +++ b/lib/Makefile.mk @@ -145,7 +145,10 @@ ifneq ($(findstring -rtmp,$(CFG)),) CPPFLAGS += -DUSE_LIBRTMP CPPFLAGS += -I"$(LIBRTMP_PATH)" _LDFLAGS += -L"$(LIBRTMP_PATH)/librtmp" - _LIBS += -lrtmp -lwinmm + _LIBS += -lrtmp + ifdef WIN32 + _LIBS += -lwinmm + endif ZLIB := 1 endif diff --git a/lib/altsvc.c b/lib/altsvc.c index 22b0b69c7..35450d6b1 100644 --- a/lib/altsvc.c +++ b/lib/altsvc.c @@ -97,7 +97,7 @@ static struct altsvc *altsvc_createid(const char *srchost, unsigned int srcport, unsigned int dstport) { - struct altsvc *as = calloc(sizeof(struct altsvc), 1); + struct altsvc *as = calloc(1, sizeof(struct altsvc)); size_t hlen; size_t dlen; if(!as) @@ -123,15 +123,13 @@ static struct altsvc *altsvc_createid(const char *srchost, dlen -= 2; } - as->src.host = Curl_memdup(srchost, hlen + 1); + as->src.host = Curl_strndup(srchost, hlen); if(!as->src.host) goto error; - as->src.host[hlen] = 0; - as->dst.host = Curl_memdup(dsthost, dlen + 1); + as->dst.host = Curl_strndup(dsthost, dlen); if(!as->dst.host) goto error; - as->dst.host[dlen] = 0; as->src.alpnid = srcalpnid; as->dst.alpnid = dstalpnid; @@ -301,7 +299,7 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp) */ struct altsvcinfo *Curl_altsvc_init(void) { - struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1); + struct altsvcinfo *asi = calloc(1, sizeof(struct altsvcinfo)); if(!asi) return NULL; Curl_llist_init(&asi->list, NULL); diff --git a/lib/arpa_telnet.h b/lib/arpa_telnet.h index de1373800..228b4466e 100644 --- a/lib/arpa_telnet.h +++ b/lib/arpa_telnet.h @@ -56,12 +56,14 @@ static const char * const telnetoptions[]= "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON" }; +#define CURL_TELOPT(x) telnetoptions[x] +#else +#define CURL_TELOPT(x) "" #endif #define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON #define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM) -#define CURL_TELOPT(x) telnetoptions[x] #define CURL_NTELOPTS 40 @@ -103,7 +105,12 @@ static const char * const telnetcmds[]= #define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \ ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) ) + +#ifndef CURL_DISABLE_VERBOSE_STRINGS #define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM] +#else +#define CURL_TELCMD(x) "" +#endif #endif /* CURL_DISABLE_TELNET */ diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index e73e41dab..437c9337f 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -60,13 +60,13 @@ #include "progress.h" #include "timediff.h" -# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ - defined(WIN32) -# define CARES_STATICLIB -# endif -# include -# include /* really old c-ares didn't include this by - itself */ +#if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ + defined(_WIN32) +# define CARES_STATICLIB +#endif +#include +#include /* really old c-ares didn't include this by + itself */ #if ARES_VERSION >= 0x010500 /* c-ares 1.5.0 or later, the callback proto is modified */ @@ -228,9 +228,9 @@ static void destroy_async_data(struct Curl_async *async); void Curl_resolver_cancel(struct Curl_easy *data) { DEBUGASSERT(data); - if(data->state.async.resolver) - ares_cancel((ares_channel)data->state.async.resolver); - destroy_async_data(&data->state.async); + if(data->conn->resolve_async.resolver) + ares_cancel((ares_channel)data->conn->resolve_async.resolver); + destroy_async_data(&data->conn->resolve_async); } /* @@ -278,14 +278,14 @@ int Curl_resolver_getsock(struct Curl_easy *data, struct timeval timebuf; struct timeval *timeout; long milli; - int max = ares_getsock((ares_channel)data->state.async.resolver, + int max = ares_getsock((ares_channel)data->conn->resolve_async.resolver, (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE); maxtime.tv_sec = CURL_TIMEOUT_RESOLVE; maxtime.tv_usec = 0; - timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime, - &timebuf); + timeout = ares_timeout((ares_channel)data->conn->resolve_async.resolver, + &maxtime, &timebuf); milli = (long)curlx_tvtoms(timeout); if(milli == 0) milli += 10; @@ -313,8 +313,8 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms) int i; int num = 0; - bitmask = ares_getsock((ares_channel)data->state.async.resolver, socks, - ARES_GETSOCK_MAXNUM); + bitmask = ares_getsock((ares_channel)data->conn->resolve_async.resolver, + socks, ARES_GETSOCK_MAXNUM); for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) { pfd[i].events = 0; @@ -344,12 +344,12 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms) if(!nfds) /* Call ares_process() unconditionally here, even if we simply timed out above, as otherwise the ares name resolve won't timeout! */ - ares_process_fd((ares_channel)data->state.async.resolver, ARES_SOCKET_BAD, - ARES_SOCKET_BAD); + ares_process_fd((ares_channel)data->conn->resolve_async.resolver, + ARES_SOCKET_BAD, ARES_SOCKET_BAD); else { /* move through the descriptors and ask for processing on them */ for(i = 0; i < num; i++) - ares_process_fd((ares_channel)data->state.async.resolver, + ares_process_fd((ares_channel)data->conn->resolve_async.resolver, (pfd[i].revents & (POLLRDNORM|POLLIN))? pfd[i].fd:ARES_SOCKET_BAD, (pfd[i].revents & (POLLWRNORM|POLLOUT))? @@ -368,7 +368,7 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms) CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, struct Curl_dns_entry **dns) { - struct thread_data *res = data->state.async.tdata; + struct thread_data *res = data->conn->resolve_async.tdata; CURLcode result = CURLE_OK; DEBUGASSERT(dns); @@ -397,7 +397,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, ARES_ECANCELLED synchronously for all pending responses. This will leave us with res->num_pending == 0, which is perfect for the next block. */ - ares_cancel((ares_channel)data->state.async.resolver); + ares_cancel((ares_channel)data->conn->resolve_async.resolver); DEBUGASSERT(res->num_pending == 0); } #endif @@ -408,12 +408,12 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, them */ res->temp_ai = NULL; - if(!data->state.async.dns) + if(!data->conn->resolve_async.dns) result = Curl_resolver_error(data); else - *dns = data->state.async.dns; + *dns = data->conn->resolve_async.dns; - destroy_async_data(&data->state.async); + destroy_async_data(&data->conn->resolve_async); } return result; @@ -464,7 +464,8 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, store.tv_sec = itimeout/1000; store.tv_usec = (itimeout%1000)*1000; - tvp = ares_timeout((ares_channel)data->state.async.resolver, &store, &tv); + tvp = ares_timeout((ares_channel)data->conn->resolve_async.resolver, + &store, &tv); /* use the timeout period ares returned to us above if less than one second is left, otherwise just use 1000ms to make sure the progress @@ -478,7 +479,7 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, return CURLE_UNRECOVERABLE_POLL; result = Curl_resolver_is_resolved(data, entry); - if(result || data->state.async.done) + if(result || data->conn->resolve_async.done) break; if(Curl_pgrsUpdate(data)) @@ -499,12 +500,12 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, } if(result) /* failure, so we cancel the ares operation */ - ares_cancel((ares_channel)data->state.async.resolver); + ares_cancel((ares_channel)data->conn->resolve_async.resolver); /* Operation complete, if the lookup was successful we now have the entry in the cache. */ if(entry) - *entry = data->state.async.dns; + *entry = data->conn->resolve_async.dns; if(result) /* close the connection, since we can't return failure here without @@ -571,12 +572,13 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */ be valid so only defer it when we know the 'status' says its fine! */ return; - res = data->state.async.tdata; + res = data->conn->resolve_async.tdata; if(res) { res->num_pending--; if(CURL_ASYNC_SUCCESS == status) { - struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->state.async.port); + struct Curl_addrinfo *ai = Curl_he2ai(hostent, + data->conn->resolve_async.port); if(ai) { compound_results(res, ai); } @@ -727,14 +729,16 @@ static void addrinfo_cb(void *arg, int status, int timeouts, struct ares_addrinfo *result) { struct Curl_easy *data = (struct Curl_easy *)arg; - struct thread_data *res = data->state.async.tdata; - (void)timeouts; - if(ARES_SUCCESS == status) { - res->temp_ai = ares2addr(result->nodes); - res->last_status = CURL_ASYNC_SUCCESS; - ares_freeaddrinfo(result); + if(data->conn) { + struct thread_data *res = data->conn->resolve_async.tdata; + (void)timeouts; + if(ARES_SUCCESS == status) { + res->temp_ai = ares2addr(result->nodes); + res->last_status = CURL_ASYNC_SUCCESS; + ares_freeaddrinfo(result); + } + res->num_pending--; } - res->num_pending--; } #endif @@ -755,15 +759,15 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, size_t namelen = strlen(hostname); *waitp = 0; /* default to synchronous response */ - res = calloc(sizeof(struct thread_data) + namelen, 1); + res = calloc(1, sizeof(struct thread_data) + namelen); if(res) { strcpy(res->hostname, hostname); - data->state.async.hostname = res->hostname; - data->state.async.port = port; - data->state.async.done = FALSE; /* not done */ - data->state.async.status = 0; /* clear */ - data->state.async.dns = NULL; /* clear */ - data->state.async.tdata = res; + data->conn->resolve_async.hostname = res->hostname; + data->conn->resolve_async.port = port; + data->conn->resolve_async.done = FALSE; /* not done */ + data->conn->resolve_async.status = 0; /* clear */ + data->conn->resolve_async.dns = NULL; /* clear */ + data->conn->resolve_async.tdata = res; /* initial status - failed */ res->last_status = ARES_ENOTFOUND; @@ -793,8 +797,8 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, hints.ai_flags = ARES_AI_NUMERICSERV; msnprintf(service, sizeof(service), "%d", port); res->num_pending = 1; - ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname, - service, &hints, addrinfo_cb, data); + ares_getaddrinfo((ares_channel)data->conn->resolve_async.resolver, + hostname, service, &hints, addrinfo_cb, data); } #else @@ -804,10 +808,10 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, res->num_pending = 2; /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, - PF_INET, query_completed_cb, data); - ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, - PF_INET6, query_completed_cb, data); + ares_gethostbyname((ares_channel)data->conn->resolve_async.resolver, + hostname, PF_INET, query_completed_cb, data); + ares_gethostbyname((ares_channel)data->conn->resolve_async.resolver, + hostname, PF_INET6, query_completed_cb, data); } else #endif @@ -815,7 +819,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, res->num_pending = 1; /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.async.resolver, + ares_gethostbyname((ares_channel)data->conn->resolve_async.resolver, hostname, PF_INET, query_completed_cb, data); } @@ -829,6 +833,7 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data, char *servers) { CURLcode result = CURLE_NOT_BUILT_IN; + ares_channel channel, lchannel = NULL; int ares_result; /* If server is NULL or empty, this would purge all DNS servers @@ -841,11 +846,23 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data, return CURLE_OK; #ifdef HAVE_CARES_SERVERS_CSV + if(data->conn) + channel = data->conn->resolve_async.resolver; + else { + /* we are called by setopt on a data without a connection (yet). In that + * case we set the value on a local instance for checking. + * The configured data options are set when the connection for this + * transfer is created. */ + result = Curl_resolver_init(data, (void **)&lchannel); + if(result) + goto out; + channel = lchannel; + } + #ifdef HAVE_CARES_PORTS_CSV - ares_result = ares_set_servers_ports_csv(data->state.async.resolver, - servers); + ares_result = ares_set_servers_ports_csv(channel, servers); #else - ares_result = ares_set_servers_csv(data->state.async.resolver, servers); + ares_result = ares_set_servers_csv(channel, servers); #endif switch(ares_result) { case ARES_SUCCESS: @@ -861,6 +878,9 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data, result = CURLE_BAD_FUNCTION_ARGUMENT; break; } +out: + if(lchannel) + Curl_resolver_cleanup(lchannel); #else /* too old c-ares version! */ (void)data; (void)(ares_result); @@ -872,11 +892,14 @@ CURLcode Curl_set_dns_interface(struct Curl_easy *data, const char *interf) { #ifdef HAVE_CARES_LOCAL_DEV - if(!interf) - interf = ""; - - ares_set_local_dev((ares_channel)data->state.async.resolver, interf); + if(data->conn) { + /* not a setopt test run, set the value */ + if(!interf) + interf = ""; + ares_set_local_dev((ares_channel)data->conn->resolve_async.resolver, + interf); + } return CURLE_OK; #else /* c-ares version too old! */ (void)data; @@ -900,8 +923,11 @@ CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, } } - ares_set_local_ip4((ares_channel)data->state.async.resolver, - ntohl(a4.s_addr)); + if(data->conn) { + /* not a setopt test run, set the value */ + ares_set_local_ip4((ares_channel)data->conn->resolve_async.resolver, + ntohl(a4.s_addr)); + } return CURLE_OK; #else /* c-ares version too old! */ @@ -927,7 +953,10 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, } } - ares_set_local_ip6((ares_channel)data->state.async.resolver, a6); + if(data->conn) { + /* not a setopt test run, set the value */ + ares_set_local_ip6((ares_channel)data->conn->resolve_async.resolver, a6); + } return CURLE_OK; #else /* c-ares version too old! */ diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index a2e294f8f..63414b617 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -136,7 +136,7 @@ static void destroy_async_data(struct Curl_async *); */ void Curl_resolver_cancel(struct Curl_easy *data) { - destroy_async_data(&data->state.async); + destroy_async_data(&data->conn->resolve_async); } /* This function is used to init a threaded resolve */ @@ -173,7 +173,7 @@ struct thread_data { static struct thread_sync_data *conn_thread_sync_data(struct Curl_easy *data) { - return &(data->state.async.tdata->tsd); + return &(data->conn->resolve_async.tdata->tsd); } /* Destroy resolver thread synchronization data */ @@ -196,7 +196,7 @@ void destroy_thread_sync_data(struct thread_sync_data *tsd) * the other end (for reading) is always closed in the parent thread. */ if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { - sclose(tsd->sock_pair[1]); + wakeup_close(tsd->sock_pair[1]); } #endif memset(tsd, 0, sizeof(*tsd)); @@ -233,8 +233,8 @@ int init_thread_sync_data(struct thread_data *td, Curl_mutex_init(tsd->mtx); #ifndef CURL_DISABLE_SOCKETPAIR - /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ - if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { + /* create socket pair or pipe */ + if(wakeup_create(&tsd->sock_pair[0]) < 0) { tsd->sock_pair[0] = CURL_SOCKET_BAD; tsd->sock_pair[1] = CURL_SOCKET_BAD; goto err_exit; @@ -254,7 +254,7 @@ int init_thread_sync_data(struct thread_data *td, err_exit: #ifndef CURL_DISABLE_SOCKETPAIR if(tsd->sock_pair[0] != CURL_SOCKET_BAD) { - sclose(tsd->sock_pair[0]); + wakeup_close(tsd->sock_pair[0]); tsd->sock_pair[0] = CURL_SOCKET_BAD; } #endif @@ -320,7 +320,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { /* DNS has been resolved, signal client task */ buf[0] = 1; - if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { + if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { /* update sock_erro to errno */ tsd->sock_error = SOCKERRNO; } @@ -428,9 +428,9 @@ static bool init_resolve_thread(struct Curl_easy *data, { struct thread_data *td = calloc(1, sizeof(struct thread_data)); int err = ENOMEM; - struct Curl_async *asp = &data->state.async; + struct Curl_async *asp = &data->conn->resolve_async; - data->state.async.tdata = td; + data->conn->resolve_async.tdata = td; if(!td) goto errno_exit; @@ -488,7 +488,7 @@ static CURLcode thread_wait_resolv(struct Curl_easy *data, CURLcode result = CURLE_OK; DEBUGASSERT(data); - td = data->state.async.tdata; + td = data->conn->resolve_async.tdata; DEBUGASSERT(td); DEBUGASSERT(td->thread_hnd != curl_thread_t_null); @@ -500,18 +500,18 @@ static CURLcode thread_wait_resolv(struct Curl_easy *data, else DEBUGASSERT(0); - data->state.async.done = TRUE; + data->conn->resolve_async.done = TRUE; if(entry) - *entry = data->state.async.dns; + *entry = data->conn->resolve_async.dns; - if(!data->state.async.dns && report) + if(!data->conn->resolve_async.dns && report) /* a name was not resolved, report error */ result = Curl_resolver_error(data); - destroy_async_data(&data->state.async); + destroy_async_data(&data->conn->resolve_async); - if(!data->state.async.dns && report) + if(!data->conn->resolve_async.dns && report) connclose(data->conn, "asynch resolve failed"); return result; @@ -524,7 +524,7 @@ static CURLcode thread_wait_resolv(struct Curl_easy *data, */ void Curl_resolver_kill(struct Curl_easy *data) { - struct thread_data *td = data->state.async.tdata; + struct thread_data *td = data->conn->resolve_async.tdata; /* If we're still resolving, we must wait for the threads to fully clean up, unfortunately. Otherwise, we can simply cancel to clean up any resolver @@ -563,7 +563,7 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, struct Curl_dns_entry **entry) { - struct thread_data *td = data->state.async.tdata; + struct thread_data *td = data->conn->resolve_async.tdata; int done = 0; DEBUGASSERT(entry); @@ -581,13 +581,13 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, if(done) { getaddrinfo_complete(data); - if(!data->state.async.dns) { + if(!data->conn->resolve_async.dns) { CURLcode result = Curl_resolver_error(data); - destroy_async_data(&data->state.async); + destroy_async_data(&data->conn->resolve_async); return result; } - destroy_async_data(&data->state.async); - *entry = data->state.async.dns; + destroy_async_data(&data->conn->resolve_async); + *entry = data->conn->resolve_async.dns; } else { /* poll for name lookup done with exponential backoff up to 250ms */ @@ -619,9 +619,9 @@ int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks) int ret_val = 0; timediff_t milli; timediff_t ms; - struct resdata *reslv = (struct resdata *)data->state.async.resolver; + struct resdata *reslv = (struct resdata *)data->conn->resolve_async.resolver; #ifndef CURL_DISABLE_SOCKETPAIR - struct thread_data *td = data->state.async.tdata; + struct thread_data *td = data->conn->resolve_async.tdata; #else (void)socks; #endif @@ -662,7 +662,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, int port, int *waitp) { - struct resdata *reslv = (struct resdata *)data->state.async.resolver; + struct resdata *reslv = (struct resdata *)data->conn->resolve_async.resolver; *waitp = 0; /* default to synchronous response */ @@ -691,7 +691,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, { struct addrinfo hints; int pf = PF_INET; - struct resdata *reslv = (struct resdata *)data->state.async.resolver; + struct resdata *reslv = (struct resdata *)data->conn->resolve_async.resolver; *waitp = 0; /* default to synchronous response */ diff --git a/lib/base64.c b/lib/base64.c index 2a49b5acd..919eb6235 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -31,6 +31,7 @@ !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_CURL) #include "curl/curl.h" #include "warnless.h" diff --git a/lib/c-hyper.c b/lib/c-hyper.c index 5726ff1cc..787d6bbdb 100644 --- a/lib/c-hyper.c +++ b/lib/c-hyper.c @@ -22,6 +22,10 @@ * ***************************************************************************/ +/* Curl's integration with Hyper. This replaces certain functions in http.c, + * based on configuration #defines. This implementation supports HTTP/1.1 but + * not HTTP/2. + */ #include "curl_setup.h" #if !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) @@ -172,17 +176,15 @@ static int hyper_each_header(void *userdata, Curl_debug(data, CURLINFO_HEADER_IN, headp, len); - if(!data->state.hconnect || !data->set.suppress_connect_headers) { - writetype = CLIENTWRITE_HEADER; - if(data->state.hconnect) - writetype |= CLIENTWRITE_CONNECT; - if(data->req.httpcode/100 == 1) - writetype |= CLIENTWRITE_1XX; - result = Curl_client_write(data, writetype, headp, len); - if(result) { - data->state.hresult = CURLE_ABORTED_BY_CALLBACK; - return HYPER_ITER_BREAK; - } + writetype = CLIENTWRITE_HEADER; + if(data->state.hconnect) + writetype |= CLIENTWRITE_CONNECT; + if(data->req.httpcode/100 == 1) + writetype |= CLIENTWRITE_1XX; + result = Curl_client_write(data, writetype, headp, len); + if(result) { + data->state.hresult = CURLE_ABORTED_BY_CALLBACK; + return HYPER_ITER_BREAK; } result = Curl_bump_headersize(data, len, FALSE); @@ -201,7 +203,7 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk) struct SingleRequest *k = &data->req; CURLcode result = CURLE_OK; - if(0 == k->bodywrites++) { + if(0 == k->bodywrites) { bool done = FALSE; #if defined(USE_NTLM) struct connectdata *conn = data->conn; @@ -241,11 +243,6 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk) return HYPER_ITER_BREAK; } } - if(k->ignorebody) - return HYPER_ITER_CONTINUE; - if(0 == len) - return HYPER_ITER_CONTINUE; - Curl_debug(data, CURLINFO_DATA_IN, buf, len); result = Curl_client_write(data, CLIENTWRITE_BODY, buf, len); if(result) { @@ -253,12 +250,6 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk) return HYPER_ITER_BREAK; } - data->req.bytecount += len; - result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount); - if(result) { - data->state.hresult = result; - return HYPER_ITER_BREAK; - } return HYPER_ITER_CONTINUE; } @@ -310,13 +301,14 @@ static CURLcode status_line(struct Curl_easy *data, Curl_debug(data, CURLINFO_HEADER_IN, Curl_dyn_ptr(&data->state.headerb), len); - if(!data->state.hconnect || !data->set.suppress_connect_headers) { - writetype = CLIENTWRITE_HEADER|CLIENTWRITE_STATUS; - result = Curl_client_write(data, writetype, - Curl_dyn_ptr(&data->state.headerb), len); - if(result) - return result; - } + writetype = CLIENTWRITE_HEADER|CLIENTWRITE_STATUS; + if(data->state.hconnect) + writetype |= CLIENTWRITE_CONNECT; + result = Curl_client_write(data, writetype, + Curl_dyn_ptr(&data->state.headerb), len); + if(result) + return result; + result = Curl_bump_headersize(data, len, FALSE); return result; } @@ -551,11 +543,9 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, static CURLcode debug_request(struct Curl_easy *data, const char *method, - const char *path, - bool h2) + const char *path) { - char *req = aprintf("%s %s HTTP/%s\r\n", method, path, - h2?"2":"1.1"); + char *req = aprintf("%s %s HTTP/1.1\r\n", method, path); if(!req) return CURLE_OUT_OF_MEMORY; Curl_debug(data, CURLINFO_HEADER_OUT, req, strlen(req)); @@ -637,7 +627,6 @@ CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers, static CURLcode request_target(struct Curl_easy *data, struct connectdata *conn, const char *method, - bool h2, hyper_request *req) { CURLcode result; @@ -649,26 +638,13 @@ static CURLcode request_target(struct Curl_easy *data, if(result) return result; - if(h2 && hyper_request_set_uri_parts(req, - /* scheme */ - (uint8_t *)data->state.up.scheme, - strlen(data->state.up.scheme), - /* authority */ - (uint8_t *)conn->host.name, - strlen(conn->host.name), - /* path_and_query */ - (uint8_t *)Curl_dyn_uptr(&r), - Curl_dyn_len(&r))) { - failf(data, "error setting uri parts to hyper"); - result = CURLE_OUT_OF_MEMORY; - } - else if(!h2 && hyper_request_set_uri(req, (uint8_t *)Curl_dyn_uptr(&r), + if(hyper_request_set_uri(req, (uint8_t *)Curl_dyn_uptr(&r), Curl_dyn_len(&r))) { failf(data, "error setting uri to hyper"); result = CURLE_OUT_OF_MEMORY; } else - result = debug_request(data, method, Curl_dyn_ptr(&r), h2); + result = debug_request(data, method, Curl_dyn_ptr(&r)); Curl_dyn_free(&r); @@ -899,7 +875,6 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) const char *p_accept; /* Accept: string */ const char *method; Curl_HttpReq httpreq; - bool h2 = FALSE; const char *te = NULL; /* transfer-encoding */ hyper_code rc; @@ -907,6 +882,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) may be parts of the request that is not yet sent, since we can deal with the rest of the request in the PERFORM phase. */ *done = TRUE; + Curl_client_cleanup(data); infof(data, "Time for the Hyper dance"); memset(h, 0, sizeof(struct hyptransfer)); @@ -917,6 +893,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) Curl_http_method(data, conn, &method, &httpreq); + DEBUGASSERT(data->req.bytecount == 0); + /* setup the authentication headers */ { char *pq = NULL; @@ -972,8 +950,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) goto error; } if(conn->alpn == CURL_HTTP_VERSION_2) { - hyper_clientconn_options_http2(options, 1); - h2 = TRUE; + failf(data, "ALPN protocol h2 not supported with Hyper"); + result = CURLE_UNSUPPORTED_PROTOCOL; + goto error; } hyper_clientconn_options_set_preserve_header_case(options, 1); hyper_clientconn_options_set_preserve_header_order(options, 1); @@ -1024,7 +1003,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) } } else { - if(!h2 && !data->state.disableexpect) { + if(!data->state.disableexpect) { data->state.expect100header = TRUE; } } @@ -1035,7 +1014,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) goto error; } - result = request_target(data, conn, method, h2, req); + result = request_target(data, conn, method, req); if(result) goto error; @@ -1056,19 +1035,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(result) goto error; - if(!h2) { - if(data->state.aptr.host) { - result = Curl_hyper_header(data, headers, data->state.aptr.host); - if(result) - goto error; - } - } - else { - /* For HTTP/2, we show the Host: header as if we sent it, to make it look - like for HTTP/1 but it isn't actually sent since :authority is then - used. */ - Curl_debug(data, CURLINFO_HEADER_OUT, data->state.aptr.host, - strlen(data->state.aptr.host)); + if(data->state.aptr.host) { + result = Curl_hyper_header(data, headers, data->state.aptr.host); + if(result) + goto error; } if(data->state.aptr.proxyuserpwd) { diff --git a/lib/cf-h1-proxy.c b/lib/cf-h1-proxy.c index 674802114..2e23b0b9f 100644 --- a/lib/cf-h1-proxy.c +++ b/lib/cf-h1-proxy.c @@ -374,7 +374,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, curl_socket_t tunnelsocket = Curl_conn_cf_get_socket(cf, data); char *linep; size_t perline; - int error; + int error, writetype; #define SELECT_OK 0 #define SELECT_ERROR 1 @@ -386,12 +386,12 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, return CURLE_OK; while(ts->keepon) { - ssize_t gotbytes; + ssize_t nread; char byte; /* Read one byte at a time to avoid a race condition. Wait at most one second before looping to ensure continuous pgrsUpdates. */ - result = Curl_read(data, tunnelsocket, &byte, 1, &gotbytes); + result = Curl_read(data, tunnelsocket, &byte, 1, &nread); if(result == CURLE_AGAIN) /* socket buffer drained, return */ return CURLE_OK; @@ -404,7 +404,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, break; } - if(gotbytes <= 0) { + if(nread <= 0) { if(data->set.proxyauth && data->state.authproxy.avail && data->state.aptr.proxyuserpwd) { /* proxy auth was requested and there was proxy auth available, @@ -437,11 +437,11 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, properly to know when the end of the body is reached */ CHUNKcode r; CURLcode extra; - ssize_t tookcareof = 0; + size_t consumed = 0; /* now parse the chunked piece of data so that we can properly tell when the stream ends */ - r = Curl_httpchunk_read(data, &byte, 1, &tookcareof, &extra); + r = Curl_httpchunk_read(data, &byte, 1, &consumed, &extra); if(r == CHUNKE_STOP) { /* we're done reading chunks! */ infof(data, "chunk reading DONE"); @@ -467,15 +467,12 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, /* output debug if that is requested */ Curl_debug(data, CURLINFO_HEADER_IN, linep, perline); - if(!data->set.suppress_connect_headers) { - /* send the header to the callback */ - int writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT | - (ts->headerlines == 1 ? CLIENTWRITE_STATUS : 0); - - result = Curl_client_write(data, writetype, linep, perline); - if(result) - return result; - } + /* send the header to the callback */ + writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT | + (ts->headerlines == 1 ? CLIENTWRITE_STATUS : 0); + result = Curl_client_write(data, writetype, linep, perline); + if(result) + return result; result = Curl_bump_headersize(data, perline, TRUE); if(result) @@ -502,6 +499,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, else if(ts->chunked_encoding) { CHUNKcode r; CURLcode extra; + size_t consumed = 0; infof(data, "Ignore chunked response-body"); @@ -516,8 +514,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, /* now parse the chunked piece of data so that we can properly tell when the stream ends */ - r = Curl_httpchunk_read(data, linep + 1, 1, &gotbytes, - &extra); + r = Curl_httpchunk_read(data, linep + 1, 1, &consumed, &extra); if(r == CHUNKE_STOP) { /* we're done reading chunks! */ infof(data, "chunk reading DONE"); @@ -1038,31 +1035,29 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf, return result; } -static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf, +static void cf_h1_proxy_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { struct h1_tunnel_state *ts = cf->ctx; - int fds; - fds = cf->next->cft->get_select_socks(cf->next, data, socks); - if(!fds && cf->next->connected && !cf->connected) { + if(!cf->connected) { /* If we are not connected, but the filter "below" is * and not waiting on something, we are tunneling. */ - socks[0] = Curl_conn_cf_get_socket(cf, data); + curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); if(ts) { /* when we've sent a CONNECT to a proxy, we should rather either wait for the socket to become readable to be able to get the response headers or if we're still sending the request, wait for write. */ - if(ts->CONNECT.sending == HTTPSEND_REQUEST) { - return GETSOCK_WRITESOCK(0); - } - return GETSOCK_READSOCK(0); + if(ts->CONNECT.sending == HTTPSEND_REQUEST) + Curl_pollset_set_out_only(data, ps, sock); + else + Curl_pollset_set_in_only(data, ps, sock); } - return GETSOCK_WRITESOCK(0); + else + Curl_pollset_set_out_only(data, ps, sock); } - return fds; } static void cf_h1_proxy_destroy(struct Curl_cfilter *cf, @@ -1093,7 +1088,7 @@ struct Curl_cftype Curl_cft_h1_proxy = { cf_h1_proxy_connect, cf_h1_proxy_close, Curl_cf_http_proxy_get_host, - cf_h1_proxy_get_select_socks, + cf_h1_proxy_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, Curl_cf_def_recv, diff --git a/lib/cf-h2-proxy.c b/lib/cf-h2-proxy.c index dbc895d26..147acdc86 100644 --- a/lib/cf-h2-proxy.c +++ b/lib/cf-h2-proxy.c @@ -688,12 +688,8 @@ static int proxy_h2_on_frame_recv(nghttp2_session *session, * window and *assume* that we treat this like a WINDOW_UPDATE. Some * servers send an explicit WINDOW_UPDATE, but not all seem to do that. * To be safe, we UNHOLD a stream in order not to stall. */ - if((data->req.keepon & KEEP_SEND_HOLD) && - (data->req.keepon & KEEP_SEND)) { - data->req.keepon &= ~KEEP_SEND_HOLD; + if(CURL_WANT_SEND(data)) { drain_tunnel(cf, data, &ctx->tunnel); - CURL_TRC_CF(data, cf, "[%d] un-holding after SETTINGS", - stream_id); } break; case NGHTTP2_GOAWAY: @@ -727,12 +723,8 @@ static int proxy_h2_on_frame_recv(nghttp2_session *session, } break; case NGHTTP2_WINDOW_UPDATE: - if((data->req.keepon & KEEP_SEND_HOLD) && - (data->req.keepon & KEEP_SEND)) { - data->req.keepon &= ~KEEP_SEND_HOLD; - Curl_expire(data, 0, EXPIRE_RUN_NOW); - CURL_TRC_CF(data, cf, "[%d] unpausing after win update", - stream_id); + if(CURL_WANT_SEND(data)) { + drain_tunnel(cf, data, &ctx->tunnel); } break; default: @@ -909,7 +901,6 @@ static CURLcode proxy_h2_submit(int32_t *pstream_id, { struct dynhds h2_headers; nghttp2_nv *nva = NULL; - unsigned int i; int32_t stream_id = -1; size_t nheader; CURLcode result; @@ -920,22 +911,12 @@ static CURLcode proxy_h2_submit(int32_t *pstream_id, if(result) goto out; - nheader = Curl_dynhds_count(&h2_headers); - nva = malloc(sizeof(nghttp2_nv) * nheader); + nva = Curl_dynhds_to_nva(&h2_headers, &nheader); if(!nva) { result = CURLE_OUT_OF_MEMORY; goto out; } - for(i = 0; i < nheader; ++i) { - struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i); - nva[i].name = (unsigned char *)e->name; - nva[i].namelen = e->namelen; - nva[i].value = (unsigned char *)e->value; - nva[i].valuelen = e->valuelen; - nva[i].flags = NGHTTP2_NV_FLAG_NONE; - } - if(read_callback) { nghttp2_data_provider data_prd; @@ -1187,25 +1168,31 @@ 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 int cf_h2_proxy_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *sock) +static void 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; - int bitmap = GETSOCK_BLANK; - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - sock[0] = Curl_conn_cf_get_socket(cf, data); - bitmap |= GETSOCK_READSOCK(0); + curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); + bool want_recv, want_send; - /* HTTP/2 layer wants to send data) AND there's a window to send data in */ - if(nghttp2_session_want_write(ctx->h2) && - nghttp2_session_get_remote_window_size(ctx->h2)) - bitmap |= GETSOCK_WRITESOCK(0); + Curl_pollset_check(data, ps, sock, &want_recv, &want_send); + if(ctx->h2 && (want_recv || want_send)) { + struct cf_call_data save; + bool c_exhaust, s_exhaust; - CF_DATA_RESTORE(cf, save); - return bitmap; + CF_DATA_SAVE(save, cf, data); + c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2); + s_exhaust = ctx->tunnel.stream_id >= 0 && + !nghttp2_session_get_stream_remote_window_size( + ctx->h2, ctx->tunnel.stream_id); + want_recv = (want_recv || c_exhaust || s_exhaust); + want_send = (!s_exhaust && want_send) || + (!c_exhaust && nghttp2_session_want_write(ctx->h2)); + + Curl_pollset_set(data, ps, sock, want_recv, want_send); + CF_DATA_RESTORE(cf, save); + } } static ssize_t h2_handle_tunnel_close(struct Curl_cfilter *cf, @@ -1542,7 +1529,7 @@ struct Curl_cftype Curl_cft_h2_proxy = { cf_h2_proxy_connect, cf_h2_proxy_close, Curl_cf_http_proxy_get_host, - cf_h2_proxy_get_select_socks, + cf_h2_proxy_adjust_pollset, cf_h2_proxy_data_pending, cf_h2_proxy_send, cf_h2_proxy_recv, @@ -1560,7 +1547,7 @@ CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf, CURLcode result = CURLE_OUT_OF_MEMORY; (void)data; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) goto out; diff --git a/lib/cf-haproxy.c b/lib/cf-haproxy.c index 39ac41571..1ca43937b 100644 --- a/lib/cf-haproxy.c +++ b/lib/cf-haproxy.c @@ -171,23 +171,17 @@ static void cf_haproxy_close(struct Curl_cfilter *cf, cf->next->cft->do_close(cf->next, data); } -static int cf_haproxy_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks) +static void cf_haproxy_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { - int fds; - - fds = cf->next->cft->get_select_socks(cf->next, data, socks); - if(!fds && cf->next->connected && !cf->connected) { + if(cf->next->connected && !cf->connected) { /* If we are not connected, but the filter "below" is * and not waiting on something, we are sending. */ - socks[0] = Curl_conn_cf_get_socket(cf, data); - return GETSOCK_WRITESOCK(0); + Curl_pollset_set_out_only(data, ps, Curl_conn_cf_get_socket(cf, data)); } - return fds; } - struct Curl_cftype Curl_cft_haproxy = { "HAPROXY", 0, @@ -196,7 +190,7 @@ struct Curl_cftype Curl_cft_haproxy = { cf_haproxy_connect, cf_haproxy_close, Curl_cf_def_get_host, - cf_haproxy_get_select_socks, + cf_haproxy_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, Curl_cf_def_recv, @@ -214,7 +208,7 @@ static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf, CURLcode result; (void)data; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/cf-https-connect.c b/lib/cf-https-connect.c index be54aec74..b4f33c8e0 100644 --- a/lib/cf-https-connect.c +++ b/lib/cf-https-connect.c @@ -188,9 +188,6 @@ static CURLcode baller_connected(struct Curl_cfilter *cf, #endif infof(data, "using HTTP/2"); break; - case CURL_HTTP_VERSION_1_1: - infof(data, "using HTTP/1.1"); - break; default: infof(data, "using HTTP/1.x"); break; @@ -325,42 +322,25 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf, return result; } -static int cf_hc_get_select_socks(struct Curl_cfilter *cf, +static void cf_hc_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { - struct cf_hc_ctx *ctx = cf->ctx; - size_t i, j, s; - int brc, rc = GETSOCK_BLANK; - curl_socket_t bsocks[MAX_SOCKSPEREASYHANDLE]; - struct cf_hc_baller *ballers[2]; - - if(cf->connected) - return cf->next->cft->get_select_socks(cf->next, data, socks); - - ballers[0] = &ctx->h3_baller; - ballers[1] = &ctx->h21_baller; - for(i = s = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) { - struct cf_hc_baller *b = ballers[i]; - if(!cf_hc_baller_is_active(b)) - continue; - brc = Curl_conn_cf_get_select_socks(b->cf, data, bsocks); - CURL_TRC_CF(data, cf, "get_selected_socks(%s) -> %x", b->name, brc); - if(!brc) - continue; - for(j = 0; j < MAX_SOCKSPEREASYHANDLE && s < MAX_SOCKSPEREASYHANDLE; ++j) { - if((brc & GETSOCK_WRITESOCK(j)) || (brc & GETSOCK_READSOCK(j))) { - socks[s] = bsocks[j]; - if(brc & GETSOCK_WRITESOCK(j)) - rc |= GETSOCK_WRITESOCK(s); - if(brc & GETSOCK_READSOCK(j)) - rc |= GETSOCK_READSOCK(s); - s++; - } + if(!cf->connected) { + struct cf_hc_ctx *ctx = cf->ctx; + struct cf_hc_baller *ballers[2]; + size_t i; + + ballers[0] = &ctx->h3_baller; + ballers[1] = &ctx->h21_baller; + for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) { + struct cf_hc_baller *b = ballers[i]; + if(!cf_hc_baller_is_active(b)) + continue; + 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, "get_selected_socks -> %x", rc); - return rc; } static bool cf_hc_data_pending(struct Curl_cfilter *cf, @@ -455,7 +435,7 @@ struct Curl_cftype Curl_cft_http_connect = { cf_hc_connect, cf_hc_close, Curl_cf_def_get_host, - cf_hc_get_select_socks, + cf_hc_adjust_pollset, cf_hc_data_pending, Curl_cf_def_send, Curl_cf_def_recv, @@ -475,7 +455,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf, CURLcode result = CURLE_OK; (void)data; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/cf-socket.c b/lib/cf-socket.c index ce3f9e943..e42b4a87b 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -81,7 +81,7 @@ #include "memdebug.h" -#if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY) && defined(WIN32) +#if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY) && defined(_WIN32) /* It makes support for IPv4-mapped IPv6 addresses. * Linux kernel, NetBSD, FreeBSD and Darwin: default is off; * Windows Vista and later: default is on; @@ -102,11 +102,7 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd) #if defined(TCP_NODELAY) curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) char buffer[STRERROR_LEN]; -#else - (void) data; -#endif if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, sizeof(onoff)) < 0) @@ -127,6 +123,7 @@ static void nosigpipe(struct Curl_easy *data, curl_socket_t sockfd) { int onoff = 1; + (void)data; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, sizeof(onoff)) < 0) { #if !defined(CURL_DISABLE_VERBOSE_STRINGS) @@ -662,7 +659,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error) int err = 0; curl_socklen_t errSize = sizeof(err); -#ifdef WIN32 +#ifdef _WIN32 /* * In October 2003 we effectively nullified this function on Windows due to * problems with it using all CPU in multi-threaded cases. @@ -883,34 +880,14 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data) struct cf_socket_ctx *ctx = cf->ctx; if(ctx && CURL_SOCKET_BAD != ctx->sock) { - if(ctx->active) { - /* We share our socket at cf->conn->sock[cf->sockindex] when active. - * If it is no longer there, someone has stolen (and hopefully - * closed it) and we just forget about it. - */ - if(ctx->sock == cf->conn->sock[cf->sockindex]) { - CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T - ", active)", ctx->sock); - socket_close(data, cf->conn, !ctx->accepted, ctx->sock); - cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD; - } - else { - CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T - ") no longer at conn->sock[], discarding", ctx->sock); - /* TODO: we do not want this to happen. Need to check which - * code is messing with conn->sock[cf->sockindex] */ - } - ctx->sock = CURL_SOCKET_BAD; - if(cf->sockindex == FIRSTSOCKET) - cf->conn->remote_addr = NULL; - } - else { - /* this is our local socket, we did never publish it */ - CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T - ", not active)", ctx->sock); - socket_close(data, cf->conn, !ctx->accepted, ctx->sock); - ctx->sock = CURL_SOCKET_BAD; - } + CURL_TRC_CF(data, cf, "cf_socket_close(%" CURL_FORMAT_SOCKET_T + ")", ctx->sock); + if(ctx->sock == cf->conn->sock[cf->sockindex]) + 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; Curl_bufq_reset(&ctx->recvbuf); ctx->active = FALSE; ctx->buffer_recv = FALSE; @@ -1169,6 +1146,7 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, *done = FALSE; /* a very negative world view is best */ if(ctx->sock == CURL_SOCKET_BAD) { + int error; result = cf_socket_open(cf, data); if(result) @@ -1181,8 +1159,12 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, /* Connect TCP socket */ rc = do_connect(cf, data, cf->conn->bits.tcp_fastopen); + error = SOCKERRNO; + set_local_ip(cf, data); + CURL_TRC_CF(data, cf, "local address %s port %d...", + ctx->l_ip, ctx->l_port); if(-1 == rc) { - result = socket_connect_result(data, ctx->r_ip, SOCKERRNO); + result = socket_connect_result(data, ctx->r_ip, error); goto out; } } @@ -1220,13 +1202,14 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, out: if(result) { if(ctx->error) { + set_local_ip(cf, data); data->state.os_errno = ctx->error; SET_SOCKERRNO(ctx->error); #ifndef CURL_DISABLE_VERBOSE_STRINGS { char buffer[STRERROR_LEN]; - infof(data, "connect to %s port %u failed: %s", - ctx->r_ip, ctx->r_port, + infof(data, "connect to %s port %u from %s port %d failed: %s", + ctx->r_ip, ctx->r_port, ctx->l_ip, ctx->l_port, Curl_strerror(ctx->error, buffer, sizeof(buffer))); } #endif @@ -1252,20 +1235,19 @@ static void cf_socket_get_host(struct Curl_cfilter *cf, *pport = cf->conn->port; } -static int cf_socket_get_select_socks(struct Curl_cfilter *cf, +static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { struct cf_socket_ctx *ctx = cf->ctx; - int rc = GETSOCK_BLANK; - (void)data; - if(!cf->connected && ctx->sock != CURL_SOCKET_BAD) { - socks[0] = ctx->sock; - rc |= GETSOCK_WRITESOCK(0); + if(ctx->sock != CURL_SOCKET_BAD) { + if(!cf->connected) + Curl_pollset_set_out_only(data, ps, ctx->sock); + else + Curl_pollset_add_in(data, ps, ctx->sock); + CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num); } - - return rc; } static bool cf_socket_data_pending(struct Curl_cfilter *cf, @@ -1518,6 +1500,9 @@ static CURLcode cf_socket_cntrl(struct Curl_cfilter *cf, case CF_CTRL_DATA_SETUP: Curl_persistconninfo(data, cf->conn, ctx->l_ip, ctx->l_port); break; + case CF_CTRL_FORGET_SOCKET: + ctx->sock = CURL_SOCKET_BAD; + break; } return CURLE_OK; } @@ -1612,7 +1597,7 @@ struct Curl_cftype Curl_cft_tcp = { cf_tcp_connect, cf_socket_close, cf_socket_get_host, - cf_socket_get_select_socks, + cf_socket_adjust_pollset, cf_socket_data_pending, cf_socket_send, cf_socket_recv, @@ -1635,7 +1620,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf, (void)data; (void)conn; DEBUGASSERT(transport == TRNSPRT_TCP); - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; @@ -1742,7 +1727,7 @@ struct Curl_cftype Curl_cft_udp = { cf_udp_connect, cf_socket_close, cf_socket_get_host, - cf_socket_get_select_socks, + cf_socket_adjust_pollset, cf_socket_data_pending, cf_socket_send, cf_socket_recv, @@ -1765,7 +1750,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf, (void)data; (void)conn; DEBUGASSERT(transport == TRNSPRT_UDP || transport == TRNSPRT_QUIC); - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; @@ -1793,7 +1778,7 @@ struct Curl_cftype Curl_cft_unix = { cf_tcp_connect, cf_socket_close, cf_socket_get_host, - cf_socket_get_select_socks, + cf_socket_adjust_pollset, cf_socket_data_pending, cf_socket_send, cf_socket_recv, @@ -1816,7 +1801,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf, (void)data; (void)conn; DEBUGASSERT(transport == TRNSPRT_UNIX); - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; @@ -1857,7 +1842,7 @@ struct Curl_cftype Curl_cft_tcp_accept = { cf_tcp_accept_connect, cf_socket_close, cf_socket_get_host, /* TODO: not accurate */ - cf_socket_get_select_socks, + cf_socket_adjust_pollset, cf_socket_data_pending, cf_socket_send, cf_socket_recv, @@ -1879,7 +1864,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data, Curl_conn_cf_discard_all(data, conn, sockindex); DEBUGASSERT(conn->sock[sockindex] == CURL_SOCKET_BAD); - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/cfilters.c b/lib/cfilters.c index f74eb4003..e78ecd71d 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -33,6 +33,7 @@ #include "sockaddr.h" /* required for Curl_sockaddr_storage */ #include "multiif.h" #include "progress.h" +#include "select.h" #include "warnless.h" /* The last 3 #include files should be in this order */ @@ -70,12 +71,14 @@ void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data, } } -int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf, +void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { - return cf->next? - cf->next->cft->get_select_socks(cf->next, data, socks) : 0; + /* NOP */ + (void)cf; + (void)data; + (void)ps; } bool Curl_cf_def_data_pending(struct Curl_cfilter *cf, @@ -212,7 +215,7 @@ CURLcode Curl_cf_create(struct Curl_cfilter **pcf, CURLcode result = CURLE_OUT_OF_MEMORY; DEBUGASSERT(cft); - cf = calloc(sizeof(*cf), 1); + cf = calloc(1, sizeof(*cf)); if(!cf) goto out; @@ -303,15 +306,6 @@ void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) cf->cft->do_close(cf, data); } -int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks) -{ - if(cf) - return cf->cft->get_select_socks(cf, data, socks); - return 0; -} - ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, const void *buf, size_t len, CURLcode *err) { @@ -433,22 +427,31 @@ bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex) return FALSE; } -int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex, - curl_socket_t *socks) +void Curl_conn_cf_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) +{ + /* Get the lowest not-connected filter, if there are any */ + while(cf && !cf->connected && cf->next && !cf->next->connected) + 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); + cf = cf->next; + } +} + +void Curl_conn_adjust_pollset(struct Curl_easy *data, + struct easy_pollset *ps) { - struct Curl_cfilter *cf; + int i; DEBUGASSERT(data); DEBUGASSERT(data->conn); - cf = data->conn->cfilter[sockindex]; - - /* if the next one is not yet connected, that's the one we want */ - while(cf && cf->next && !cf->next->connected) - cf = cf->next; - if(cf) { - return cf->cft->get_select_socks(cf, data, socks); + for(i = 0; i < 2; ++i) { + Curl_conn_cf_adjust_pollset(data->conn->cfilter[i], data, ps); } - return GETSOCK_BLANK; } void Curl_conn_get_host(struct Curl_easy *data, int sockindex, @@ -524,6 +527,18 @@ curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex) return data->conn? data->conn->sock[sockindex] : CURL_SOCKET_BAD; } +void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex) +{ + if(data->conn) { + struct Curl_cfilter *cf = data->conn->cfilter[sockindex]; + if(cf) + (void)Curl_conn_cf_cntrl(cf, data, TRUE, + CF_CTRL_FORGET_SOCKET, 0, NULL); + fake_sclose(data->conn->sock[sockindex]); + data->conn->sock[sockindex] = CURL_SOCKET_BAD; + } +} + static CURLcode cf_cntrl_all(struct connectdata *conn, struct Curl_easy *data, bool ignore_result, @@ -646,3 +661,142 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data, &n, NULL) : CURLE_UNKNOWN_OPTION; return (result || n <= 0)? 1 : (size_t)n; } + + +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, + struct connectdata *conn, + curl_socket_t *socks)) +{ + curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; + int bitmap; + + DEBUGASSERT(data->conn); + bitmap = get_socks_cb(data, data->conn, socks); + ps_add(data, ps, bitmap, socks); +} + +void Curl_pollset_add_socks2(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; +} diff --git a/lib/cfilters.h b/lib/cfilters.h index 2c65264d9..09a3f162a 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -60,14 +60,34 @@ typedef void Curl_cft_get_host(struct Curl_cfilter *cf, const char **pdisplay_host, int *pport); -/* Filters may return sockets and fdset flags they are waiting for. - * The passes array has room for up to MAX_SOCKSPEREASYHANDLE sockets. - * @return read/write fdset for index in socks - * or GETSOCK_BLANK when nothing to wait on +struct easy_pollset; + +/* Passing in an easy_pollset for monitoring of sockets, let + * filters add or remove sockets actions (CURL_POLL_OUT, CURL_POLL_IN). + * This may add a socket or, in case no actions remain, remove + * a socket from the set. + * + * Filter implementations need to call filters "below" *after* they have + * made their adjustments. This allows lower filters to override "upper" + * actions. If a "lower" filter is unable to write, it needs to be able + * to disallow POLL_OUT. + * + * A filter without own restrictions/preferences should not modify + * the pollset. Filters, whose filter "below" is not connected, should + * also do no adjustments. + * + * Examples: a TLS handshake, while ongoing, might remove POLL_IN + * when it needs to write, or vice versa. A HTTP/2 filter might remove + * POLL_OUT when a stream window is exhausted and a WINDOW_UPDATE needs + * to be received first and add instead POLL_IN. + * + * @param cf the filter to ask + * @param data the easy handle the pollset is about + * @param ps the pollset (inout) for the easy handle */ -typedef int Curl_cft_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks); +typedef void 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); @@ -110,6 +130,7 @@ typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf, #define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */ /* update conn info at connection and data */ #define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */ +#define CF_CTRL_FORGET_SOCKET (256+1) /* 0 NULL ignored */ /** * Handle event/control for the filter. @@ -171,7 +192,7 @@ struct Curl_cftype { Curl_cft_connect *do_connect; /* establish connection */ Curl_cft_close *do_close; /* close conn */ Curl_cft_get_host *get_host; /* host filter talks to */ - Curl_cft_get_select_socks *get_select_socks;/* sockets to select on */ + Curl_cft_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 */ Curl_cft_recv *do_recv; /* receive data */ @@ -200,9 +221,9 @@ void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data, const char **phost, const char **pdisplay_host, int *pport); -int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks); +void 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, @@ -279,9 +300,6 @@ CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool blocking, bool *done); void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data); -int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks); ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data, const void *buf, size_t len, CURLcode *err); ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -364,11 +382,22 @@ bool Curl_conn_data_pending(struct Curl_easy *data, curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex); /** - * Get any select fd flags and the socket filters at chain `sockindex` - * at connection `conn` might be waiting for. + * Tell filters to forget about the socket at sockindex. */ -int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex, - curl_socket_t *socks); +void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex); + +/** + * Adjust the pollset for the filter chain startgin at `cf`. + */ +void 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 easy_pollset *ps); /** * Receive data through the filter chain at `sockindex` for connection @@ -468,6 +497,54 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data, int sockindex); +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, + struct connectdata *conn, + curl_socket_t *socks)); +void Curl_pollset_add_socks2(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/lib/config-amigaos.h b/lib/config-amigaos.h index 8f4d3e6c3..d168b446b 100644 --- a/lib/config-amigaos.h +++ b/lib/config-amigaos.h @@ -32,7 +32,6 @@ #define HAVE_ARPA_INET_H 1 #define HAVE_CLOSESOCKET_CAMEL 1 -#define HAVE_INTTYPES_H 1 #define HAVE_IOCTLSOCKET_CAMEL 1 #define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 #define HAVE_LONGLONG 1 diff --git a/lib/config-dos.h b/lib/config-dos.h index 550c410a1..c6fbba796 100644 --- a/lib/config-dos.h +++ b/lib/config-dos.h @@ -122,7 +122,6 @@ #define HAVE_SIGSETJMP 1 #define HAVE_SYS_TIME_H 1 #define HAVE_TERMIOS_H 1 - #define HAVE_VARIADIC_MACROS_GCC 1 #elif defined(__HIGHC__) #define HAVE_SYS_TIME_H 1 diff --git a/lib/config-os400.h b/lib/config-os400.h index e9a628863..357a36458 100644 --- a/lib/config-os400.h +++ b/lib/config-os400.h @@ -104,9 +104,6 @@ /* Define if you have the `timeval' struct. */ #define HAVE_STRUCT_TIMEVAL -/* Define if you have the header file. */ -#define HAVE_INTTYPES_H - /* Define if you have the header file. */ #undef HAVE_IO_H @@ -152,9 +149,6 @@ /* Define if you have the `socket' function. */ #define HAVE_SOCKET -/* Define if you have the header file. */ -#undef HAVE_STDINT_H - /* The following define is needed on OS400 to enable strcmpi(), stricmp() and strdup(). */ diff --git a/lib/config-plan9.h b/lib/config-plan9.h index fa4be8e6d..aa9623f92 100644 --- a/lib/config-plan9.h +++ b/lib/config-plan9.h @@ -91,7 +91,6 @@ #define HAVE_GMTIME_R 1 #define HAVE_INET_NTOP 1 #define HAVE_INET_PTON 1 -#define HAVE_INTTYPES_H 1 #define HAVE_LIBGEN_H 1 #define HAVE_LIBZ 1 #define HAVE_LOCALE_H 1 @@ -117,7 +116,6 @@ #define HAVE_SOCKET 1 #define HAVE_SSL_GET_SHUTDOWN 1 #define HAVE_STDBOOL_H 1 -#define HAVE_STDINT_H 1 #define HAVE_STRCASECMP 1 #define HAVE_STRDUP 1 #define HAVE_STRTOK_R 1 diff --git a/lib/config-riscos.h b/lib/config-riscos.h index 52c279f5b..f3a8e6832 100644 --- a/lib/config-riscos.h +++ b/lib/config-riscos.h @@ -108,9 +108,6 @@ /* Define if you have the `timeval' struct. */ #define HAVE_STRUCT_TIMEVAL -/* Define if you have the header file. */ -#define HAVE_INTTYPES_H - /* Define if you have the header file. */ #undef HAVE_IO_H @@ -144,9 +141,6 @@ /* Define if you have the `socket' function. */ #define HAVE_SOCKET -/* Define if you have the header file. */ -#undef HAVE_STDINT_H - /* Define if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP diff --git a/lib/config-win32.h b/lib/config-win32.h index e55ef2fd2..7b8a289bc 100644 --- a/lib/config-win32.h +++ b/lib/config-win32.h @@ -38,17 +38,6 @@ /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 -/* Define to 1 if you have the header file. */ -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__) -#define HAVE_INTTYPES_H 1 -#endif - -/* Define to 1 if you have the header file. */ -#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(__MINGW32__) || \ - (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0582)) || defined(__POCC__) -#define HAVE_STDINT_H 1 -#endif - /* Define if you have the header file. */ #define HAVE_IO_H 1 @@ -56,9 +45,7 @@ #define HAVE_LOCALE_H 1 /* Define if you need header even with header file. */ -#if !defined(__SALFORDC__) && !defined(__POCC__) #define NEED_MALLOC_H 1 -#endif /* Define if you have the header file. */ /* #define HAVE_NETDB_H 1 */ @@ -72,7 +59,9 @@ #endif /* Define if you have the header file. */ -/* #define HAVE_SYS_PARAM_H 1 */ +#if defined(__MINGW32__) +#define HAVE_SYS_PARAM_H 1 +#endif /* Define if you have the header file. */ /* #define HAVE_SYS_SELECT_H 1 */ @@ -87,15 +76,15 @@ #define HAVE_SYS_STAT_H 1 /* Define if you have the header file. */ -/* #define HAVE_SYS_TIME_H 1 */ +#if defined(__MINGW32__) +#define HAVE_SYS_TIME_H 1 +#endif /* Define if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define if you have the header file. */ -#ifndef __BORLANDC__ #define HAVE_SYS_UTIME_H 1 -#endif /* Define if you have the header file. */ /* #define HAVE_TERMIO_H 1 */ @@ -104,7 +93,7 @@ /* #define HAVE_TERMIOS_H 1 */ /* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__LCC__) || defined(__POCC__) +#if defined(__MINGW32__) #define HAVE_UNISTD_H 1 #endif @@ -112,14 +101,10 @@ #define HAVE_WINDOWS_H 1 /* Define if you have the header file. */ -#ifndef __SALFORDC__ #define HAVE_WINSOCK2_H 1 -#endif /* Define if you have the header file. */ -#ifndef __SALFORDC__ #define HAVE_WS2TCPIP_H 1 -#endif /* Define to 1 if you have the header file. */ #if defined(__MINGW32__) @@ -160,7 +145,9 @@ #define HAVE_GETHOSTNAME 1 /* Define if you have the gettimeofday function. */ -/* #define HAVE_GETTIMEOFDAY 1 */ +#if defined(__MINGW32__) +#define HAVE_GETTIMEOFDAY 1 +#endif /* Define if you have the ioctlsocket function. */ #define HAVE_IOCTLSOCKET 1 @@ -192,15 +179,12 @@ #define HAVE_STRICMP 1 /* Define if you have the strtoll function. */ -#if defined(__MINGW32__) || defined(__POCC__) || \ - (defined(_MSC_VER) && (_MSC_VER >= 1800)) +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || defined(__MINGW32__) #define HAVE_STRTOLL 1 #endif /* Define if you have the utime function. */ -#ifndef __BORLANDC__ #define HAVE_UTIME 1 -#endif /* Define if you have the recv function. */ #define HAVE_RECV 1 @@ -242,7 +226,7 @@ #define SEND_TYPE_RETV int /* Define to 1 if you have the snprintf function. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || defined(__MINGW32__) #define HAVE_SNPRINTF 1 #endif @@ -275,7 +259,7 @@ /* Define if ssize_t is not an available 'typedefed' type. */ #ifndef _SSIZE_T_DEFINED -# if defined(__POCC__) || defined(__MINGW32__) +# if defined(__MINGW32__) # elif defined(_WIN64) # define _SSIZE_T_DEFINED # define ssize_t __int64 @@ -325,8 +309,6 @@ # undef RECV_TYPE_ARG3 # undef SEND_TYPE_ARG1 # undef SEND_TYPE_ARG3 -# define HAVE_FREEADDRINFO -# define HAVE_GETADDRINFO # define HAVE_GETHOSTBYNAME_R # define HAVE_GETHOSTBYNAME_R_6 # define LWIP_POSIX_SOCKETS_IO_NAMES 0 @@ -347,13 +329,11 @@ #undef USE_WINSOCK #undef HAVE_WINSOCK2_H #undef HAVE_WS2TCPIP_H - #define HAVE_GETADDRINFO #define HAVE_SYS_IOCTL_H #define HAVE_SYS_SOCKET_H #define HAVE_NETINET_IN_H #define HAVE_NETDB_H #define HAVE_ARPA_INET_H - #define HAVE_FREEADDRINFO #define SOCKET int #endif @@ -371,15 +351,8 @@ /* Windows should not have HAVE_GMTIME_R defined */ /* #undef HAVE_GMTIME_R */ -/* Define if the compiler supports C99 variadic macro style. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define HAVE_VARIADIC_MACROS_C99 1 -#endif - /* Define if the compiler supports the 'long long' data type. */ -#if defined(__MINGW32__) || \ - (defined(_MSC_VER) && (_MSC_VER >= 1310)) || \ - (defined(__BORLANDC__) && (__BORLANDC__ >= 0x561)) +#if (defined(_MSC_VER) && (_MSC_VER >= 1310)) || defined(__MINGW32__) #define HAVE_LONGLONG 1 #endif @@ -461,53 +434,17 @@ Vista # endif #endif -/* When no build target is specified Pelles C 5.00 and later default build - target is Windows Vista. We override default target to be Windows 2000. */ -#if defined(__POCC__) && (__POCC__ >= 500) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 -# endif -# ifndef WINVER -# define WINVER 0x0500 -# endif -#endif - -/* Availability of freeaddrinfo, getaddrinfo, and if_nametoindex - functions is quite convoluted, compiler dependent and even build target - dependent. */ -#if defined(HAVE_WS2TCPIP_H) -# if defined(__POCC__) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETADDRINFO_THREADSAFE 1 -# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETADDRINFO_THREADSAFE 1 -# elif defined(_MSC_VER) && (_MSC_VER >= 1200) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETADDRINFO_THREADSAFE 1 -# endif -#endif - -#if defined(__POCC__) -# ifndef _MSC_VER -# error Microsoft extensions /Ze compiler option is required -# endif -# ifndef __POCC__OLDNAMES -# error Compatibility names /Go compiler option is required -# endif -#endif +/* Windows XP is required for freeaddrinfo, getaddrinfo */ +#define HAVE_FREEADDRINFO 1 +#define HAVE_GETADDRINFO 1 +#define HAVE_GETADDRINFO_THREADSAFE 1 /* ---------------------------------------------------------------- */ /* STRUCT RELATED */ /* ---------------------------------------------------------------- */ /* Define if you have struct sockaddr_storage. */ -#if !defined(__SALFORDC__) && !defined(__BORLANDC__) #define HAVE_STRUCT_SOCKADDR_STORAGE 1 -#endif /* Define if you have struct timeval. */ #define HAVE_STRUCT_TIMEVAL 1 @@ -531,10 +468,6 @@ Vista # define USE_WIN32_LARGE_FILES #endif -#if defined(__POCC__) -# undef USE_WIN32_LARGE_FILES -#endif - #if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES) # define USE_WIN32_SMALL_FILES #endif @@ -596,10 +529,6 @@ Vista #define USE_WIN32_LDAP 1 #endif -#if defined(__POCC__) && defined(USE_WIN32_LDAP) -# define CURL_DISABLE_LDAP 1 -#endif - /* Define to use the Windows crypto library. */ #if !defined(CURL_WINDOWS_APP) #define USE_WIN32_CRYPTO @@ -635,7 +564,7 @@ Vista /* If you want to build curl with the built-in manual */ #define USE_MANUAL 1 -#if defined(__POCC__) || defined(USE_IPV6) +#if defined(USE_IPV6) # define ENABLE_IPV6 1 #endif diff --git a/lib/config-win32ce.h b/lib/config-win32ce.h index cc3833d01..e0db57fd0 100644 --- a/lib/config-win32ce.h +++ b/lib/config-win32ce.h @@ -81,7 +81,7 @@ /* #define HAVE_TERMIOS_H 1 */ /* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__LCC__) +#if defined(__MINGW32__) #define HAVE_UNISTD_H 1 #endif @@ -190,8 +190,7 @@ #define in_addr_t unsigned long /* Define ssize_t if it is not an available 'typedefed' type */ -#if defined(__POCC__) -#elif defined(_WIN64) +#if defined(_WIN64) #define ssize_t __int64 #else #define ssize_t int diff --git a/lib/conncache.c b/lib/conncache.c index 93d87686c..66f18ecb8 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -107,7 +107,7 @@ int Curl_conncache_init(struct conncache *connc, int size) connc->closure_handle = curl_easy_init(); if(!connc->closure_handle) return 1; /* bad */ - connc->closure_handle->internal = true; + connc->closure_handle->state.internal = true; Curl_hash_init(&connc->hash, size, Curl_hash_str, Curl_str_key_compare, free_bundle_hash_entry); @@ -243,7 +243,7 @@ CURLcode Curl_conncache_add_conn(struct Curl_easy *data) conn->connection_id = connc->next_connection_id++; connc->num_conn++; - DEBUGF(infof(data, "Added connection %ld. " + DEBUGF(infof(data, "Added connection %" CURL_FORMAT_CURL_OFF_T ". " "The cache now contains %zu members", conn->connection_id, connc->num_conn)); @@ -379,21 +379,26 @@ conncache_find_first_connection(struct conncache *connc) bool Curl_conncache_return_conn(struct Curl_easy *data, struct connectdata *conn) { - /* data->multi->maxconnects can be negative, deal with it. */ - size_t maxconnects = - (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: - data->multi->maxconnects; + unsigned int maxconnects = !data->multi->maxconnects ? + data->multi->num_easy * 4: data->multi->maxconnects; struct connectdata *conn_candidate = NULL; conn->lastused = Curl_now(); /* it was used up until now */ - if(maxconnects > 0 && - Curl_conncache_size(data) > maxconnects) { + if(maxconnects && Curl_conncache_size(data) > maxconnects) { infof(data, "Connection cache is full, closing the oldest one"); conn_candidate = Curl_conncache_extract_oldest(data); if(conn_candidate) { - /* the winner gets the honour of being disconnected */ - Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE); + /* Use the closure handle for this disconnect so that anything that + happens during the disconnect is not stored and associated with the + 'data' handle which already just finished a transfer and it is + important that details from this (unrelated) disconnect does not + taint meta-data in the data handle. */ + struct conncache *connc = data->state.conn_cache; + connc->closure_handle->state.buffer = data->state.buffer; + connc->closure_handle->set.buffer_size = data->set.buffer_size; + Curl_disconnect(connc->closure_handle, conn_candidate, + /* dead_connection */ FALSE); } } diff --git a/lib/connect.c b/lib/connect.c index c7ba3e20e..ec5ab71d4 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -84,6 +84,9 @@ #include "curl_memory.h" #include "memdebug.h" +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif /* * Curl_timeleft() returns the amount of milliseconds left allowed for the @@ -348,6 +351,7 @@ void Curl_conncontrol(struct connectdata *conn, */ 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 */ @@ -359,9 +363,12 @@ struct eyeballer { 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(inconclusive); /* connect was not a hard failure, we + * might talk to a restarting server */ }; @@ -408,7 +415,7 @@ static CURLcode eyeballer_new(struct eyeballer **pballer, #endif "ip")); baller->cf_create = cf_create; - baller->addr = addr; + baller->first = baller->addr = addr; baller->ai_family = ai_family; baller->primary = primary; baller->delay_ms = delay_ms; @@ -438,6 +445,13 @@ static void baller_free(struct eyeballer *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); @@ -528,6 +542,10 @@ static CURLcode baller_start_next(struct Curl_cfilter *cf, { if(cf->sockindex == FIRSTSOCKET) { baller_next_addr(baller); + /* If we get inconclusive answers from the server(s), we make + * a second iteration over the address list */ + if(!baller->addr && baller->inconclusive && !baller->rewinded) + baller_rewind(baller); baller_start(cf, data, baller, timeoutms); } else { @@ -566,6 +584,8 @@ static CURLcode baller_connect(struct Curl_cfilter *cf, baller->result = CURLE_OPERATION_TIMEDOUT; } } + else if(baller->result == CURLE_WEIRD_SERVER_REPLY) + baller->inconclusive = TRUE; } return baller->result; } @@ -595,7 +615,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf, *connected = FALSE; /* a very negative world view is best */ now = Curl_now(); ongoing = not_started = 0; - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || baller->is_done) @@ -656,7 +676,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf, if(not_started > 0) { int added = 0; - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || baller->has_started) @@ -691,13 +711,13 @@ static CURLcode is_connected(struct Curl_cfilter *cf, /* all ballers have failed to connect. */ CURL_TRC_CF(data, cf, "all eyeballers failed"); result = CURLE_COULDNT_CONNECT; - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < 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?baller->name:NULL, - baller?baller->has_started:0, - baller?baller->result:0); - if(baller && baller->has_started && baller->result) { + baller->name, baller->has_started, baller->result); + if(baller->has_started && baller->result) { result = baller->result; break; } @@ -838,7 +858,7 @@ static void cf_he_ctx_clear(struct Curl_cfilter *cf, struct Curl_easy *data) DEBUGASSERT(ctx); DEBUGASSERT(data); - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { baller_free(ctx->baller[i], data); ctx->baller[i] = NULL; } @@ -846,35 +866,22 @@ static void cf_he_ctx_clear(struct Curl_cfilter *cf, struct Curl_easy *data) ctx->winner = NULL; } -static int cf_he_get_select_socks(struct Curl_cfilter *cf, +static void cf_he_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { struct cf_he_ctx *ctx = cf->ctx; - size_t i, s; - int wrc, rc = GETSOCK_BLANK; - curl_socket_t wsocks[MAX_SOCKSPEREASYHANDLE]; - - if(cf->connected) - return cf->next->cft->get_select_socks(cf->next, data, socks); - - for(i = s = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { - struct eyeballer *baller = ctx->baller[i]; - if(!baller || !baller->cf) - continue; + size_t i; - wrc = Curl_conn_cf_get_select_socks(baller->cf, data, wsocks); - if(wrc) { - /* TODO: we assume we get at most one socket back */ - socks[s] = wsocks[0]; - if(wrc & GETSOCK_WRITESOCK(0)) - rc |= GETSOCK_WRITESOCK(s); - if(wrc & GETSOCK_READSOCK(0)) - rc |= GETSOCK_READSOCK(s); - s++; + if(!cf->connected) { + for(i = 0; i < 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); } - return rc; } static CURLcode cf_he_connect(struct Curl_cfilter *cf, @@ -956,7 +963,7 @@ static bool cf_he_data_pending(struct Curl_cfilter *cf, if(cf->connected) return cf->next->cft->has_data_pending(cf->next, data); - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || !baller->cf) continue; @@ -975,7 +982,7 @@ static struct curltime get_max_baller_time(struct Curl_cfilter *cf, size_t i; memset(&tmax, 0, sizeof(tmax)); - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; memset(&t, 0, sizeof(t)); @@ -1000,7 +1007,7 @@ static CURLcode cf_he_query(struct Curl_cfilter *cf, int reply_ms = -1; size_t i; - for(i = 0; i < sizeof(ctx->baller)/sizeof(ctx->baller[0]); i++) { + for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; int breply_ms; @@ -1055,7 +1062,7 @@ struct Curl_cftype Curl_cft_happy_eyeballs = { cf_he_connect, cf_he_close, Curl_cf_def_get_host, - cf_he_get_select_socks, + cf_he_adjust_pollset, cf_he_data_pending, Curl_cf_def_send, Curl_cf_def_recv, @@ -1089,7 +1096,7 @@ cf_happy_eyeballs_create(struct Curl_cfilter **pcf, (void)data; (void)conn; *pcf = NULL; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; @@ -1122,13 +1129,13 @@ struct transport_provider transport_providers[] = { #ifdef ENABLE_QUIC { 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 }, -}; - -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) #endif +}; static cf_ip_connect_create *get_cf_create(int transport) { @@ -1319,7 +1326,7 @@ struct Curl_cftype Curl_cft_setup = { cf_setup_connect, cf_setup_close, Curl_cf_def_get_host, - Curl_cf_def_get_select_socks, + Curl_cf_def_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, Curl_cf_def_recv, @@ -1340,7 +1347,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf, CURLcode result = CURLE_OK; (void)data; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/content_encoding.c b/lib/content_encoding.c index be7c075e9..4167d4d68 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -63,6 +63,9 @@ #ifndef CURL_DISABLE_HTTP +/* allow no more than 5 "chained" compression steps */ +#define MAX_ENCODE_STACK 5 + #define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */ @@ -95,7 +98,7 @@ typedef enum { /* Deflate and gzip writer. */ struct zlib_writer { - struct contenc_writer super; + struct Curl_cwriter super; zlibInitState zlib_init; /* zlib init state */ uInt trailerlen; /* Remaining trailer byte count. */ z_stream z; /* State structure for zlib. */ @@ -171,7 +174,7 @@ static CURLcode process_trailer(struct Curl_easy *data, } static CURLcode inflate_stream(struct Curl_easy *data, - struct contenc_writer *writer, + struct Curl_cwriter *writer, int type, zlibInitState started) { struct zlib_writer *zp = (struct zlib_writer *) writer; @@ -196,7 +199,7 @@ static CURLcode inflate_stream(struct Curl_easy *data, return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); /* because the buffer size is fixed, iteratively decompress and transfer to - the client via downstream_write function. */ + the client via next_write function. */ while(!done) { int status; /* zlib status */ done = TRUE; @@ -217,7 +220,7 @@ static CURLcode inflate_stream(struct Curl_easy *data, if(z->avail_out != DSIZ) { if(status == Z_OK || status == Z_STREAM_END) { zp->zlib_init = started; /* Data started. */ - result = Curl_unencode_write(data, writer->downstream, decomp, + result = Curl_cwriter_write(data, writer->next, type, decomp, DSIZ - z->avail_out); if(result) { exit_zlib(data, z, &zp->zlib_init, result); @@ -274,8 +277,8 @@ static CURLcode inflate_stream(struct Curl_easy *data, /* Deflate handler. */ -static CURLcode deflate_init_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static CURLcode deflate_do_init(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ @@ -290,13 +293,16 @@ static CURLcode deflate_init_writer(struct Curl_easy *data, return CURLE_OK; } -static CURLcode deflate_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, +static CURLcode deflate_do_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ + if(!(type & CLIENTWRITE_BODY)) + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); + /* Set the compressed input when this function is called */ z->next_in = (Bytef *) buf; z->avail_in = (uInt) nbytes; @@ -305,11 +311,11 @@ static CURLcode deflate_unencode_write(struct Curl_easy *data, return process_trailer(data, zp); /* Now uncompress the data */ - return inflate_stream(data, writer, ZLIB_INFLATING); + return inflate_stream(data, writer, type, ZLIB_INFLATING); } -static void deflate_close_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static void deflate_do_close(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ @@ -317,19 +323,19 @@ static void deflate_close_writer(struct Curl_easy *data, exit_zlib(data, z, &zp->zlib_init, CURLE_OK); } -static const struct content_encoding deflate_encoding = { +static const struct Curl_cwtype deflate_encoding = { "deflate", NULL, - deflate_init_writer, - deflate_unencode_write, - deflate_close_writer, + deflate_do_init, + deflate_do_write, + deflate_do_close, sizeof(struct zlib_writer) }; /* Gzip handler. */ -static CURLcode gzip_init_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static CURLcode gzip_do_init(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ @@ -441,19 +447,22 @@ static enum { } #endif -static CURLcode gzip_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, +static CURLcode gzip_do_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ + if(!(type & CLIENTWRITE_BODY)) + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); + if(zp->zlib_init == ZLIB_INIT_GZIP) { /* Let zlib handle the gzip decompression entirely */ z->next_in = (Bytef *) buf; z->avail_in = (uInt) nbytes; /* Now uncompress the data */ - return inflate_stream(data, writer, ZLIB_INIT_GZIP); + return inflate_stream(data, writer, type, ZLIB_INIT_GZIP); } #ifndef OLD_ZLIB_SUPPORT @@ -565,12 +574,12 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data, } /* We've parsed the header, now uncompress the data */ - return inflate_stream(data, writer, ZLIB_GZIP_INFLATING); + return inflate_stream(data, writer, type, ZLIB_GZIP_INFLATING); #endif } -static void gzip_close_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static void gzip_do_close(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ @@ -578,12 +587,12 @@ static void gzip_close_writer(struct Curl_easy *data, exit_zlib(data, z, &zp->zlib_init, CURLE_OK); } -static const struct content_encoding gzip_encoding = { +static const struct Curl_cwtype gzip_encoding = { "gzip", "x-gzip", - gzip_init_writer, - gzip_unencode_write, - gzip_close_writer, + gzip_do_init, + gzip_do_write, + gzip_do_close, sizeof(struct zlib_writer) }; @@ -593,7 +602,7 @@ static const struct content_encoding gzip_encoding = { #ifdef HAVE_BROTLI /* Brotli writer. */ struct brotli_writer { - struct contenc_writer super; + struct Curl_cwriter super; BrotliDecoderState *br; /* State structure for brotli. */ }; @@ -635,8 +644,8 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be) return CURLE_WRITE_ERROR; } -static CURLcode brotli_init_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static CURLcode brotli_do_init(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct brotli_writer *bp = (struct brotli_writer *) writer; (void) data; @@ -645,8 +654,8 @@ static CURLcode brotli_init_writer(struct Curl_easy *data, return bp->br? CURLE_OK: CURLE_OUT_OF_MEMORY; } -static CURLcode brotli_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, +static CURLcode brotli_do_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { struct brotli_writer *bp = (struct brotli_writer *) writer; @@ -657,6 +666,9 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data, CURLcode result = CURLE_OK; BrotliDecoderResult r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; + if(!(type & CLIENTWRITE_BODY)) + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); + if(!bp->br) return CURLE_WRITE_ERROR; /* Stream already ended. */ @@ -670,7 +682,7 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data, dstleft = DSIZ; r = BrotliDecoderDecompressStream(bp->br, &nbytes, &src, &dstleft, &dst, NULL); - result = Curl_unencode_write(data, writer->downstream, + result = Curl_cwriter_write(data, writer->next, type, decomp, DSIZ - dstleft); if(result) break; @@ -693,8 +705,8 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data, return result; } -static void brotli_close_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static void brotli_do_close(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct brotli_writer *bp = (struct brotli_writer *) writer; @@ -706,12 +718,12 @@ static void brotli_close_writer(struct Curl_easy *data, } } -static const struct content_encoding brotli_encoding = { +static const struct Curl_cwtype brotli_encoding = { "br", NULL, - brotli_init_writer, - brotli_unencode_write, - brotli_close_writer, + brotli_do_init, + brotli_do_write, + brotli_do_close, sizeof(struct brotli_writer) }; #endif @@ -720,13 +732,13 @@ static const struct content_encoding brotli_encoding = { #ifdef HAVE_ZSTD /* Zstd writer. */ struct zstd_writer { - struct contenc_writer super; + struct Curl_cwriter super; ZSTD_DStream *zds; /* State structure for zstd. */ void *decomp; }; -static CURLcode zstd_init_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static CURLcode zstd_do_init(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct zstd_writer *zp = (struct zstd_writer *) writer; @@ -737,8 +749,8 @@ static CURLcode zstd_init_writer(struct Curl_easy *data, return zp->zds ? CURLE_OK : CURLE_OUT_OF_MEMORY; } -static CURLcode zstd_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, +static CURLcode zstd_do_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { CURLcode result = CURLE_OK; @@ -747,6 +759,9 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data, ZSTD_outBuffer out; size_t errorCode; + if(!(type & CLIENTWRITE_BODY)) + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); + if(!zp->decomp) { zp->decomp = malloc(DSIZ); if(!zp->decomp) @@ -766,7 +781,7 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data, return CURLE_BAD_CONTENT_ENCODING; } if(out.pos > 0) { - result = Curl_unencode_write(data, writer->downstream, + result = Curl_cwriter_write(data, writer->next, type, zp->decomp, out.pos); if(result) break; @@ -778,8 +793,8 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data, return result; } -static void zstd_close_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static void zstd_do_close(struct Curl_easy *data, + struct Curl_cwriter *writer) { struct zstd_writer *zp = (struct zstd_writer *) writer; @@ -795,52 +810,30 @@ static void zstd_close_writer(struct Curl_easy *data, } } -static const struct content_encoding zstd_encoding = { +static const struct Curl_cwtype zstd_encoding = { "zstd", NULL, - zstd_init_writer, - zstd_unencode_write, - zstd_close_writer, + zstd_do_init, + zstd_do_write, + zstd_do_close, sizeof(struct zstd_writer) }; #endif /* Identity handler. */ -static CURLcode identity_init_writer(struct Curl_easy *data, - struct contenc_writer *writer) -{ - (void)data; - (void)writer; - return CURLE_OK; -} - -static CURLcode identity_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, - const char *buf, size_t nbytes) -{ - return Curl_unencode_write(data, writer->downstream, buf, nbytes); -} - -static void identity_close_writer(struct Curl_easy *data, - struct contenc_writer *writer) -{ - (void) data; - (void) writer; -} - -static const struct content_encoding identity_encoding = { +static const struct Curl_cwtype identity_encoding = { "identity", "none", - identity_init_writer, - identity_unencode_write, - identity_close_writer, - sizeof(struct contenc_writer) + Curl_cwriter_def_init, + Curl_cwriter_def_write, + Curl_cwriter_def_close, + sizeof(struct Curl_cwriter) }; /* supported content encodings table. */ -static const struct content_encoding * const encodings[] = { +static const struct Curl_cwtype * const encodings[] = { &identity_encoding, #ifdef HAVE_LIBZ &deflate_encoding, @@ -856,13 +849,17 @@ static const struct content_encoding * const encodings[] = { }; -/* Return a list of comma-separated names of supported encodings. */ -char *Curl_all_content_encodings(void) +/* Provide a list of comma-separated names of supported encodings. +*/ +void Curl_all_content_encodings(char *buf, size_t blen) { size_t len = 0; - const struct content_encoding * const *cep; - const struct content_encoding *ce; - char *ace; + const struct Curl_cwtype * const *cep; + const struct Curl_cwtype *ce; + + DEBUGASSERT(buf); + DEBUGASSERT(blen); + buf[0] = 0; for(cep = encodings; *cep; cep++) { ce = *cep; @@ -870,12 +867,12 @@ char *Curl_all_content_encodings(void) len += strlen(ce->name) + 2; } - if(!len) - return strdup(CONTENT_ENCODING_DEFAULT); - - ace = malloc(len); - if(ace) { - char *p = ace; + if(!len) { + if(blen >= sizeof(CONTENT_ENCODING_DEFAULT)) + strcpy(buf, CONTENT_ENCODING_DEFAULT); + } + else if(blen > len) { + char *p = buf; for(cep = encodings; *cep; cep++) { ce = *cep; if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) { @@ -887,75 +884,60 @@ char *Curl_all_content_encodings(void) } p[-2] = '\0'; } - - return ace; } - /* Deferred error dummy writer. */ -static CURLcode error_init_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static CURLcode error_do_init(struct Curl_easy *data, + struct Curl_cwriter *writer) { (void)data; (void)writer; return CURLE_OK; } -static CURLcode error_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, +static CURLcode error_do_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, const char *buf, size_t nbytes) { - char *all = Curl_all_content_encodings(); + char all[256]; + (void)Curl_all_content_encodings(all, sizeof(all)); (void) writer; (void) buf; (void) nbytes; - if(!all) - return CURLE_OUT_OF_MEMORY; + if(!(type & CLIENTWRITE_BODY)) + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); + failf(data, "Unrecognized content encoding type. " "libcurl understands %s content encodings.", all); - free(all); return CURLE_BAD_CONTENT_ENCODING; } -static void error_close_writer(struct Curl_easy *data, - struct contenc_writer *writer) +static void error_do_close(struct Curl_easy *data, + struct Curl_cwriter *writer) { (void) data; (void) writer; } -static const struct content_encoding error_encoding = { - NULL, +static const struct Curl_cwtype error_writer = { + "ce-error", NULL, - error_init_writer, - error_unencode_write, - error_close_writer, - sizeof(struct contenc_writer) + error_do_init, + error_do_write, + error_do_close, + sizeof(struct Curl_cwriter) }; -/* Write data using an unencoding writer stack. "nbytes" is not - allowed to be 0. */ -CURLcode Curl_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, - const char *buf, size_t nbytes) -{ - if(!nbytes) - return CURLE_OK; - if(!writer) - return CURLE_WRITE_ERROR; - return writer->handler->unencode_write(data, writer, buf, nbytes); -} - /* Find the content encoding by name. */ -static const struct content_encoding *find_encoding(const char *name, +static const struct Curl_cwtype *find_encoding(const char *name, size_t len) { - const struct content_encoding * const *cep; + const struct Curl_cwtype * const *cep; for(cep = encodings; *cep; cep++) { - const struct content_encoding *ce = *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])) return ce; @@ -969,7 +951,8 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, const char *enclist, int is_transfer) { struct SingleRequest *k = &data->req; - unsigned int order = is_transfer? 2: 1; + Curl_cwriter_phase phase = is_transfer? + CURL_CW_TRANSFER_DECODE:CURL_CW_CONTENT_DECODE; CURLcode result; do { @@ -992,23 +975,32 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, Curl_httpchunk_init(data); /* init our chunky engine. */ } else if(namelen) { - const struct content_encoding *encoding; - struct contenc_writer *writer; - if(is_transfer && !data->set.http_transfer_encoding) + const struct Curl_cwtype *cwt; + struct Curl_cwriter *writer; + + if((is_transfer && !data->set.http_transfer_encoding) || + (!is_transfer && data->set.http_ce_skip)) { /* not requested, ignore */ return CURLE_OK; + } - encoding = find_encoding(name, namelen); - if(!encoding) - encoding = &error_encoding; /* Defer error at stack use. */ + if(Curl_cwriter_count(data, phase) + 1 >= MAX_ENCODE_STACK) { + failf(data, "Reject response due to more than %u content encodings", + MAX_ENCODE_STACK); + return CURLE_BAD_CONTENT_ENCODING; + } + + cwt = find_encoding(name, namelen); + if(!cwt) + cwt = &error_writer; /* Defer error at use. */ - result = Curl_client_create_writer(&writer, data, encoding, order); + result = Curl_cwriter_create(&writer, data, cwt, phase); if(result) return result; - result = Curl_client_add_writer(data, writer); + result = Curl_cwriter_add(data, writer); if(result) { - Curl_client_free_writer(data, writer); + Curl_cwriter_free(data, writer); return result; } } @@ -1028,20 +1020,15 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, return CURLE_NOT_BUILT_IN; } -CURLcode Curl_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, - const char *buf, size_t nbytes) +void Curl_all_content_encodings(char *buf, size_t blen) { - (void) data; - (void) writer; - (void) buf; - (void) nbytes; - return CURLE_NOT_BUILT_IN; + DEBUGASSERT(buf); + DEBUGASSERT(blen); + if(blen < sizeof(CONTENT_ENCODING_DEFAULT)) + buf[0] = 0; + else + strcpy(buf, CONTENT_ENCODING_DEFAULT); } -char *Curl_all_content_encodings(void) -{ - return strdup(CONTENT_ENCODING_DEFAULT); /* Satisfy caller. */ -} #endif /* CURL_DISABLE_HTTP */ diff --git a/lib/content_encoding.h b/lib/content_encoding.h index ef7930cb3..1addf230b 100644 --- a/lib/content_encoding.h +++ b/lib/content_encoding.h @@ -25,15 +25,10 @@ ***************************************************************************/ #include "curl_setup.h" -struct contenc_writer; +struct Curl_cwriter; -char *Curl_all_content_encodings(void); +void Curl_all_content_encodings(char *buf, size_t blen); CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, const char *enclist, int is_transfer); -CURLcode Curl_unencode_write(struct Curl_easy *data, - struct contenc_writer *writer, - const char *buf, size_t nbytes); -void Curl_unencode_cleanup(struct Curl_easy *data); - #endif /* HEADER_CURL_CONTENT_ENCODING_H */ diff --git a/lib/cookie.c b/lib/cookie.c index af01203a9..9095cea3e 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -330,7 +330,7 @@ static char *sanitize_cookie_path(const char *cookie_path) */ void Curl_cookie_loadfiles(struct Curl_easy *data) { - struct curl_slist *list = data->set.cookielist; + struct curl_slist *list = data->state.cookielist; if(list) { Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); while(list) { @@ -365,9 +365,7 @@ static void strstore(char **str, const char *newstr, size_t len) DEBUGASSERT(newstr); DEBUGASSERT(str); free(*str); - *str = Curl_memdup(newstr, len + 1); - if(*str) - (*str)[len] = 0; + *str = Curl_strndup(newstr, len); } /* @@ -1029,15 +1027,23 @@ Curl_cookie_add(struct Curl_easy *data, * dereference it. */ if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) { - const psl_ctx_t *psl = Curl_psl_use(data); - int acceptable; - - if(psl) { - acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain); - Curl_psl_release(data); + bool acceptable = FALSE; + char lcase[256]; + char lcookie[256]; + size_t dlen = strlen(domain); + size_t clen = strlen(co->domain); + if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) { + const psl_ctx_t *psl = Curl_psl_use(data); + if(psl) { + /* the PSL check requires lowercase domain name and pattern */ + Curl_strntolower(lcase, domain, dlen + 1); + Curl_strntolower(lcookie, co->domain, clen + 1); + acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie); + Curl_psl_release(data); + } + else + acceptable = !bad_domain(domain, strlen(domain)); } - else - acceptable = !bad_domain(domain, strlen(domain)); if(!acceptable) { infof(data, "cookie '%s' dropped, domain '%s' must not " @@ -1347,7 +1353,7 @@ static int cookie_sort_ct(const void *p1, const void *p2) static struct Cookie *dup_cookie(struct Cookie *src) { - struct Cookie *d = calloc(sizeof(struct Cookie), 1); + struct Cookie *d = calloc(1, sizeof(struct Cookie)); if(d) { CLONE(domain); CLONE(path); diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake index 0bfb45796..339358ea3 100644 --- a/lib/curl_config.h.cmake +++ b/lib/curl_config.h.cmake @@ -74,9 +74,15 @@ /* disables FTP */ #cmakedefine CURL_DISABLE_FTP 1 +/* disables curl_easy_options API for existing options to curl_easy_setopt */ +#cmakedefine CURL_DISABLE_GETOPTIONS 1 + /* disables GOPHER */ #cmakedefine CURL_DISABLE_GOPHER 1 +/* disables headers-api support */ +#cmakedefine CURL_DISABLE_HEADERS_API 1 + /* disables HSTS support */ #cmakedefine CURL_DISABLE_HSTS 1 @@ -98,6 +104,9 @@ /* disables MIME support */ #cmakedefine CURL_DISABLE_MIME 1 +/* disables local binding support */ +#cmakedefine CURL_DISABLE_BINDLOCAL 1 + /* disables MQTT */ #cmakedefine CURL_DISABLE_MQTT 1 @@ -168,9 +177,6 @@ /* Define to 1 if you have _Atomic support. */ #cmakedefine HAVE_ATOMIC 1 -/* Define to 1 if you have the `fchmod' function. */ -#cmakedefine HAVE_FCHMOD 1 - /* Define to 1 if you have the `fnmatch' function. */ #cmakedefine HAVE_FNMATCH 1 @@ -208,6 +214,9 @@ /* Define to 1 if you have the fseeko function. */ #cmakedefine HAVE_FSEEKO 1 +/* Define to 1 if you have the fseeko declaration. */ +#cmakedefine HAVE_DECL_FSEEKO 1 + /* Define to 1 if you have the _fseeki64 function. */ #cmakedefine HAVE__FSEEKI64 1 @@ -313,9 +322,6 @@ /* Define to 1 if symbol `ADDRESS_FAMILY' exists */ #cmakedefine HAVE_ADDRESS_FAMILY 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - /* Define to 1 if you have the ioctlsocket function. */ #cmakedefine HAVE_IOCTLSOCKET 1 @@ -497,9 +503,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDBOOL_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - /* Define to 1 if you have the strcasecmp function. */ #cmakedefine HAVE_STRCASECMP 1 @@ -596,12 +599,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UTIME_H 1 -/* Define to 1 if compiler supports C99 variadic macro style. */ -#cmakedefine HAVE_VARIADIC_MACROS_C99 1 - -/* Define to 1 if compiler supports old gcc variadic macro style. */ -#cmakedefine HAVE_VARIADIC_MACROS_GCC 1 - /* Define to 1 if you have the windows.h header file. */ #cmakedefine HAVE_WINDOWS_H 1 diff --git a/lib/curl_hmac.h b/lib/curl_hmac.h index 2ea03dd26..7a5387a94 100644 --- a/lib/curl_hmac.h +++ b/lib/curl_hmac.h @@ -25,7 +25,8 @@ ***************************************************************************/ #if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \ - || !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) + || !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \ + || defined(USE_LIBSSH2) #include diff --git a/lib/curl_memory.h b/lib/curl_memory.h index b8c46d793..714ad71c9 100644 --- a/lib/curl_memory.h +++ b/lib/curl_memory.h @@ -68,7 +68,7 @@ #undef send #undef recv -#ifdef WIN32 +#ifdef _WIN32 # ifdef UNICODE # undef wcsdup # undef _wcsdup @@ -134,7 +134,7 @@ 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) +#if defined(_WIN32) && defined(UNICODE) extern curl_wcsdup_callback Curl_cwcsdup; #endif @@ -160,7 +160,7 @@ extern curl_wcsdup_callback Curl_cwcsdup; #undef free #define free(ptr) Curl_cfree(ptr) -#ifdef WIN32 +#ifdef _WIN32 # ifdef UNICODE # undef wcsdup # define wcsdup(ptr) Curl_cwcsdup(ptr) diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c index 522ea34e8..ff2109856 100644 --- a/lib/curl_multibyte.c +++ b/lib/curl_multibyte.c @@ -32,7 +32,7 @@ #include "curl_setup.h" -#if defined(WIN32) +#if defined(_WIN32) #include "curl_multibyte.h" @@ -84,7 +84,7 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w) return str_utf8; } -#endif /* WIN32 */ +#endif /* _WIN32 */ #if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES) diff --git a/lib/curl_multibyte.h b/lib/curl_multibyte.h index ddac1f638..8b9ac719e 100644 --- a/lib/curl_multibyte.h +++ b/lib/curl_multibyte.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(WIN32) +#if defined(_WIN32) /* * MultiByte conversions using Windows kernel32 library. @@ -33,7 +33,7 @@ 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 /* _WIN32 */ /* * Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8() @@ -54,7 +54,7 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w); * ensure that the curl memdebug override macros do not replace them. */ -#if defined(UNICODE) && defined(WIN32) +#if defined(UNICODE) && defined(_WIN32) #define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr)) #define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr)) @@ -78,7 +78,7 @@ typedef union { const unsigned char *const_tbyte_ptr; } xcharp_u; -#endif /* UNICODE && WIN32 */ +#endif /* UNICODE && _WIN32 */ #define curlx_unicodefree(ptr) \ do { \ diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c index cc0ed9167..6f6d75c03 100644 --- a/lib/curl_ntlm_core.c +++ b/lib/curl_ntlm_core.c @@ -111,6 +111,7 @@ # include #else # error "Can't compile NTLM support without a crypto library with DES." +# define CURL_NTLM_NOT_SUPPORTED #endif #include "urldata.h" @@ -130,6 +131,7 @@ #define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00" #define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4) +#if !defined(CURL_NTLM_NOT_SUPPORTED) /* * Turns a 56-bit key into being 64-bit wide. */ @@ -144,6 +146,7 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key) key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6)); key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF); } +#endif #if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) /* @@ -337,6 +340,10 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, encrypt_des(plaintext, results, keys); encrypt_des(plaintext, results + 8, keys + 7); encrypt_des(plaintext, results + 16, keys + 14); +#else + (void)keys; + (void)plaintext; + (void)results; #endif } @@ -347,9 +354,11 @@ 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) static const unsigned char magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ }; +#endif size_t len = CURLMIN(strlen(password), 14); Curl_strntoupper((char *)pw, password, len); diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c index aa7bea75e..b087a37a3 100644 --- a/lib/curl_ntlm_wb.c +++ b/lib/curl_ntlm_wb.c @@ -68,7 +68,9 @@ /* Portable 'sclose_nolog' used only in child process instead of 'sclose' to avoid fooling the socket leak detector */ -#if defined(HAVE_CLOSESOCKET) +#ifdef HAVE_PIPE +# define sclose_nolog(x) close((x)) +#elif defined(HAVE_CLOSESOCKET) # define sclose_nolog(x) closesocket((x)) #elif defined(HAVE_CLOSESOCKET_CAMEL) # define sclose_nolog(x) CloseSocket((x)) @@ -189,7 +191,7 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, goto done; } - if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { + if(wakeup_create(sockfds)) { failf(data, "Could not open socket pair. errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; @@ -197,8 +199,8 @@ static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm, child_pid = fork(); if(child_pid == -1) { - sclose(sockfds[0]); - sclose(sockfds[1]); + wakeup_close(sockfds[0]); + wakeup_close(sockfds[1]); failf(data, "Could not fork. errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); goto done; @@ -268,7 +270,7 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm, Curl_dyn_init(&b, MAX_NTLM_WB_RESPONSE); while(len_in > 0) { - ssize_t written = swrite(ntlm->ntlm_auth_hlpr_socket, input, len_in); + ssize_t written = wakeup_write(ntlm->ntlm_auth_hlpr_socket, input, len_in); if(written == -1) { /* Interrupted by a signal, retry it */ if(errno == EINTR) @@ -282,7 +284,7 @@ static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm, /* Read one line */ while(1) { ssize_t size = - sread(ntlm->ntlm_auth_hlpr_socket, buf, data->set.buffer_size); + wakeup_read(ntlm->ntlm_auth_hlpr_socket, buf, data->set.buffer_size); if(size == -1) { if(errno == EINTR) continue; diff --git a/lib/curl_path.h b/lib/curl_path.h index 9ed09dea8..cbe51c221 100644 --- a/lib/curl_path.h +++ b/lib/curl_path.h @@ -28,7 +28,7 @@ #include #include "urldata.h" -#ifdef WIN32 +#ifdef _WIN32 # undef PATH_MAX # define PATH_MAX MAX_PATH # ifndef R_OK diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c index 406fb42ac..f7cf54e88 100644 --- a/lib/curl_rtmp.c +++ b/lib/curl_rtmp.c @@ -39,7 +39,7 @@ /* The last #include file should be: */ #include "memdebug.h" -#if defined(WIN32) && !defined(USE_LWIPSOCK) +#if defined(_WIN32) && !defined(USE_LWIPSOCK) #define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) #define SET_RCVTIMEO(tv,s) int tv = s*1000 #elif defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 91ddf1062..78ad298f2 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -262,6 +262,8 @@ static void sasl_state(struct SASL *sasl, struct Curl_easy *data, sasl->state = newstate; } +#if defined(USE_NTLM) || defined(USE_GSASL) || defined(USE_KERBEROS5) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) /* Get the SASL server message and convert it to binary. */ static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data, struct bufref *out) @@ -284,6 +286,7 @@ static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data, } return result; } +#endif /* Encode the outgoing SASL message. */ static CURLcode build_message(struct SASL *sasl, struct bufref *msg) diff --git a/lib/curl_setup.h b/lib/curl_setup.h index ba14972e2..a08784140 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -28,6 +28,11 @@ #define CURL_NO_OLDIES #endif +/* Set default _WIN32_WINNT */ +#ifdef __MINGW32__ +#include <_mingw.h> +#endif + /* * Disable Visual Studio warnings: * 4127 "conditional expression is constant" @@ -36,15 +41,7 @@ #pragma warning(disable:4127) #endif -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -#define WIN32 -#endif - -#ifdef WIN32 +#ifdef _WIN32 /* * Don't include unneeded stuff in Windows headers to avoid compiler * warnings and macro clashes. @@ -82,7 +79,7 @@ #ifdef _WIN32_WCE # include "config-win32ce.h" #else -# ifdef WIN32 +# ifdef _WIN32 # include "config-win32.h" # endif #endif @@ -214,6 +211,23 @@ # define CURL_DISABLE_RTSP #endif +/* + * When HTTP is disabled, disable HTTP-only features + */ + +#if defined(CURL_DISABLE_HTTP) +# define CURL_DISABLE_ALTSVC 1 +# define CURL_DISABLE_COOKIES 1 +# define CURL_DISABLE_BASIC_AUTH 1 +# define CURL_DISABLE_BEARER_AUTH 1 +# define CURL_DISABLE_AWS 1 +# define CURL_DISABLE_DOH 1 +# define CURL_DISABLE_FORM_API 1 +# define CURL_DISABLE_HEADERS_API 1 +# define CURL_DISABLE_HSTS 1 +# define CURL_DISABLE_HTTP_AUTH 1 +#endif + /* ================================================================ */ /* No system header file shall be included in this file before this */ /* point. */ @@ -331,23 +345,6 @@ #include #endif -#ifdef __POCC__ -# include -# include -# define sys_nerr EILSEQ -#endif - -/* - * Salford-C kludge section (mostly borrowed from wxWidgets). - */ -#ifdef __SALFORDC__ - #pragma suppress 353 /* Possible nested comments */ - #pragma suppress 593 /* Define not used */ - #pragma suppress 61 /* enum has no name */ - #pragma suppress 106 /* unnamed, unused parameter */ - #include -#endif - /* * Large file (>2Gb) support using WIN32 functions. */ @@ -500,11 +497,11 @@ 5. set dir/file naming defines */ -#ifdef WIN32 +#ifdef _WIN32 # define DIR_CHAR "\\" -#else /* WIN32 */ +#else /* _WIN32 */ # ifdef MSDOS /* Watt-32 */ @@ -529,48 +526,19 @@ # define DIR_CHAR "/" -# ifndef fileno /* sunos 4 have this as a macro! */ - int fileno(FILE *stream); -# endif - -#endif /* WIN32 */ - -/* - * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN - * defined in ws2tcpip.h as well as to provide IPv6 support. - * Does not apply if lwIP is used. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK) -# if !defined(HAVE_WS2TCPIP_H) || \ - ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN)) -# undef HAVE_GETADDRINFO_THREADSAFE -# undef HAVE_FREEADDRINFO -# undef HAVE_GETADDRINFO -# undef ENABLE_IPV6 -# endif -#endif +#endif /* _WIN32 */ /* ---------------------------------------------------------------- */ /* resolver specialty compile-time defines */ /* CURLRES_* defines to use in the host*.c sources */ /* ---------------------------------------------------------------- */ -/* - * lcc-win32 doesn't have _beginthreadex(), lacks threads support. - */ - -#if defined(__LCC__) && defined(WIN32) -# undef USE_THREADS_POSIX -# undef USE_THREADS_WIN32 -#endif - /* * MSVC threads support requires a multi-threaded runtime library. * _beginthreadex() is not available in single-threaded ones. */ -#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT) +#if defined(_MSC_VER) && !defined(_MT) # undef USE_THREADS_POSIX # undef USE_THREADS_WIN32 #endif @@ -581,6 +549,9 @@ #if defined(ENABLE_IPV6) && defined(HAVE_GETADDRINFO) # define CURLRES_IPV6 +#elif defined(ENABLE_IPV6) && (defined(_WIN32) || defined(__CYGWIN__)) +/* assume on Windows that IPv6 without getaddrinfo is a broken build */ +# error "Unexpected build: IPv6 is enabled but getaddrinfo was not found." #else # define CURLRES_IPV4 #endif @@ -600,35 +571,6 @@ /* ---------------------------------------------------------------- */ -/* - * msvc 6.0 does not have struct sockaddr_storage and - * does not define IPPROTO_ESP in winsock2.h. But both - * are available if PSDK is properly installed. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) -# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP)) -# undef HAVE_STRUCT_SOCKADDR_STORAGE -# endif -#endif - -/* - * Intentionally fail to build when using msvc 6.0 without PSDK installed. - * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK - * in lib/config-win32.h although absolutely discouraged and unsupported. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) -# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_)) -# if !defined(ALLOW_MSVC6_WITHOUT_PSDK) -# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \ - "Windows Server 2003 PSDK" -# else -# define CURL_DISABLE_LDAP 1 -# endif -# endif -#endif - #if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN) /* The lib and header are present */ #define USE_LIBIDN2 @@ -694,6 +636,18 @@ # define WARN_UNUSED_RESULT #endif +/* noreturn attribute */ + +#if !defined(CURL_NORETURN) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) +# define CURL_NORETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) +# define CURL_NORETURN __declspec(noreturn) +#else +# define CURL_NORETURN +#endif +#endif + /* * Include macros and defines that should only be processed once. */ @@ -752,7 +706,7 @@ /* In Windows the default file mode is text but an application can override it. Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 */ -#if defined(WIN32) || defined(MSDOS) +#if defined(_WIN32) || defined(MSDOS) #define FOPEN_READTEXT "rt" #define FOPEN_WRITETEXT "wt" #define FOPEN_APPENDTEXT "at" @@ -807,7 +761,8 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #define UNITTEST static #endif -#if defined(USE_NGHTTP2) || defined(USE_HYPER) +/* Hyper supports HTTP2 also, but Curl's integration with Hyper does not */ +#if defined(USE_NGHTTP2) #define USE_HTTP2 #endif @@ -820,11 +775,11 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, /* 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. */ -#if defined(HAVE_BASENAME) && defined(WIN32) +#if defined(HAVE_BASENAME) && defined(_WIN32) #undef HAVE_BASENAME #endif -#if defined(USE_UNIX_SOCKETS) && defined(WIN32) +#if defined(USE_UNIX_SOCKETS) && defined(_WIN32) # if !defined(UNIX_PATH_MAX) /* Replicating logic present in afunix.h (distributed with newer Windows 10 SDK versions only) */ diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h index c1ed05907..bf0ee663d 100644 --- a/lib/curl_setup_once.h +++ b/lib/curl_setup_once.h @@ -56,7 +56,7 @@ #include #endif -#ifdef WIN32 +#ifdef _WIN32 #include #include #endif @@ -70,11 +70,7 @@ #endif #ifdef USE_WOLFSSL -# if defined(HAVE_STDINT_H) -# include -# elif defined(HAVE_INTTYPES_H) -# include -# endif +#include #endif #ifdef USE_SCHANNEL diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h index 5af7c2483..b26c39156 100644 --- a/lib/curl_sspi.h +++ b/lib/curl_sspi.h @@ -88,6 +88,22 @@ extern PSecurityFunctionTable s_pSecFn; # 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 + +#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 diff --git a/lib/curl_trc.c b/lib/curl_trc.c index e53b30573..0ebe40b8f 100644 --- a/lib/curl_trc.c +++ b/lib/curl_trc.c @@ -61,10 +61,6 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type, "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; if(data->set.fdebug) { bool inCallback = Curl_is_in_callback(data); - /* CURLOPT_DEBUGFUNCTION doc says the user may set CURLOPT_PRIVATE to - distinguish their handle from internal handles. */ - if(data->internal) - DEBUGASSERT(!data->set.private_data); Curl_set_in_callback(data, true); (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); Curl_set_in_callback(data, inCallback); @@ -109,6 +105,8 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...) } } +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* Curl_infof() is for info message along the way */ #define MAXINFO 2048 @@ -128,13 +126,11 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...) } } -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) - void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf, const char *fmt, ...) { DEBUGASSERT(cf); - if(data && Curl_trc_cf_is_verbose(cf, data)) { + if(Curl_trc_cf_is_verbose(cf, data)) { va_list ap; int len; char buffer[MAXINFO + 2]; @@ -232,24 +228,14 @@ CURLcode Curl_trc_init(void) if(config) { return Curl_trc_opt(config); } -#endif +#endif /* DEBUGBUILD */ return CURLE_OK; } -#else /* !CURL_DISABLE_VERBOSE_STRINGS) */ +#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */ CURLcode Curl_trc_init(void) { return CURLE_OK; } -#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) -void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf, - const char *fmt, ...) -{ - (void)data; - (void)cf; - (void)fmt; -} -#endif - -#endif /* !DEBUGBUILD */ +#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */ diff --git a/lib/curl_trc.h b/lib/curl_trc.h index 84b5471d8..ade9108ac 100644 --- a/lib/curl_trc.h +++ b/lib/curl_trc.h @@ -54,19 +54,6 @@ CURLcode Curl_trc_opt(const char *config); void Curl_debug(struct Curl_easy *data, curl_infotype type, char *ptr, size_t size); -/** - * Output an informational message when transfer's verbose logging is enabled. - */ -void Curl_infof(struct Curl_easy *data, -#if defined(__GNUC__) && !defined(printf) && \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__MINGW32__) - const char *fmt, ...) - __attribute__((format(printf, 2, 3))); -#else - const char *fmt, ...); -#endif - /** * Output a failure message on registered callbacks for transfer. */ @@ -82,39 +69,15 @@ void Curl_failf(struct Curl_easy *data, #define failf Curl_failf -/** - * Output an informational message when both transfer's verbose logging - * and connection filters verbose logging are enabled. - */ -void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf, -#if defined(__GNUC__) && !defined(printf) && \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__MINGW32__) - const char *fmt, ...) - __attribute__((format(printf, 3, 4))); -#else - const char *fmt, ...); -#endif - #define CURL_LOG_LVL_NONE 0 #define CURL_LOG_LVL_INFO 1 -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) -/* informational messages enabled */ - -#define Curl_trc_is_verbose(data) ((data) && (data)->set.verbose) -#define Curl_trc_cf_is_verbose(cf, data) \ - ((data) && (data)->set.verbose && \ - (cf) && (cf)->cft->log_level >= CURL_LOG_LVL_INFO) - -/* explainer: we have some mix configuration and werror settings - * that define HAVE_VARIADIC_MACROS_C99 even though C89 is enforced - * on gnuc and some other compiler. Need to treat carefully. - */ -#if defined(HAVE_VARIADIC_MACROS_C99) && \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define CURL_HAVE_C99 +#endif +#ifdef CURL_HAVE_C99 #define infof(data, ...) \ do { if(Curl_trc_is_verbose(data)) \ Curl_infof(data, __VA_ARGS__); } while(0) @@ -122,29 +85,62 @@ void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf, do { if(Curl_trc_cf_is_verbose(cf, data)) \ Curl_trc_cf_infof(data, cf, __VA_ARGS__); } while(0) -#else /* no variadic macro args */ +#else #define infof Curl_infof #define CURL_TRC_CF Curl_trc_cf_infof -#endif /* variadic macro args */ +#endif + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +/* informational messages enabled */ -#else /* !CURL_DISABLE_VERBOSE_STRINGS */ +#define Curl_trc_is_verbose(data) ((data) && (data)->set.verbose) +#define Curl_trc_cf_is_verbose(cf, data) \ + ((data) && (data)->set.verbose && \ + (cf) && (cf)->cft->log_level >= CURL_LOG_LVL_INFO) + +/** + * Output an informational message when transfer's verbose logging is enabled. + */ +void Curl_infof(struct Curl_easy *data, +#if defined(__GNUC__) && !defined(printf) && defined(CURL_HAVE_C99) && \ + !defined(__MINGW32__) + const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else + const char *fmt, ...); +#endif + +/** + * Output an informational message when both transfer's verbose logging + * and connection filters verbose logging are enabled. + */ +void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf, +#if defined(__GNUC__) && !defined(printf) && defined(CURL_HAVE_C99) && \ + !defined(__MINGW32__) + const char *fmt, ...) + __attribute__((format(printf, 3, 4))); +#else + const char *fmt, ...); +#endif + +#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */ /* All informational messages are not compiled in for size savings */ #define Curl_trc_is_verbose(d) ((void)(d), FALSE) #define Curl_trc_cf_is_verbose(x,y) ((void)(x), (void)(y), FALSE) -#if defined(HAVE_VARIADIC_MACROS_C99) -#define infof(...) Curl_nop_stmt -#define CURL_TRC_CF(...) Curl_nop_stmt -#define Curl_trc_cf_infof(...) Curl_nop_stmt -#elif defined(HAVE_VARIADIC_MACROS_GCC) -#define infof(x...) Curl_nop_stmt -#define CURL_TRC_CF(x...) Curl_nop_stmt -#define Curl_trc_cf_infof(x...) Curl_nop_stmt -#else -#error "missing VARIADIC macro define, fix and rebuild!" -#endif +static void Curl_infof(struct Curl_easy *data, const char *fmt, ...) +{ + (void)data; (void)fmt; +} + +static void Curl_trc_cf_infof(struct Curl_easy *data, + struct Curl_cfilter *cf, + const char *fmt, ...) +{ + (void)data; (void)cf; (void)fmt; +} -#endif /* CURL_DISABLE_VERBOSE_STRINGS */ +#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */ #endif /* HEADER_CURL_TRC_H */ diff --git a/lib/doh.c b/lib/doh.c index bb0c89ec6..1d928e92c 100644 --- a/lib/doh.c +++ b/lib/doh.c @@ -242,7 +242,7 @@ static CURLcode dohprobe(struct Curl_easy *data, /* pass in the struct pointer via a local variable to please coverity and the gcc typecheck helpers */ struct dynbuf *resp = &p->serverdoh; - doh->internal = true; + doh->state.internal = true; ERROR_CHECK_SETOPT(CURLOPT_URL, url); ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https"); ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb); @@ -252,6 +252,7 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers); #ifdef USE_HTTP2 ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); + ERROR_CHECK_SETOPT(CURLOPT_PIPEWAIT, 1L); #endif #ifndef CURLDEBUG /* enforce HTTPS if not debug */ @@ -339,9 +340,10 @@ static CURLcode dohprobe(struct Curl_easy *data, doh->set.dohfor = data; /* identify for which transfer this is done */ p->easy = doh; - /* DoH private_data must be null because the user must have a way to - distinguish their transfer's handle from DoH handles in user - callbacks (ie SSL CTX callback). */ + /* DoH handles must not inherit private_data. The handles may be passed to + the user via callbacks and the user will be able to identify them as + internal handles because private data is not set. The user can then set + private_data via CURLOPT_PRIVATE if they so choose. */ DEBUGASSERT(!doh->set.private_data); if(curl_multi_add_handle(multi, doh)) @@ -372,7 +374,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, int slot; struct dohdata *dohp; struct connectdata *conn = data->conn; - *waitp = TRUE; /* this never returns synchronously */ + *waitp = FALSE; (void)hostname; (void)port; @@ -380,7 +382,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, DEBUGASSERT(conn); /* start clean, consider allocating this struct on demand */ - dohp = data->req.doh = calloc(sizeof(struct dohdata), 1); + dohp = data->req.doh = calloc(1, sizeof(struct dohdata)); if(!dohp) return NULL; @@ -412,12 +414,14 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, dohp->pending++; } #endif + *waitp = TRUE; /* this never returns synchronously */ return NULL; error: curl_slist_free_all(dohp->headers); data->req.doh->headers = NULL; for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + (void)curl_multi_remove_handle(data->multi, dohp->probe[slot].easy); Curl_close(&dohp->probe[slot].easy); } Curl_safefree(data->req.doh); @@ -787,8 +791,8 @@ static void showdoh(struct Curl_easy *data, * must be an associated call later to Curl_freeaddrinfo(). */ -static struct Curl_addrinfo * -doh2ai(const struct dohentry *de, const char *hostname, int port) +static CURLcode doh2ai(const struct dohentry *de, const char *hostname, + int port, struct Curl_addrinfo **aip) { struct Curl_addrinfo *ai; struct Curl_addrinfo *prevai = NULL; @@ -801,9 +805,10 @@ doh2ai(const struct dohentry *de, const char *hostname, int port) int i; size_t hostlen = strlen(hostname) + 1; /* include null-terminator */ - if(!de) - /* no input == no output! */ - return NULL; + DEBUGASSERT(de); + + if(!de->numaddr) + return CURLE_COULDNT_RESOLVE_HOST; for(i = 0; i < de->numaddr; i++) { size_t ss_size; @@ -876,8 +881,9 @@ doh2ai(const struct dohentry *de, const char *hostname, int port) Curl_freeaddrinfo(firstai); firstai = NULL; } + *aip = firstai; - return firstai; + return result; } #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -898,6 +904,7 @@ UNITTEST void de_cleanup(struct dohentry *d) CURLcode Curl_doh_is_resolved(struct Curl_easy *data, struct Curl_dns_entry **dnsp) { + struct connectdata *conn = data->conn; CURLcode result; struct dohdata *dohp = data->req.doh; *dnsp = NULL; /* defaults to no response */ @@ -906,7 +913,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy && !dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) { - failf(data, "Could not DoH-resolve: %s", data->state.async.hostname); + failf(data, "Could not DoH-resolve: %s", conn->resolve_async.hostname); return CONN_IS_PROXIED(data->conn)?CURLE_COULDNT_RESOLVE_PROXY: CURLE_COULDNT_RESOLVE_HOST; } @@ -932,10 +939,12 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, p->dnstype, &de); Curl_dyn_free(&p->serverdoh); +#ifndef CURL_DISABLE_VERBOSE_STRINGS if(rc[slot]) { infof(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]), type2name(p->dnstype), dohp->host); } +#endif } /* next slot */ result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */ @@ -947,10 +956,10 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, infof(data, "DoH Host name: %s", dohp->host); showdoh(data, &de); - ai = doh2ai(&de, dohp->host, dohp->port); - if(!ai) { + result = doh2ai(&de, dohp->host, dohp->port, &ai); + if(result) { de_cleanup(&de); - return CURLE_OUT_OF_MEMORY; + return result; } if(data->share) @@ -967,7 +976,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, Curl_freeaddrinfo(ai); } else { - data->state.async.dns = dns; + conn->resolve_async.dns = dns; *dnsp = dns; result = CURLE_OK; /* address resolution OK */ } diff --git a/lib/dynbuf.c b/lib/dynbuf.c index 0c9c491ae..2973d8da2 100644 --- a/lib/dynbuf.c +++ b/lib/dynbuf.c @@ -77,6 +77,7 @@ static CURLcode dyn_nappend(struct dynbuf *s, DEBUGASSERT(indx < s->toobig); DEBUGASSERT(!s->leng || s->bufr); DEBUGASSERT(a <= s->toobig); + DEBUGASSERT(!len || mem); if(fit > s->toobig) { Curl_dyn_free(s); @@ -174,10 +175,12 @@ CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len) */ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str) { - size_t n = strlen(str); + size_t n; + DEBUGASSERT(str); DEBUGASSERT(s); DEBUGASSERT(s->init == DYNINIT); DEBUGASSERT(!s->leng || s->bufr); + n = strlen(str); return dyn_nappend(s, (unsigned char *)str, n); } @@ -191,6 +194,7 @@ CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap) DEBUGASSERT(s); DEBUGASSERT(s->init == DYNINIT); DEBUGASSERT(!s->leng || s->bufr); + DEBUGASSERT(fmt); rc = Curl_dyn_vprintf(s, fmt, ap); if(!rc) diff --git a/lib/dynhds.c b/lib/dynhds.c index 979b3e825..d7548959b 100644 --- a/lib/dynhds.c +++ b/lib/dynhds.c @@ -27,6 +27,10 @@ #include "strcase.h" /* The last 3 #include files should be in this order */ +#ifdef USE_NGHTTP2 +#include +#include +#endif /* USE_NGHTTP2 */ #include "curl_printf.h" #include "curl_memory.h" #include "memdebug.h" @@ -365,3 +369,28 @@ CURLcode Curl_dynhds_h1_dprint(struct dynhds *dynhds, struct dynbuf *dbuf) return result; } +#ifdef USE_NGHTTP2 + +nghttp2_nv *Curl_dynhds_to_nva(struct dynhds *dynhds, size_t *pcount) +{ + nghttp2_nv *nva = calloc(1, sizeof(nghttp2_nv) * dynhds->hds_len); + size_t i; + + *pcount = 0; + if(!nva) + return NULL; + + for(i = 0; i < dynhds->hds_len; ++i) { + struct dynhds_entry *e = dynhds->hds[i]; + DEBUGASSERT(e); + nva[i].name = (unsigned char *)e->name; + nva[i].namelen = e->namelen; + nva[i].value = (unsigned char *)e->value; + nva[i].valuelen = e->valuelen; + nva[i].flags = NGHTTP2_NV_FLAG_NONE; + } + *pcount = dynhds->hds_len; + return nva; +} + +#endif /* USE_NGHTTP2 */ diff --git a/lib/dynhds.h b/lib/dynhds.h index 8a053480e..3b536000a 100644 --- a/lib/dynhds.h +++ b/lib/dynhds.h @@ -171,4 +171,13 @@ CURLcode Curl_dynhds_h1_add_line(struct dynhds *dynhds, */ CURLcode Curl_dynhds_h1_dprint(struct dynhds *dynhds, struct dynbuf *dbuf); +#ifdef USE_NGHTTP2 + +#include +#include + +nghttp2_nv *Curl_dynhds_to_nva(struct dynhds *dynhds, size_t *pcount); + +#endif /* USE_NGHTTP2 */ + #endif /* HEADER_CURL_DYNHDS_H */ diff --git a/lib/easy.c b/lib/easy.c index 6b4fb8efe..322d1a41b 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -112,7 +112,7 @@ static curl_simple_lock s_lock = CURL_SIMPLE_LOCK_INIT; #define system_strdup strdup #endif -#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) +#if defined(_MSC_VER) && defined(_DLL) # pragma warning(disable:4232) /* MSVC extension, dllimport identity */ #endif @@ -125,11 +125,11 @@ 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) +#if defined(_WIN32) && defined(UNICODE) curl_wcsdup_callback Curl_cwcsdup = Curl_wcsdup; #endif -#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) +#if defined(_MSC_VER) && defined(_DLL) # pragma warning(default:4232) /* MSVC extension, dllimport identity */ #endif @@ -153,7 +153,7 @@ 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) +#if defined(_WIN32) && defined(UNICODE) Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; #endif } @@ -188,18 +188,10 @@ static CURLcode global_init(long flags, bool memoryfuncs) goto fail; } -#if defined(USE_SSH) if(Curl_ssh_init()) { + DEBUGF(fprintf(stderr, "Error: Curl_ssh_init failed\n")); goto fail; } -#endif - -#ifdef USE_WOLFSSH - if(WS_SUCCESS != wolfSSH_Init()) { - DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n")); - return CURLE_FAILED_INIT; - } -#endif easy_init_flags = flags; @@ -295,7 +287,7 @@ void curl_global_cleanup(void) Curl_ssl_cleanup(); Curl_resolver_global_cleanup(); -#ifdef WIN32 +#ifdef _WIN32 Curl_win32_cleanup(easy_init_flags); #endif @@ -752,7 +744,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) return CURLE_RECURSIVE_API_CALL; /* Copy the MAXCONNECTS option to the multi handle */ - curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects); + curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, (long)data->set.maxconnects); mcode = curl_multi_add_handle(multi, data); if(mcode) { @@ -845,8 +837,10 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) dst->set = src->set; Curl_mime_initpart(&dst->set.mimepost); - /* clear all string pointers first */ + /* clear all dest string and blob pointers first, in case we error out + mid-function */ memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); + memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *)); /* duplicate all strings */ for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { @@ -855,8 +849,6 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) return result; } - /* clear all blob pointers first */ - memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *)); /* duplicate all blobs */ for(j = (enum dupblob)0; j < BLOB_LAST; j++) { result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]); @@ -866,10 +858,13 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) /* duplicate memory areas pointed to */ i = STRING_COPYPOSTFIELDS; - if(src->set.postfieldsize && src->set.str[i]) { - /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ - dst->set.str[i] = Curl_memdup(src->set.str[i], - curlx_sotouz(src->set.postfieldsize)); + if(src->set.str[i]) { + if(src->set.postfieldsize == -1) + dst->set.str[i] = strdup(src->set.str[i]); + else + /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ + dst->set.str[i] = Curl_memdup(src->set.str[i], + curlx_sotouz(src->set.postfieldsize)); if(!dst->set.str[i]) return CURLE_OUT_OF_MEMORY; /* point to the new copy */ @@ -919,18 +914,19 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) outcurl->progress.callback = data->progress.callback; #ifndef CURL_DISABLE_COOKIES - if(data->cookies) { + outcurl->state.cookielist = NULL; + if(data->cookies && data->state.cookie_engine) { /* If cookies are enabled in the parent handle, we enable them in the clone as well! */ - outcurl->cookies = Curl_cookie_init(data, NULL, outcurl->cookies, + outcurl->cookies = Curl_cookie_init(outcurl, NULL, outcurl->cookies, data->set.cookiesession); if(!outcurl->cookies) goto fail; } - if(data->set.cookielist) { - outcurl->set.cookielist = Curl_slist_duplicate(data->set.cookielist); - if(!outcurl->set.cookielist) + if(data->state.cookielist) { + outcurl->state.cookielist = Curl_slist_duplicate(data->state.cookielist); + if(!outcurl->state.cookielist) goto fail; } #endif @@ -976,33 +972,6 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) (void)Curl_hsts_loadcb(outcurl, outcurl->hsts); } #endif - /* Clone the resolver handle, if present, for the new handle */ - if(Curl_resolver_duphandle(outcurl, - &outcurl->state.async.resolver, - data->state.async.resolver)) - goto fail; - -#ifdef USE_ARES - { - CURLcode rc; - - rc = Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]); - if(rc && rc != CURLE_NOT_BUILT_IN) - goto fail; - - rc = Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]); - if(rc && rc != CURLE_NOT_BUILT_IN) - goto fail; - - rc = Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]); - if(rc && rc != CURLE_NOT_BUILT_IN) - goto fail; - - rc = Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]); - if(rc && rc != CURLE_NOT_BUILT_IN) - goto fail; - } -#endif /* USE_ARES */ Curl_initinfo(outcurl); @@ -1016,13 +985,10 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) if(outcurl) { #ifndef CURL_DISABLE_COOKIES - curl_slist_free_all(outcurl->set.cookielist); - outcurl->set.cookielist = NULL; + free(outcurl->cookies); #endif - Curl_safefree(outcurl->state.buffer); + free(outcurl->state.buffer); Curl_dyn_free(&outcurl->state.headerb); - Curl_safefree(outcurl->state.url); - Curl_safefree(outcurl->state.referer); Curl_altsvc_cleanup(&outcurl->asi); Curl_hsts_cleanup(&outcurl->hsts); Curl_freeset(outcurl); diff --git a/lib/easy_lock.h b/lib/easy_lock.h index d3fffd0d2..4f6764d42 100644 --- a/lib/easy_lock.h +++ b/lib/easy_lock.h @@ -93,6 +93,15 @@ static inline void curl_simple_lock_unlock(curl_simple_lock *lock) atomic_store_explicit(lock, false, memory_order_release); } +#elif defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + +#include + +#define curl_simple_lock pthread_mutex_t +#define CURL_SIMPLE_LOCK_INIT PTHREAD_MUTEX_INITIALIZER +#define curl_simple_lock_lock(m) pthread_mutex_lock(m) +#define curl_simple_lock_unlock(m) pthread_mutex_unlock(m) + #else #undef GLOBAL_INIT_IS_THREADSAFE diff --git a/lib/file.c b/lib/file.c index ffa9fb76d..c98507137 100644 --- a/lib/file.c +++ b/lib/file.c @@ -69,7 +69,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) +#if defined(_WIN32) || defined(MSDOS) || defined(__EMX__) #define DOS_FILESYSTEM 1 #elif defined(__amigaos4__) #define AMIGA_FILESYSTEM 1 @@ -414,7 +414,6 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) bool size_known; bool fstated = FALSE; char *buf = data->state.buffer; - curl_off_t bytecount = 0; int fd; struct FILEPROTO *file; @@ -563,7 +562,6 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) if(nread <= 0 || (size_known && (expected_size == 0))) break; - bytecount += nread; if(size_known) expected_size -= nread; @@ -571,10 +569,6 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) if(result) return result; - result = Curl_pgrsSetDownloadCounter(data, bytecount); - if(result) - return result; - if(Curl_pgrsUpdate(data)) result = CURLE_ABORTED_BY_CALLBACK; else diff --git a/lib/fopen.c b/lib/fopen.c index 75b8a7aa5..851279fe1 100644 --- a/lib/fopen.c +++ b/lib/fopen.c @@ -39,6 +39,51 @@ #include "curl_memory.h" #include "memdebug.h" +/* + The dirslash() function breaks a null-terminated pathname string into + directory and filename components then returns the directory component up + to, *AND INCLUDING*, a final '/'. If there is no directory in the path, + this instead returns a "" string. + + This function returns a pointer to malloc'ed memory. + + The input path to this function is expected to have a file name part. +*/ + +#ifdef _WIN32 +#define PATHSEP "\\" +#define IS_SEP(x) (((x) == '/') || ((x) == '\\')) +#elif defined(MSDOS) || defined(__EMX__) || defined(OS2) +#define PATHSEP "\\" +#define IS_SEP(x) ((x) == '\\') +#else +#define PATHSEP "/" +#define IS_SEP(x) ((x) == '/') +#endif + +static char *dirslash(const char *path) +{ + size_t n; + struct dynbuf out; + DEBUGASSERT(path); + Curl_dyn_init(&out, CURL_MAX_INPUT_LENGTH); + n = strlen(path); + if(n) { + /* find the rightmost path separator, if any */ + while(n && !IS_SEP(path[n-1])) + --n; + /* skip over all the path separators, if any */ + while(n && IS_SEP(path[n-1])) + --n; + } + if(Curl_dyn_addn(&out, path, n)) + return NULL; + /* if there was a directory, append a single trailing slash */ + if(n && Curl_dyn_addn(&out, PATHSEP, 1)) + return NULL; + return Curl_dyn_ptr(&out); +} + /* * Curl_fopen() opens a file for writing with a temp name, to be renamed * to the final name when completed. If there is an existing file using this @@ -50,47 +95,44 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, FILE **fh, char **tempname) { CURLcode result = CURLE_WRITE_ERROR; - unsigned char randsuffix[9]; + unsigned char randbuf[41]; char *tempstore = NULL; struct_stat sb; int fd = -1; + char *dir = NULL; *tempname = NULL; *fh = fopen(filename, FOPEN_WRITETEXT); if(!*fh) goto fail; - if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) + if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) { return CURLE_OK; + } fclose(*fh); *fh = NULL; - result = Curl_rand_alnum(data, randsuffix, sizeof(randsuffix)); + result = Curl_rand_alnum(data, randbuf, sizeof(randbuf)); if(result) goto fail; - tempstore = aprintf("%s.%s.tmp", filename, randsuffix); + dir = dirslash(filename); + if(dir) { + /* The temp file name should not end up too long for the target file + system */ + tempstore = aprintf("%s%s.tmp", dir, randbuf); + free(dir); + } + if(!tempstore) { result = CURLE_OUT_OF_MEMORY; goto fail; } result = CURLE_WRITE_ERROR; - fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600); + fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600|sb.st_mode); if(fd == -1) goto fail; -#ifdef HAVE_FCHMOD - { - struct_stat nsb; - if((fstat(fd, &nsb) != -1) && - (nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) { - /* if the user and group are the same, clone the original mode */ - if(fchmod(fd, (mode_t)sb.st_mode) == -1) - goto fail; - } - } -#endif - *fh = fdopen(fd, FOPEN_WRITETEXT); if(!*fh) goto fail; @@ -105,7 +147,6 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, } free(tempstore); - return result; } diff --git a/lib/formdata.c b/lib/formdata.c index e40c4bcb0..05dc9b53d 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -603,9 +603,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, app passed in a bad combo, so we better check for that first. */ if(form->name) { /* copy name (without strdup; possibly not null-terminated) */ - form->name = Curl_memdup(form->name, form->namelength? - form->namelength: - strlen(form->name) + 1); + form->name = Curl_strndup(form->name, form->namelength? + form->namelength: + strlen(form->name)); } if(!form->name) { return_value = CURL_FORMADD_MEMORY; @@ -792,7 +792,7 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len) /* wrap call to fseeko so it matches the calling convention of callback */ static int fseeko_wrapper(void *stream, curl_off_t offset, int whence) { -#if defined(HAVE_FSEEKO) +#if defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO) return fseeko(stream, (off_t)offset, whence); #elif defined(HAVE__FSEEKI64) return _fseeki64(stream, (__int64)offset, whence); diff --git a/lib/ftp.c b/lib/ftp.c index 518c92332..a8dcedf53 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -819,7 +819,7 @@ static int ftp_domore_getsock(struct Curl_easy *data, DEBUGF(infof(data, "ftp_domore_getsock()")); if(conn->cfilter[SECONDARYSOCKET] && !Curl_conn_is_connected(conn, SECONDARYSOCKET)) - return Curl_conn_get_select_socks(data, SECONDARYSOCKET, socks); + return 0; if(FTP_STOP == ftpc->state) { int bits = GETSOCK_READSOCK(0); @@ -947,7 +947,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, char *port_start = NULL; char *port_sep = NULL; - addr = calloc(addrlen + 1, 1); + addr = calloc(1, addrlen + 1); if(!addr) { result = CURLE_OUT_OF_MEMORY; goto out; @@ -4379,7 +4379,7 @@ static CURLcode ftp_setup_connection(struct Curl_easy *data, CURLcode result = CURLE_OK; struct ftp_conn *ftpc = &conn->proto.ftpc; - ftp = calloc(sizeof(struct FTP), 1); + ftp = calloc(1, sizeof(struct FTP)); if(!ftp) return CURLE_OUT_OF_MEMORY; diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c index 2a7ca5baf..82f1ea00d 100644 --- a/lib/ftplistparser.c +++ b/lib/ftplistparser.c @@ -55,9 +55,6 @@ /* The last #include file should be: */ #include "memdebug.h" -/* allocs buffer which will contain one line of LIST command response */ -#define FTP_BUFFER_ALLOCSIZE 160 - typedef enum { PL_UNIX_TOTALSIZE = 0, PL_UNIX_FILETYPE, diff --git a/lib/functypes.h b/lib/functypes.h index 075c02e54..ea66d3281 100644 --- a/lib/functypes.h +++ b/lib/functypes.h @@ -38,7 +38,7 @@ 2. For systems with config-*.h files, define them there. */ -#ifdef WIN32 +#ifdef _WIN32 /* int recv(SOCKET, char *, int, int) */ #define RECV_TYPE_ARG1 SOCKET #define RECV_TYPE_ARG2 char * diff --git a/lib/getenv.c b/lib/getenv.c index 806978472..48ee97228 100644 --- a/lib/getenv.c +++ b/lib/getenv.c @@ -31,10 +31,11 @@ static char *GetEnv(const char *variable) { -#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) || \ + defined(__ORBIS__) || defined(__PROSPERO__) /* PlayStation 4 and 5 */ (void)variable; return NULL; -#elif defined(WIN32) +#elif defined(_WIN32) /* This uses Windows API instead of C runtime getenv() to get the environment variable since some changes aren't always visible to the latter. #4774 */ char *buf = NULL; diff --git a/lib/hostasyn.c b/lib/hostasyn.c index 2f6762ca4..faf01c5f4 100644 --- a/lib/hostasyn.c +++ b/lib/hostasyn.c @@ -67,10 +67,11 @@ CURLcode Curl_addrinfo_callback(struct Curl_easy *data, int status, struct Curl_addrinfo *ai) { + struct connectdata *conn = data->conn; struct Curl_dns_entry *dns = NULL; CURLcode result = CURLE_OK; - data->state.async.status = status; + conn->resolve_async.status = status; if(CURL_ASYNC_SUCCESS == status) { if(ai) { @@ -78,8 +79,8 @@ CURLcode Curl_addrinfo_callback(struct Curl_easy *data, Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); dns = Curl_cache_addr(data, ai, - data->state.async.hostname, 0, - data->state.async.port); + conn->resolve_async.hostname, 0, + conn->resolve_async.port); if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); @@ -94,12 +95,12 @@ CURLcode Curl_addrinfo_callback(struct Curl_easy *data, } } - data->state.async.dns = dns; + conn->resolve_async.dns = dns; /* Set async.done TRUE last in this function since it may be used multi- threaded and once this is TRUE the other thread may read fields from the async struct */ - data->state.async.done = TRUE; + conn->resolve_async.done = TRUE; /* IPv4: The input hostent struct will be freed by ares when we return from this function */ diff --git a/lib/hostip.c b/lib/hostip.c index 3cd9a65c5..e7c318af7 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -117,6 +117,13 @@ static void freednsentry(void *freethis); +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void show_resolve_info(struct Curl_easy *data, + struct Curl_dns_entry *dns); +#else +#define show_resolve_info(x,y) Curl_nop_stmt +#endif + /* * Curl_printable_address() stores a printable version of the 1st address * given in the 'ai' argument. The result will be stored in the buf that is @@ -481,9 +488,11 @@ Curl_cache_addr(struct Curl_easy *data, return NULL; } #endif + if(!hostlen) + hostlen = strlen(hostname); /* Create a new cache entry */ - dns = calloc(1, sizeof(struct Curl_dns_entry)); + dns = calloc(1, sizeof(struct Curl_dns_entry) + hostlen); if(!dns) { return NULL; } @@ -497,6 +506,9 @@ Curl_cache_addr(struct Curl_easy *data, time(&dns->timestamp); if(dns->timestamp == 0) dns->timestamp = 1; /* zero indicates permanent CURLOPT_RESOLVE entry */ + dns->hostport = port; + if(hostlen) + memcpy(dns->hostname, hostname, hostlen); /* Store the resolved data in our DNS cache. */ dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len + 1, @@ -521,7 +533,7 @@ static struct Curl_addrinfo *get_localhost6(int port, const char *name) struct sockaddr_in6 sa6; unsigned char ipv6[16]; unsigned short port16 = (unsigned short)(port & 0xffff); - ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1); + ca = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1); if(!ca) return NULL; @@ -568,7 +580,7 @@ static struct Curl_addrinfo *get_localhost(int port, const char *name) return NULL; memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4)); - ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1); + ca = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1); if(!ca) return NULL; ca->ai_flags = 0; @@ -729,7 +741,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, Curl_set_in_callback(data, true); st = data->set.resolver_start( #ifdef USE_CURL_ASYNC - data->state.async.resolver, + conn->resolve_async.resolver, #else NULL, #endif @@ -823,8 +835,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, if(!dns) /* returned failure, bail out nicely */ Curl_freeaddrinfo(addr); - else + else { rc = CURLRESOLV_RESOLVED; + show_resolve_info(data, dns); + } } } @@ -839,7 +853,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, * execution. This effectively causes the remainder of the application to run * within a signal handler which is nonportable and could lead to problems. */ -static +CURL_NORETURN static void alarmfunc(int sig) { (void)sig; @@ -1269,9 +1283,11 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } +#ifndef CURL_DISABLE_VERBOSE_STRINGS infof(data, "Added %.*s:%d:%s to DNS cache%s", (int)hlen, host_begin, port, addresses, permanent ? "" : " (non-permanent)"); +#endif /* Wildcard hostname */ if((hlen == 1) && (host_begin[0] == '*')) { @@ -1285,18 +1301,89 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) return CURLE_OK; } +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void show_resolve_info(struct Curl_easy *data, + struct Curl_dns_entry *dns) +{ + struct Curl_addrinfo *a; + CURLcode result = CURLE_OK; +#ifdef CURLRES_IPV6 + struct dynbuf out[2]; +#else + struct dynbuf out[1]; +#endif + DEBUGASSERT(data); + DEBUGASSERT(dns); + + if(!data->set.verbose || + /* ignore no name or numerical IP addresses */ + !dns->hostname[0] || Curl_host_is_ipnum(dns->hostname)) + return; + + a = dns->addr; + + infof(data, "Host %s:%d was resolved.", + (dns->hostname[0] ? dns->hostname : "(none)"), dns->hostport); + + Curl_dyn_init(&out[0], 1024); +#ifdef CURLRES_IPV6 + Curl_dyn_init(&out[1], 1024); +#endif + + while(a) { + if( +#ifdef CURLRES_IPV6 + a->ai_family == PF_INET6 || +#endif + a->ai_family == PF_INET) { + char buf[MAX_IPADR_LEN]; + struct dynbuf *d = &out[(a->ai_family != PF_INET)]; + Curl_printable_address(a, buf, sizeof(buf)); + if(Curl_dyn_len(d)) + result = Curl_dyn_addn(d, ", ", 2); + if(!result) + result = Curl_dyn_add(d, buf); + if(result) { + infof(data, "too many IP, can't show"); + goto fail; + } + } + a = a->ai_next; + } + +#ifdef CURLRES_IPV6 + infof(data, "IPv6: %s", + (Curl_dyn_len(&out[1]) ? Curl_dyn_ptr(&out[1]) : "(none)")); +#endif + infof(data, "IPv4: %s", + (Curl_dyn_len(&out[0]) ? Curl_dyn_ptr(&out[0]) : "(none)")); + +fail: + Curl_dyn_free(&out[0]); +#ifdef CURLRES_IPV6 + Curl_dyn_free(&out[1]); +#endif +} +#endif + CURLcode Curl_resolv_check(struct Curl_easy *data, struct Curl_dns_entry **dns) { + CURLcode result; #if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH) (void)data; (void)dns; #endif #ifndef CURL_DISABLE_DOH - if(data->conn->bits.doh) - return Curl_doh_is_resolved(data, dns); + if(data->conn->bits.doh) { + result = Curl_doh_is_resolved(data, dns); + } + else #endif - return Curl_resolver_is_resolved(data, dns); + result = Curl_resolver_is_resolved(data, dns); + if(*dns) + show_resolve_info(data, *dns); + return result; } int Curl_resolv_getsock(struct Curl_easy *data, @@ -1328,9 +1415,9 @@ CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_done) struct connectdata *conn = data->conn; #ifdef USE_CURL_ASYNC - if(data->state.async.dns) { - conn->dns_entry = data->state.async.dns; - data->state.async.dns = NULL; + if(conn->resolve_async.dns) { + conn->dns_entry = conn->resolve_async.dns; + conn->resolve_async.dns = NULL; } #endif @@ -1352,11 +1439,11 @@ CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_done) #ifdef USE_CURL_ASYNC CURLcode Curl_resolver_error(struct Curl_easy *data) { + struct connectdata *conn = data->conn; const char *host_or_proxy; CURLcode result; #ifndef CURL_DISABLE_PROXY - struct connectdata *conn = data->conn; if(conn->bits.httpproxy) { host_or_proxy = "proxy"; result = CURLE_COULDNT_RESOLVE_PROXY; @@ -1369,7 +1456,7 @@ CURLcode Curl_resolver_error(struct Curl_easy *data) } failf(data, "Could not resolve %s: %s", host_or_proxy, - data->state.async.hostname); + conn->resolve_async.hostname); return result; } diff --git a/lib/hostip.h b/lib/hostip.h index b68f539b2..fb53a5776 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -64,6 +64,10 @@ struct Curl_dns_entry { time_t timestamp; /* use-counter, use Curl_resolv_unlock to release reference */ long inuse; + /* hostname port number that resolved to addr. */ + int hostport; + /* hostname that resolved to addr. may be NULL (unix domain sockets). */ + char hostname[1]; }; bool Curl_host_is_ipnum(const char *hostname); diff --git a/lib/hostip6.c b/lib/hostip6.c index 6b0ba55e9..18969a7a7 100644 --- a/lib/hostip6.c +++ b/lib/hostip6.c @@ -71,8 +71,7 @@ bool Curl_ipvalid(struct Curl_easy *data, struct connectdata *conn) #if defined(CURLRES_SYNCH) #ifdef DEBUG_ADDRINFO -static void dump_addrinfo(struct connectdata *conn, - const struct Curl_addrinfo *ai) +static void dump_addrinfo(const struct Curl_addrinfo *ai) { printf("dump_addrinfo:\n"); for(; ai; ai = ai->ai_next) { @@ -84,7 +83,7 @@ static void dump_addrinfo(struct connectdata *conn, } } #else -#define dump_addrinfo(x,y) Curl_nop_stmt +#define dump_addrinfo(x) Curl_nop_stmt #endif /* @@ -149,7 +148,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, Curl_addrinfo_set_port(res, port); } - dump_addrinfo(conn, res); + dump_addrinfo(res); return res; } diff --git a/lib/hsts.c b/lib/hsts.c index 7ecf0042a..9314be294 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -40,6 +40,7 @@ #include "fopen.h" #include "rename.h" #include "share.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -76,7 +77,7 @@ static time_t hsts_debugtime(void *unused) struct hsts *Curl_hsts_init(void) { - struct hsts *h = calloc(sizeof(struct hsts), 1); + struct hsts *h = calloc(1, sizeof(struct hsts)); if(h) { Curl_llist_init(&h->list, NULL); } @@ -108,7 +109,7 @@ void Curl_hsts_cleanup(struct hsts **hp) static struct stsentry *hsts_entry(void) { - return calloc(sizeof(struct stsentry), 1); + return calloc(1, sizeof(struct stsentry)); } static CURLcode hsts_create(struct hsts *h, @@ -116,23 +117,30 @@ static CURLcode hsts_create(struct hsts *h, bool subdomains, curl_off_t expires) { - struct stsentry *sts = hsts_entry(); + struct stsentry *sts; char *duphost; size_t hlen; + DEBUGASSERT(h); + DEBUGASSERT(hostname); + + hlen = strlen(hostname); + if(hlen && (hostname[hlen - 1] == '.')) + /* strip off any trailing dot */ + --hlen; + if(!hlen) + /* no host name left */ + return CURLE_BAD_FUNCTION_ARGUMENT; + + sts = hsts_entry(); if(!sts) return CURLE_OUT_OF_MEMORY; - duphost = strdup(hostname); + duphost = Curl_strndup(hostname, hlen); if(!duphost) { free(sts); return CURLE_OUT_OF_MEMORY; } - hlen = strlen(duphost); - if(duphost[hlen - 1] == '.') - /* strip off trailing any dot */ - duphost[--hlen] = 0; - sts->host = duphost; sts->expires = expires; sts->includeSubDomains = subdomains; @@ -564,7 +572,7 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h) void Curl_hsts_loadfiles(struct Curl_easy *data) { - struct curl_slist *l = data->set.hstslist; + struct curl_slist *l = data->state.hstslist; if(l) { Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE); diff --git a/lib/http.c b/lib/http.c index 40ef70df5..be6d442e8 100644 --- a/lib/http.c +++ b/lib/http.c @@ -836,6 +836,7 @@ output_auth_headers(struct Curl_easy *data, (data->state.aptr.user ? data->state.aptr.user : "")); #else + (void)proxy; infof(data, "Server auth using %s with user '%s'", auth, data->state.aptr.user ? data->state.aptr.user : ""); @@ -845,7 +846,7 @@ output_auth_headers(struct Curl_easy *data, else authstatus->multipass = FALSE; - return CURLE_OK; + return result; } /** @@ -970,17 +971,21 @@ Curl_http_output_auth(struct Curl_easy *data, } #endif -/* - * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: - * headers. They are dealt with both in the transfer.c main loop and in the - * proxy CONNECT loop. - */ - +#if defined(USE_SPNEGO) || defined(USE_NTLM) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) || \ + !defined(CURL_DISABLE_BASIC_AUTH) || \ + !defined(CURL_DISABLE_BEARER_AUTH) static int is_valid_auth_separator(char ch) { return ch == '\0' || ch == ',' || ISSPACE(ch); } +#endif +/* + * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: + * headers. They are dealt with both in the transfer.c main loop and in the + * proxy CONNECT loop. + */ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, const char *auth) /* the first non-space */ { @@ -992,11 +997,15 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state : &conn->http_negotiate_state; #endif +#if defined(USE_SPNEGO) || \ + defined(USE_NTLM) || \ + !defined(CURL_DISABLE_DIGEST_AUTH) || \ + !defined(CURL_DISABLE_BASIC_AUTH) || \ + !defined(CURL_DISABLE_BEARER_AUTH) + unsigned long *availp; struct auth *authp; - (void) conn; /* In case conditionals make it unused. */ - if(proxy) { availp = &data->info.proxyauthavail; authp = &data->state.authproxy; @@ -1005,6 +1014,11 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, availp = &data->info.httpauthavail; authp = &data->state.authhost; } +#else + (void) proxy; +#endif + + (void) conn; /* In case conditionals make it unused. */ /* * Here we check if we want the specific single authentication (using ==) and @@ -1140,7 +1154,14 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, } } #else - ; + { + /* + * Empty block to terminate the if-else chain correctly. + * + * A semicolon would yield the same result here, but can cause a + * compiler warning when -Wextra is enabled. + */ + } #endif /* there may be multiple methods on one line, so keep reading */ @@ -1403,7 +1424,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in, * and install our own `data->state.fread_func` that * on subsequent calls reads `in` empty. * - when the whisked away `in` is empty, the `fread_func` - * is restored ot its original state. + * is restored to its original state. * The problem is that `fread_func` can only return * `upload_buffer_size` lengths. If the send we do here * is larger and blocks, we do re-sending with smaller @@ -1678,8 +1699,6 @@ static CURLcode expect100(struct Curl_easy *data, struct dynbuf *req) { CURLcode result = CURLE_OK; - data->state.expect100header = FALSE; /* default to false unless it is set - to TRUE below */ if(!data->state.disableexpect && Curl_use_http_1_1plus(data, conn) && (conn->httpversion < 20)) { /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an @@ -2414,14 +2433,16 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, /* Convert the form structure into a mime structure, then keep the conversion */ if(!data->state.formp) { - data->state.formp = calloc(sizeof(curl_mimepart), 1); + data->state.formp = calloc(1, sizeof(curl_mimepart)); if(!data->state.formp) return CURLE_OUT_OF_MEMORY; Curl_mime_cleanpart(data->state.formp); result = Curl_getformdata(data, data->state.formp, data->set.httppost, data->state.fread_func); - if(result) + if(result) { + Curl_safefree(data->state.formp); return result; + } data->state.mimepost = data->state.formp; } break; @@ -2494,6 +2515,29 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, return result; } +static CURLcode addexpect(struct Curl_easy *data, struct connectdata *conn, + struct dynbuf *r) +{ + data->state.expect100header = FALSE; + /* Avoid Expect: 100-continue if Upgrade: is used */ + if(data->req.upgr101 == UPGR101_INIT) { + struct HTTP *http = data->req.p.http; + /* For really small puts we don't use Expect: headers at all, and for + the somewhat bigger ones we allow the app to disable it. Just make + sure that the expect100header is always set to the preferred value + here. */ + char *ptr = Curl_checkheaders(data, STRCONST("Expect")); + if(ptr) { + data->state.expect100header = + Curl_compareheader(ptr, STRCONST("Expect:"), + STRCONST("100-continue")); + } + else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) + return expect100(data, conn, r); + } + return CURLE_OK; +} + CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, struct dynbuf *r, Curl_HttpReq httpreq) { @@ -2506,14 +2550,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, #endif CURLcode result = CURLE_OK; struct HTTP *http = data->req.p.http; - const char *ptr; - - /* If 'authdone' is FALSE, we must not set the write socket index to the - Curl_transfer() call below, as we're not ready to actually upload any - data yet. */ switch(httpreq) { - case HTTPREQ_PUT: /* Let's PUT the data to the server! */ if(conn->bits.authneg) @@ -2531,20 +2569,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, return result; } - /* For really small puts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ - ptr = Curl_checkheaders(data, STRCONST("Expect")); - if(ptr) { - data->state.expect100header = - Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); - } - else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) { - result = expect100(data, conn, r); - if(result) - return result; - } + result = addexpect(data, conn, r); + if(result) + return result; /* end of headers */ result = Curl_dyn_addn(r, STRCONST("\r\n")); @@ -2617,22 +2644,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, } #endif - /* For really small posts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ - ptr = Curl_checkheaders(data, STRCONST("Expect")); - if(ptr) { - data->state.expect100header = - Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); - } - else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) { - result = expect100(data, conn, r); - if(result) - return result; - } - else - data->state.expect100header = FALSE; + result = addexpect(data, conn, r); + if(result) + return result; /* make the request end in a true CRLF */ result = Curl_dyn_addn(r, STRCONST("\r\n")); @@ -2692,22 +2706,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, return result; } - /* For really small posts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ - ptr = Curl_checkheaders(data, STRCONST("Expect")); - if(ptr) { - data->state.expect100header = - Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue")); - } - else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) { - result = expect100(data, conn, r); - if(result) - return result; - } - else - data->state.expect100header = FALSE; + result = addexpect(data, conn, r); + if(result) + return result; #ifndef USE_HYPER /* With Hyper the body is always passed on separately */ @@ -3193,7 +3194,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) DEBUGASSERT(Curl_conn_is_http2(data, conn, FIRSTSOCKET)); break; case CURL_HTTP_VERSION_1_1: - /* continue with HTTP/1.1 when explicitly requested */ + /* continue with HTTP/1.x when explicitly requested */ break; default: /* Check if user wants to use HTTP/2 with clear TCP */ @@ -3685,7 +3686,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, k->content_range = TRUE; } } - else + else if(k->httpcode < 300) data->state.resume_from = 0; /* get everything */ } #if !defined(CURL_DISABLE_COOKIES) @@ -3996,35 +3997,30 @@ CURLcode Curl_bump_headersize(struct Curl_easy *data, */ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, struct connectdata *conn, - ssize_t *nread, - bool *stop_reading) + const char *buf, size_t blen, + size_t *pconsumed) { CURLcode result; struct SingleRequest *k = &data->req; - ssize_t onread = *nread; - char *ostr = k->str; char *headp; - char *str_start; char *end_ptr; /* header line within buffer loop */ + *pconsumed = 0; do { - size_t rest_length; - size_t full_length; + size_t line_length; int writetype; - /* str_start is start of line within buf */ - str_start = k->str; - /* data is in network encoding so use 0x0a instead of '\n' */ - end_ptr = memchr(str_start, 0x0a, *nread); + end_ptr = memchr(buf, 0x0a, blen); if(!end_ptr) { /* Not a complete header line within buffer, append the data to the end of the headerbuff. */ - result = Curl_dyn_addn(&data->state.headerb, str_start, *nread); + result = Curl_dyn_addn(&data->state.headerb, buf, blen); if(result) return result; + *pconsumed += blen; if(!k->headerline) { /* check if this looks like a protocol header */ @@ -4036,31 +4032,28 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(st == STATUS_BAD) { /* this is not the beginning of a protocol first header line */ k->header = FALSE; - k->badheader = HEADER_ALLBAD; + k->badheader = TRUE; streamclose(conn, "bad HTTP: No end-of-message indicator"); if(!data->set.http09_allowed) { failf(data, "Received HTTP/0.9 when not allowed"); return CURLE_UNSUPPORTED_PROTOCOL; } - break; + goto out; } } - - break; /* read more and try again */ + goto out; /* read more and try again */ } /* decrease the size of the remaining (supposed) header line */ - rest_length = (end_ptr - k->str) + 1; - *nread -= (ssize_t)rest_length; - - k->str = end_ptr + 1; /* move past new line */ - - full_length = k->str - str_start; - - result = Curl_dyn_addn(&data->state.headerb, str_start, full_length); + line_length = (end_ptr - buf) + 1; + result = Curl_dyn_addn(&data->state.headerb, buf, line_length); if(result) return result; + blen -= line_length; + buf += line_length; + *pconsumed += line_length; + /**** * We now have a FULL header line in 'headerb'. *****/ @@ -4078,14 +4071,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, return CURLE_UNSUPPORTED_PROTOCOL; } k->header = FALSE; - if(*nread) + if(blen) /* since there's more, this is a partial bad header */ - k->badheader = HEADER_PARTHEADER; + k->badheader = TRUE; else { /* this was all we read so it's all a bad header */ - k->badheader = HEADER_ALLBAD; - *nread = onread; - k->str = ostr; + k->badheader = TRUE; return CURLE_OK; } break; @@ -4139,22 +4130,23 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, /* switch to http2 now. The bytes after response headers are also processed here, otherwise they are lost. */ - result = Curl_http2_upgrade(data, conn, FIRSTSOCKET, - k->str, *nread); + result = Curl_http2_upgrade(data, conn, FIRSTSOCKET, buf, blen); if(result) return result; - *nread = 0; + *pconsumed += blen; + blen = 0; } #ifdef USE_WEBSOCKETS else if(k->upgr101 == UPGR101_WS) { /* verify the response */ - result = Curl_ws_accept(data, k->str, *nread); + result = Curl_ws_accept(data, buf, blen); if(result) return result; k->header = FALSE; /* no more header to parse! */ if(data->set.connect_only) { k->keepon &= ~KEEP_RECV; /* read no more content */ - *nread = 0; + *pconsumed += blen; + blen = 0; } } #endif @@ -4366,7 +4358,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, * out and return home. */ if(data->req.no_body) - *stop_reading = TRUE; + k->download_done = TRUE; #ifndef CURL_DISABLE_RTSP else if((conn->handler->protocol & CURLPROTO_RTSP) && (data->set.rtspreq == RTSPREQ_DESCRIBE) && @@ -4375,7 +4367,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, absent, a length 0 must be assumed. It will prevent libcurl from hanging on DESCRIBE request that got refused for whatever reason */ - *stop_reading = TRUE; + k->download_done = TRUE; #endif /* If max download size is *zero* (nothing) we already have @@ -4386,15 +4378,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(0 == k->maxdownload && !Curl_conn_is_http2(data, conn, FIRSTSOCKET) && !Curl_conn_is_http3(data, conn, FIRSTSOCKET)) - *stop_reading = TRUE; + k->download_done = TRUE; - if(*stop_reading) { - /* we make sure that this socket isn't read more now */ - k->keepon &= ~KEEP_RECV; - } - - Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen); - break; /* exit header line loop */ + Curl_debug(data, CURLINFO_HEADER_IN, + Curl_dyn_ptr(&data->state.headerb), + Curl_dyn_len(&data->state.headerb)); + goto out; /* exit header line loop */ } /* We continue reading headers, reset the line-based header */ @@ -4583,12 +4572,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, Curl_dyn_reset(&data->state.headerb); } - while(*k->str); /* header line within buffer */ + while(blen); /* We might have reached the end of the header part here, but there might be a non-header part left in the end of the read buffer. */ - +out: return CURLE_OK; } @@ -4618,17 +4607,6 @@ CURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len) return result; } -/* simple implementation of strndup(), which isn't portable */ -static char *my_strndup(const char *ptr, size_t len) -{ - char *copy = malloc(len + 1); - if(!copy) - return NULL; - memcpy(copy, ptr, len); - copy[len] = '\0'; - return copy; -} - CURLcode Curl_http_req_make(struct httpreq **preq, const char *method, size_t m_len, const char *scheme, size_t s_len, @@ -4647,17 +4625,17 @@ CURLcode Curl_http_req_make(struct httpreq **preq, goto out; memcpy(req->method, method, m_len); if(scheme) { - req->scheme = my_strndup(scheme, s_len); + req->scheme = Curl_strndup(scheme, s_len); if(!req->scheme) goto out; } if(authority) { - req->authority = my_strndup(authority, a_len); + req->authority = Curl_strndup(authority, a_len); if(!req->authority) goto out; } if(path) { - req->path = my_strndup(path, p_len); + req->path = Curl_strndup(path, p_len); if(!req->path) goto out; } diff --git a/lib/http.h b/lib/http.h index 9ee3c6537..56b091301 100644 --- a/lib/http.h +++ b/lib/http.h @@ -227,8 +227,8 @@ CURLcode Curl_http_size(struct Curl_easy *data); CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, struct connectdata *conn, - ssize_t *nread, - bool *stop_reading); + const char *buf, size_t blen, + size_t *pconsumed); /** * Curl_http_output_auth() setups the authentication headers for the @@ -263,7 +263,7 @@ CURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len); * All about a core HTTP request, excluding body and trailers */ struct httpreq { - char method[12]; + char method[24]; char *scheme; char *authority; char *path; diff --git a/lib/http2.c b/lib/http2.c index c8b059498..973848484 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -107,14 +107,14 @@ static int populate_settings(nghttp2_settings_entry *iv, return 3; } -static size_t populate_binsettings(uint8_t *binsettings, - struct Curl_easy *data) +static ssize_t populate_binsettings(uint8_t *binsettings, + struct Curl_easy *data) { nghttp2_settings_entry iv[H2_SETTINGS_IV_LEN]; int ivlen; ivlen = populate_settings(iv, data); - /* this returns number of bytes it wrote */ + /* this returns number of bytes it wrote or a negative number on error. */ return nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, iv, ivlen); } @@ -369,12 +369,15 @@ static ssize_t nw_out_writer(void *writer_ctx, { struct Curl_cfilter *cf = writer_ctx; struct Curl_easy *data = CF_DATA_CURRENT(cf); - ssize_t nwritten; - nwritten = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen, err); - if(nwritten > 0) - CURL_TRC_CF(data, cf, "[0] egress: wrote %zd bytes", nwritten); - return nwritten; + if(data) { + ssize_t nwritten = Curl_conn_cf_send(cf->next, data, + (const char *)buf, buflen, 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, @@ -452,9 +455,14 @@ static CURLcode cf_h2_ctx_init(struct Curl_cfilter *cf, * in the H1 request and we upgrade from there. This stream * is opened implicitly as #1. */ uint8_t binsettings[H2_BINSETTINGS_LEN]; - size_t binlen; /* length of the binsettings data */ + ssize_t binlen; /* length of the binsettings data */ binlen = populate_binsettings(binsettings, data); + if(binlen <= 0) { + failf(data, "nghttp2 unexpectedly failed on pack_settings_payload"); + result = CURLE_FAILED_INIT; + goto out; + } result = http2_data_setup(cf, data, &stream); if(result) @@ -1076,16 +1084,11 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf, stream->reset = TRUE; } stream->send_closed = TRUE; - data->req.keepon &= ~KEEP_SEND_HOLD; drain_stream(cf, data, stream); break; case NGHTTP2_WINDOW_UPDATE: - if((data->req.keepon & KEEP_SEND_HOLD) && - (data->req.keepon & KEEP_SEND)) { - data->req.keepon &= ~KEEP_SEND_HOLD; + if(CURL_WANT_SEND(data)) { drain_stream(cf, data, stream); - CURL_TRC_CF(data, cf, "[%d] un-holding after win update", - stream_id); } break; default: @@ -1230,15 +1233,10 @@ 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((data->req.keepon & KEEP_SEND_HOLD) && - (data->req.keepon & KEEP_SEND)) { + if(CURL_WANT_SEND(data)) { struct stream_ctx *stream = H2_STREAM_CTX(data); - data->req.keepon &= ~KEEP_SEND_HOLD; - if(stream) { + if(stream) drain_stream(cf, data, stream); - CURL_TRC_CF(data, cf, "[%d] un-holding after SETTINGS", - stream_id); - } } } break; @@ -1338,7 +1336,6 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, stream->error = error_code; if(stream->error) stream->reset = TRUE; - data_s->req.keepon &= ~KEEP_SEND_HOLD; if(stream->error) CURL_TRC_CF(data_s, cf, "[%d] RESET: %s (err %d)", @@ -1602,10 +1599,10 @@ static int error_callback(nghttp2_session *session, size_t len, void *userp) { + struct Curl_cfilter *cf = userp; + struct Curl_easy *data = CF_DATA_CURRENT(cf); (void)session; - (void)msg; - (void)len; - (void)userp; + failf(data, "%.*s", (int)len, msg); return 0; } #endif @@ -1621,7 +1618,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, size_t blen; struct SingleRequest *k = &data->req; uint8_t binsettings[H2_BINSETTINGS_LEN]; - size_t binlen; /* length of the binsettings data */ + ssize_t binlen; /* length of the binsettings data */ binlen = populate_binsettings(binsettings, data); if(binlen <= 0) { @@ -2052,23 +2049,13 @@ static ssize_t h2_submit(struct stream_ctx **pstream, /* no longer needed */ Curl_h1_req_parse_free(&stream->h1); - nheader = Curl_dynhds_count(&h2_headers); - nva = malloc(sizeof(nghttp2_nv) * nheader); + nva = Curl_dynhds_to_nva(&h2_headers, &nheader); if(!nva) { *err = CURLE_OUT_OF_MEMORY; nwritten = -1; goto out; } - for(i = 0; i < nheader; ++i) { - struct dynhds_entry *e = Curl_dynhds_getn(&h2_headers, i); - nva[i].name = (unsigned char *)e->name; - nva[i].namelen = e->namelen; - nva[i].value = (unsigned char *)e->value; - nva[i].valuelen = e->valuelen; - nva[i].flags = NGHTTP2_NV_FLAG_NONE; - } - h2_pri_spec(data, &pri_spec); if(!nghttp2_session_check_request_allowed(ctx->h2)) CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)"); @@ -2272,14 +2259,6 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, * frame buffer or our network out buffer. */ size_t rwin = nghttp2_session_get_stream_remote_window_size(ctx->h2, stream->id); - if(rwin == 0) { - /* H2 flow window exhaustion. We need to HOLD upload until we get - * a WINDOW_UPDATE from the server. */ - data->req.keepon |= KEEP_SEND_HOLD; - CURL_TRC_CF(data, cf, "[%d] holding send as remote flow " - "window is exhausted", stream->id); - } - /* Whatever the cause, we need to return CURL_EAGAIN for this call. * We have unwritten state that needs us being invoked again and EAGAIN * is the only way to ensure that. */ @@ -2331,38 +2310,34 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data, return nwritten; } -static int cf_h2_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *sock) +static void cf_h2_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_h2_ctx *ctx = cf->ctx; - struct SingleRequest *k = &data->req; - struct stream_ctx *stream = H2_STREAM_CTX(data); - int bitmap = GETSOCK_BLANK; - struct cf_call_data save; + bool want_recv = CURL_WANT_RECV(data); + bool want_send = CURL_WANT_SEND(data); - CF_DATA_SAVE(save, cf, data); - sock[0] = Curl_conn_cf_get_socket(cf, data); - - if(!(k->keepon & (KEEP_RECV_PAUSE|KEEP_RECV_HOLD))) - /* Unless paused - in an HTTP/2 connection we can basically always get a - frame so we should always be ready for one */ - bitmap |= GETSOCK_READSOCK(0); - - /* we're (still uploading OR the HTTP/2 layer wants to send data) AND - there's a window to send data in */ - if((((k->keepon & KEEP_SENDBITS) == KEEP_SEND) || - nghttp2_session_want_write(ctx->h2)) && - (nghttp2_session_get_remote_window_size(ctx->h2) && - nghttp2_session_get_stream_remote_window_size(ctx->h2, - stream->id))) - bitmap |= GETSOCK_WRITESOCK(0); + if(ctx->h2 && (want_recv || want_send)) { + struct stream_ctx *stream = H2_STREAM_CTX(data); + curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); + struct cf_call_data save; + bool c_exhaust, s_exhaust; - CF_DATA_RESTORE(cf, save); - return bitmap; + CF_DATA_SAVE(save, cf, data); + c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2); + s_exhaust = stream && stream->id >= 0 && + !nghttp2_session_get_stream_remote_window_size(ctx->h2, + stream->id); + want_recv = (want_recv || c_exhaust || s_exhaust); + want_send = (!s_exhaust && want_send) || + (!c_exhaust && nghttp2_session_want_write(ctx->h2)); + + Curl_pollset_set(data, ps, sock, want_recv, want_send); + CF_DATA_RESTORE(cf, save); + } } - static CURLcode cf_h2_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool blocking, bool *done) @@ -2511,14 +2486,15 @@ static CURLcode cf_h2_cntrl(struct Curl_cfilter *cf, case CF_CTRL_DATA_PAUSE: result = http2_data_pause(cf, data, (arg1 != 0)); break; - case CF_CTRL_DATA_DONE_SEND: { + case CF_CTRL_DATA_DONE_SEND: result = http2_data_done_send(cf, data); break; - } - case CF_CTRL_DATA_DONE: { + case CF_CTRL_DATA_DETACH: + http2_data_done(cf, data, TRUE); + break; + case CF_CTRL_DATA_DONE: http2_data_done(cf, data, arg1 != 0); break; - } default: break; } @@ -2606,7 +2582,7 @@ struct Curl_cftype Curl_cft_nghttp2 = { cf_h2_connect, cf_h2_close, Curl_cf_def_get_host, - cf_h2_get_select_socks, + cf_h2_adjust_pollset, cf_h2_data_pending, cf_h2_send, cf_h2_recv, @@ -2626,7 +2602,7 @@ static CURLcode http2_cfilter_add(struct Curl_cfilter **pcf, CURLcode result = CURLE_OUT_OF_MEMORY; DEBUGASSERT(data->conn); - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) goto out; @@ -2652,7 +2628,7 @@ static CURLcode http2_cfilter_insert_after(struct Curl_cfilter *cf, CURLcode result = CURLE_OUT_OF_MEMORY; (void)data; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) goto out; diff --git a/lib/http_aws_sigv4.c b/lib/http_aws_sigv4.c index 901c22fbb..b673055f3 100644 --- a/lib/http_aws_sigv4.c +++ b/lib/http_aws_sigv4.c @@ -456,6 +456,7 @@ static CURLcode canon_query(struct Curl_easy *data, for(i = 0; !result && (i < entry); i++, ap++) { size_t len; const char *q = ap->p; + bool found_equals = false; if(!ap->len) continue; for(len = ap->len; len && !result; q++, len--) { @@ -467,9 +468,13 @@ static CURLcode canon_query(struct Curl_easy *data, case '.': case '_': case '~': + /* allowed as-is */ + result = Curl_dyn_addn(dq, q, 1); + break; case '=': /* allowed as-is */ result = Curl_dyn_addn(dq, q, 1); + found_equals = true; break; case '%': /* uppercase the following if hexadecimal */ @@ -497,7 +502,11 @@ static CURLcode canon_query(struct Curl_easy *data, } } } - if(i < entry - 1) { + if(!result && !found_equals) { + /* queries without value still need an equals */ + result = Curl_dyn_addn(dq, "=", 1); + } + if(!result && i < entry - 1) { /* insert ampersands between query pairs */ result = Curl_dyn_addn(dq, "&", 1); } diff --git a/lib/http_chunks.c b/lib/http_chunks.c index 2a401d14c..acdb10863 100644 --- a/lib/http_chunks.c +++ b/lib/http_chunks.c @@ -75,8 +75,6 @@ */ -#define isxdigit_ascii(x) Curl_isxdigit(x) - void Curl_httpchunk_init(struct Curl_easy *data) { struct connectdata *conn = data->conn; @@ -98,9 +96,9 @@ void Curl_httpchunk_init(struct Curl_easy *data) * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. */ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, - char *datap, - ssize_t datalen, - ssize_t *wrote, + char *buf, + size_t blen, + size_t *pconsumed, CURLcode *extrap) { CURLcode result = CURLE_OK; @@ -108,28 +106,27 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, struct Curl_chunker *ch = &conn->chunk; struct SingleRequest *k = &data->req; size_t piece; - curl_off_t length = (curl_off_t)datalen; - *wrote = 0; /* nothing's written yet */ + *pconsumed = 0; /* nothing's written yet */ /* the original data is written to the client, but we go on with the chunk read process, to properly calculate the content length */ if(data->set.http_te_skip && !k->ignorebody) { - result = Curl_client_write(data, CLIENTWRITE_BODY, datap, datalen); + result = Curl_client_write(data, CLIENTWRITE_BODY, buf, blen); if(result) { *extrap = result; return CHUNKE_PASSTHRU_ERROR; } } - while(length) { + while(blen) { switch(ch->state) { case CHUNK_HEX: - if(ISXDIGIT(*datap)) { + if(ISXDIGIT(*buf)) { if(ch->hexindex < CHUNK_MAXNUM_LEN) { - ch->hexbuffer[ch->hexindex] = *datap; - datap++; - length--; + ch->hexbuffer[ch->hexindex] = *buf; + buf++; + blen--; ch->hexindex++; } else { @@ -143,7 +140,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, a hexadecimal digit. */ return CHUNKE_ILLEGAL_HEX; - /* length and datap are unmodified */ + /* blen and buf are unmodified */ ch->hexbuffer[ch->hexindex] = 0; if(curlx_strtoofft(ch->hexbuffer, &endptr, 16, &ch->datasize)) @@ -154,7 +151,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, case CHUNK_LF: /* waiting for the LF after a chunk size */ - if(*datap == 0x0a) { + if(*buf == 0x0a) { /* we're now expecting data to come, unless size was zero! */ if(0 == ch->datasize) { ch->state = CHUNK_TRAILER; /* now check for trailers */ @@ -163,19 +160,21 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, ch->state = CHUNK_DATA; } - datap++; - length--; + buf++; + blen--; break; case CHUNK_DATA: - /* We expect 'datasize' of data. We have 'length' right now, it can be + /* We expect 'datasize' of data. We have 'blen' right now, it can be more or less than 'datasize'. Get the smallest piece. */ - piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize); + piece = blen; + if(ch->datasize < (curl_off_t)blen) + piece = curlx_sotouz(ch->datasize); /* Write the data portion available */ if(!data->set.http_te_skip && !k->ignorebody) { - result = Curl_client_write(data, CLIENTWRITE_BODY, datap, piece); + result = Curl_client_write(data, CLIENTWRITE_BODY, buf, piece); if(result) { *extrap = result; @@ -183,10 +182,10 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, } } - *wrote += piece; + *pconsumed += piece; ch->datasize -= piece; /* decrease amount left to expect */ - datap += piece; /* move read pointer forward */ - length -= piece; /* decrease space left in this round */ + buf += piece; /* move read pointer forward */ + blen -= piece; /* decrease space left in this round */ if(0 == ch->datasize) /* end of data this round, we now expect a trailing CRLF */ @@ -194,18 +193,18 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, break; case CHUNK_POSTLF: - if(*datap == 0x0a) { + if(*buf == 0x0a) { /* The last one before we go back to hex state and start all over. */ Curl_httpchunk_init(data); /* sets state back to CHUNK_HEX */ } - else if(*datap != 0x0d) + else if(*buf != 0x0d) return CHUNKE_BAD_CHUNK; - datap++; - length--; + buf++; + blen--; break; case CHUNK_TRAILER: - if((*datap == 0x0d) || (*datap == 0x0a)) { + if((*buf == 0x0d) || (*buf == 0x0a)) { char *tr = Curl_dyn_ptr(&conn->trailer); /* this is the end of a trailer, but if the trailer was zero bytes there was no trailer and we move on */ @@ -229,7 +228,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, } Curl_dyn_reset(&conn->trailer); ch->state = CHUNK_TRAILER_CR; - if(*datap == 0x0a) + if(*buf == 0x0a) /* already on the LF */ break; } @@ -240,19 +239,19 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, } } else { - result = Curl_dyn_addn(&conn->trailer, datap, 1); + result = Curl_dyn_addn(&conn->trailer, buf, 1); if(result) return CHUNKE_OUT_OF_MEMORY; } - datap++; - length--; + buf++; + blen--; break; case CHUNK_TRAILER_CR: - if(*datap == 0x0a) { + if(*buf == 0x0a) { ch->state = CHUNK_TRAILER_POSTCR; - datap++; - length--; + buf++; + blen--; } else return CHUNKE_BAD_CHUNK; @@ -261,27 +260,27 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, case CHUNK_TRAILER_POSTCR: /* We enter this state when a CR should arrive so we expect to have to first pass a CR before we wait for LF */ - if((*datap != 0x0d) && (*datap != 0x0a)) { + if((*buf != 0x0d) && (*buf != 0x0a)) { /* not a CR then it must be another header in the trailer */ ch->state = CHUNK_TRAILER; break; } - if(*datap == 0x0d) { + if(*buf == 0x0d) { /* skip if CR */ - datap++; - length--; + buf++; + blen--; } /* now wait for the final LF */ ch->state = CHUNK_STOP; break; case CHUNK_STOP: - if(*datap == 0x0a) { - length--; + if(*buf == 0x0a) { + blen--; /* Record the length of any data left in the end of the buffer even if there's no more chunks to read */ - ch->datasize = curlx_sotouz(length); + ch->datasize = blen; return CHUNKE_STOP; /* return stop */ } diff --git a/lib/http_chunks.h b/lib/http_chunks.h index ed5071316..0a36f379b 100644 --- a/lib/http_chunks.h +++ b/lib/http_chunks.h @@ -93,8 +93,8 @@ struct Curl_chunker { /* The following functions are defined in http_chunks.c */ void Curl_httpchunk_init(struct Curl_easy *data); -CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, char *datap, - ssize_t length, ssize_t *wrote, +CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, char *buf, + size_t blen, size_t *pconsumed, CURLcode *passthru); #endif /* HEADER_CURL_HTTP_CHUNKS_H */ diff --git a/lib/http_proxy.c b/lib/http_proxy.c index a1d6da954..8e1832581 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -299,7 +299,7 @@ struct Curl_cftype Curl_cft_http_proxy = { http_proxy_cf_connect, http_proxy_cf_close, Curl_cf_http_proxy_get_host, - Curl_cf_def_get_select_socks, + Curl_cf_def_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, Curl_cf_def_recv, diff --git a/lib/idn.c b/lib/idn.c index a024691d1..81a177f8c 100644 --- a/lib/idn.c +++ b/lib/idn.c @@ -36,7 +36,7 @@ #ifdef USE_LIBIDN2 #include -#if defined(WIN32) && defined(UNICODE) +#if defined(_WIN32) && defined(UNICODE) #define IDN2_LOOKUP(name, host, flags) \ idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags) #else diff --git a/lib/imap.c b/lib/imap.c index de64c2a7f..47cff4897 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -1194,8 +1194,6 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, if(result) return result; - data->req.bytecount += chunk; - infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU " bytes are left for transfer", chunk, size - chunk); @@ -1430,7 +1428,7 @@ static CURLcode imap_init(struct Curl_easy *data) CURLcode result = CURLE_OK; struct IMAP *imap; - imap = data->req.p.imap = calloc(sizeof(struct IMAP), 1); + imap = data->req.p.imap = calloc(1, sizeof(struct IMAP)); if(!imap) result = CURLE_OUT_OF_MEMORY; diff --git a/lib/ldap.c b/lib/ldap.c index 239d3fbf0..eb5fe795e 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -313,7 +313,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) int ldap_ssl = 0; char *val_b64 = NULL; size_t val_b64_sz = 0; - curl_off_t dlsize = 0; #ifdef LDAP_OPT_NETWORK_TIMEOUT struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */ #endif @@ -327,7 +326,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) *done = TRUE; /* unconditionally */ infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d", - LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); + LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); infof(data, "LDAP local: %s", data->state.url); #ifdef HAVE_LDAP_URL_PARSE @@ -345,7 +344,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) if(conn->given->flags & PROTOPT_SSL) ldap_ssl = 1; infof(data, "LDAP local: trying to establish %s connection", - ldap_ssl ? "encrypted" : "cleartext"); + ldap_ssl ? "encrypted" : "cleartext"); #if defined(USE_WIN32_LDAP) host = curlx_convert_UTF8_to_tchar(conn->host.name); @@ -535,6 +534,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } + Curl_pgrsSetDownloadCounter(data, 0); rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg); @@ -596,8 +596,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } - dlsize += name_len + 5; - FREE_ON_WINLDAP(name); ldap_memfree(dn); } @@ -659,8 +657,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } - dlsize += attr_len + 3; - if((attr_len > 7) && (strcmp(";binary", attr + (attr_len - 7)) == 0)) { /* Binary attribute, encode to base64. */ @@ -689,8 +685,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } - - dlsize += val_b64_sz; } } else { @@ -705,8 +699,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } - - dlsize += vals[i]->bv_len; } result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); @@ -719,8 +711,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } - - dlsize++; } /* Free memory used to store values */ @@ -734,10 +724,6 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); if(result) goto quit; - dlsize++; - result = Curl_pgrsSetDownloadCounter(data, dlsize); - if(result) - goto quit; } if(ber) diff --git a/lib/md4.c b/lib/md4.c index 30ab62e60..486e5fa6a 100644 --- a/lib/md4.c +++ b/lib/md4.c @@ -32,9 +32,8 @@ #include "warnless.h" #ifdef USE_OPENSSL -#include -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) && \ - !defined(USE_AMISSL) +#include +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) && !defined(USE_AMISSL) /* OpenSSL 3.0.0 marks the MD4 functions as deprecated */ #define OPENSSL_NO_MD4 #endif diff --git a/lib/memdebug.c b/lib/memdebug.c index d6952a07a..f6ced85cd 100644 --- a/lib/memdebug.c +++ b/lib/memdebug.c @@ -208,7 +208,7 @@ ALLOC_FUNC char *curl_dbg_strdup(const char *str, return mem; } -#if defined(WIN32) && defined(UNICODE) +#if defined(_WIN32) && defined(UNICODE) ALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) { diff --git a/lib/memdebug.h b/lib/memdebug.h index c9eb5dc37..78a012580 100644 --- a/lib/memdebug.h +++ b/lib/memdebug.h @@ -64,7 +64,7 @@ CURL_EXTERN ALLOC_SIZE(2) void *curl_dbg_realloc(void *ptr, CURL_EXTERN void curl_dbg_free(void *ptr, 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) +#if defined(_WIN32) && defined(UNICODE) CURL_EXTERN ALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source); @@ -121,7 +121,7 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); #define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__) #define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) -#ifdef WIN32 +#ifdef _WIN32 # ifdef UNICODE # undef wcsdup # define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) diff --git a/lib/mime.c b/lib/mime.c index 3b27e59e1..bb66130ad 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -48,7 +48,7 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef WIN32 +#ifdef _WIN32 # ifndef R_OK # define R_OK 4 # endif @@ -311,8 +311,7 @@ static char *escape_string(struct Curl_easy *data, table = formtable; /* data can be NULL when this function is called indirectly from curl_formget(). */ - if(strategy == MIMESTRATEGY_MAIL || - (data && (data->set.mime_options & CURLMIMEOPT_FORMESCAPE))) + if(strategy == MIMESTRATEGY_MAIL || (data && (data->set.mime_formescape))) table = mimetable; Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH); diff --git a/lib/mprintf.c b/lib/mprintf.c index af5d753d6..6b5df5bdd 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -66,9 +66,7 @@ * Non-ANSI integer extensions */ -#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \ - (defined(__POCC__) && defined(_MSC_VER)) || \ - (defined(_WIN32_WCE)) || \ +#if (defined(_WIN32_WCE)) || \ (defined(__MINGW32__)) || \ (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)) # define MP_HAVE_INT_EXTENSIONS @@ -1071,9 +1069,6 @@ static int alloc_addbyter(int output, FILE *data) return outc; /* fputc() returns like this on success */ } -extern int Curl_dyn_vprintf(struct dynbuf *dyn, - const char *format, va_list ap_save); - /* appends the formatted string, returns 0 on success, 1 on error */ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save) { diff --git a/lib/mqtt.c b/lib/mqtt.c index 54f88822c..366235c55 100644 --- a/lib/mqtt.c +++ b/lib/mqtt.c @@ -616,9 +616,6 @@ static void mqstate(struct Curl_easy *data, } -/* for the publish packet */ -#define MQTT_HEADER_LEN 5 /* max 5 bytes */ - static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) { CURLcode result = CURLE_OK; @@ -677,7 +674,6 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) /* FALLTHROUGH */ case MQTT_PUB_REMAIN: { /* read rest of packet, but no more. Cap to buffer size */ - struct SingleRequest *k = &data->req; size_t rest = mq->npacket; if(rest > (size_t)data->set.buffer_size) rest = (size_t)data->set.buffer_size; @@ -693,13 +689,8 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) result = CURLE_PARTIAL_FILE; goto end; } - Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread); mq->npacket -= nread; - k->bytecount += nread; - result = Curl_pgrsSetDownloadCounter(data, k->bytecount); - if(result) - goto end; /* if QoS is set, message contains packet id */ diff --git a/lib/multi.c b/lib/multi.c index ff753ac8c..5456113be 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -55,22 +55,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef __APPLE__ - -#define wakeup_write write -#define wakeup_read read -#define wakeup_close close -#define wakeup_create pipe - -#else /* __APPLE__ */ - -#define wakeup_write swrite -#define wakeup_read sread -#define wakeup_close sclose -#define wakeup_create(p) Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, p) - -#endif /* __APPLE__ */ - /* CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every @@ -231,10 +215,6 @@ struct Curl_sh_entry { unsigned int readers; /* this many transfers want to read */ unsigned int writers; /* this many transfers want to write */ }; -/* bits for 'action' having no bits means this socket is not expecting any - action */ -#define SH_READ 1 -#define SH_WRITE 2 /* look up a given socket in the socket hash, skip invalid sockets */ static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh, @@ -416,9 +396,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ Curl_llist_init(&multi->msgsent, NULL); multi->multiplexing = TRUE; - - /* -1 means it not set by user, use the default value */ - multi->maxconnects = -1; multi->max_concurrent_streams = 100; #ifdef USE_WINSOCK @@ -1040,49 +1017,61 @@ static int protocol_getsock(struct Curl_easy *data, { if(conn->handler->proto_getsock) return conn->handler->proto_getsock(data, conn, socks); - return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks); + return GETSOCK_BLANK; } -/* returns bitmapped flags for this handle and its sockets. The 'socks[]' - array contains MAX_SOCKSPEREASYHANDLE entries. */ -static int multi_getsock(struct Curl_easy *data, - curl_socket_t *socks) +/* Initializes `poll_set` with the current socket poll actions needed + * for transfer `data`. */ +static void multi_getsock(struct Curl_easy *data, + struct easy_pollset *ps) { - struct connectdata *conn = data->conn; /* The no connection case can happen when this is called from curl_multi_remove_handle() => singlesocket() => multi_getsock(). */ - if(!conn) - return 0; + Curl_pollset_reset(data, ps); + if(!data->conn) + return; switch(data->mstate) { default: - return 0; + break; case MSTATE_RESOLVING: - return Curl_resolv_getsock(data, socks); + Curl_pollset_add_socks2(data, ps, Curl_resolv_getsock); + /* connection filters are not involved in this phase */ + return; case MSTATE_PROTOCONNECTING: case MSTATE_PROTOCONNECT: - return protocol_getsock(data, conn, socks); + Curl_pollset_add_socks(data, ps, protocol_getsock); + break; case MSTATE_DO: case MSTATE_DOING: - return doing_getsock(data, conn, socks); + Curl_pollset_add_socks(data, ps, doing_getsock); + break; case MSTATE_TUNNELING: case MSTATE_CONNECTING: - return Curl_conn_get_select_socks(data, FIRSTSOCKET, socks); + break; case MSTATE_DOING_MORE: - return domore_getsock(data, conn, socks); + Curl_pollset_add_socks(data, ps, domore_getsock); + break; case MSTATE_DID: /* since is set after DO is completed, we switch to waiting for the same as the PERFORMING state */ case MSTATE_PERFORMING: - return Curl_single_getsock(data, conn, socks); + Curl_pollset_add_socks(data, ps, Curl_single_getsock); + break; + + case MSTATE_RATELIMITING: + /* nothing to wait for */ + return; } + /* Let connection filters add/remove as needed */ + Curl_conn_adjust_pollset(data, ps); } CURLMcode curl_multi_fdset(struct Curl_multi *multi, @@ -1094,8 +1083,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, and then we must make sure that is done. */ struct Curl_easy *data; int this_max_fd = -1; - curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; - int i; + struct easy_pollset ps; + unsigned int i; (void)exc_fd_set; /* not used */ if(!GOOD_MULTI_HANDLE(multi)) @@ -1104,29 +1093,20 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; + memset(&ps, 0, sizeof(ps)); for(data = multi->easyp; data; data = data->next) { - int bitmap; -#ifdef __clang_analyzer_ - /* to prevent "The left operand of '>=' is a garbage value" warnings */ - memset(sockbunch, 0, sizeof(sockbunch)); -#endif - bitmap = multi_getsock(data, sockbunch); - - for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { - if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) { - if(!FDSET_SOCK(sockbunch[i])) - /* pretend it doesn't exist */ - continue; - if(bitmap & GETSOCK_READSOCK(i)) - FD_SET(sockbunch[i], read_fd_set); - if(bitmap & GETSOCK_WRITESOCK(i)) - FD_SET(sockbunch[i], write_fd_set); - if((int)sockbunch[i] > this_max_fd) - this_max_fd = (int)sockbunch[i]; - } - else { - break; - } + multi_getsock(data, &ps); + + for(i = 0; i < ps.num; i++) { + if(!FDSET_SOCK(ps.sockets[i])) + /* pretend it doesn't exist */ + continue; + if(ps.actions[i] & CURL_POLL_IN) + FD_SET(ps.sockets[i], read_fd_set); + if(ps.actions[i] & CURL_POLL_OUT) + FD_SET(ps.sockets[i], write_fd_set); + if((int)ps.sockets[i] > this_max_fd) + this_max_fd = (int)ps.sockets[i]; } } @@ -1162,9 +1142,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi, bool use_wakeup) { struct Curl_easy *data; - curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; - int bitmap; - unsigned int i; + struct easy_pollset ps; + size_t i; unsigned int nfds = 0; unsigned int curlfds; long timeout_internal; @@ -1190,17 +1169,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi, return CURLM_BAD_FUNCTION_ARGUMENT; /* Count up how many fds we have from the multi handle */ + memset(&ps, 0, sizeof(ps)); for(data = multi->easyp; data; data = data->next) { - bitmap = multi_getsock(data, sockbunch); - - for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { - if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) { - ++nfds; - } - else { - break; - } - } + multi_getsock(data, &ps); + nfds += ps.num; } /* If the internally desired timeout is actually shorter than requested from @@ -1241,40 +1213,35 @@ static CURLMcode multi_wait(struct Curl_multi *multi, if(curlfds) { /* Add the curl handles to our pollfds first */ for(data = multi->easyp; data; data = data->next) { - bitmap = multi_getsock(data, sockbunch); + multi_getsock(data, &ps); - for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { - if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) { - struct pollfd *ufd = &ufds[nfds++]; -#ifdef USE_WINSOCK - long mask = 0; -#endif - ufd->fd = sockbunch[i]; - ufd->events = 0; - if(bitmap & GETSOCK_READSOCK(i)) { + for(i = 0; i < ps.num; i++) { + struct pollfd *ufd = &ufds[nfds++]; #ifdef USE_WINSOCK - mask |= FD_READ|FD_ACCEPT|FD_CLOSE; + long mask = 0; #endif - ufd->events |= POLLIN; - } - if(bitmap & GETSOCK_WRITESOCK(i)) { + ufd->fd = ps.sockets[i]; + ufd->events = 0; + if(ps.actions[i] & CURL_POLL_IN) { #ifdef USE_WINSOCK - mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; - reset_socket_fdwrite(sockbunch[i]); + mask |= FD_READ|FD_ACCEPT|FD_CLOSE; #endif - ufd->events |= POLLOUT; - } + ufd->events |= POLLIN; + } + if(ps.actions[i] & CURL_POLL_OUT) { #ifdef USE_WINSOCK - if(WSAEventSelect(sockbunch[i], multi->wsa_event, mask) != 0) { - if(ufds_malloc) - free(ufds); - return CURLM_INTERNAL_ERROR; - } + mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; + reset_socket_fdwrite(ps.sockets[i]); #endif + ufd->events |= POLLOUT; } - else { - break; +#ifdef USE_WINSOCK + if(WSAEventSelect(ps.sockets[i], multi->wsa_event, mask) != 0) { + if(ufds_malloc) + free(ufds); + return CURLM_INTERNAL_ERROR; } +#endif } } } @@ -1386,21 +1353,16 @@ static CURLMcode multi_wait(struct Curl_multi *multi, if(curlfds) { for(data = multi->easyp; data; data = data->next) { - bitmap = multi_getsock(data, sockbunch); - - for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { - if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) { - wsa_events.lNetworkEvents = 0; - if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) { - if(ret && !pollrc && wsa_events.lNetworkEvents) - retcode++; - } - WSAEventSelect(sockbunch[i], multi->wsa_event, 0); - } - else { - /* break on entry not checked for being readable or writable */ - break; + multi_getsock(data, &ps); + + for(i = 0; i < ps.num; i++) { + wsa_events.lNetworkEvents = 0; + if(WSAEnumNetworkEvents(ps.sockets[i], NULL, + &wsa_events) == 0) { + if(ret && !pollrc && wsa_events.lNetworkEvents) + retcode++; } + WSAEventSelect(ps.sockets[i], multi->wsa_event, 0); } } } @@ -2021,8 +1983,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(dns) { #ifdef CURLRES_ASYNCH - data->state.async.dns = dns; - data->state.async.done = TRUE; + conn->resolve_async.dns = dns; + conn->resolve_async.done = TRUE; #endif result = CURLE_OK; infof(data, "Hostname '%s' was found in DNS cache", hostname); @@ -2895,53 +2857,36 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) static CURLMcode singlesocket(struct Curl_multi *multi, struct Curl_easy *data) { - curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; - int i; + struct easy_pollset cur_poll; + unsigned int i; struct Curl_sh_entry *entry; curl_socket_t s; - int num; - unsigned int curraction; - unsigned char actions[MAX_SOCKSPEREASYHANDLE]; int rc; - for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) - socks[i] = CURL_SOCKET_BAD; - /* Fill in the 'current' struct with the state as it is now: what sockets to supervise and for what actions */ - curraction = multi_getsock(data, socks); + multi_getsock(data, &cur_poll); /* We have 0 .. N sockets already and we get to know about the 0 .. M sockets we should have from now on. Detect the differences, remove no longer supervised ones and add new ones */ /* walk over the sockets we got right now */ - for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) && - (curraction & GETSOCK_MASK_RW(i)); - i++) { - unsigned char action = CURL_POLL_NONE; - unsigned char prevaction = 0; + for(i = 0; i < cur_poll.num; i++) { + unsigned char cur_action = cur_poll.actions[i]; + unsigned char last_action = 0; int comboaction; - bool sincebefore = FALSE; - s = socks[i]; + s = cur_poll.sockets[i]; /* get it from the hash */ entry = sh_getentry(&multi->sockhash, s); - - if(curraction & GETSOCK_READSOCK(i)) - action |= CURL_POLL_IN; - if(curraction & GETSOCK_WRITESOCK(i)) - action |= CURL_POLL_OUT; - - actions[i] = action; if(entry) { /* check if new for this transfer */ - int j; - for(j = 0; j< data->numsocks; j++) { - if(s == data->sockets[j]) { - prevaction = data->actions[j]; - sincebefore = TRUE; + unsigned int j; + for(j = 0; j< data->last_poll.num; j++) { + if(s == data->last_poll.sockets[j]) { + last_action = data->last_poll.actions[j]; break; } } @@ -2953,23 +2898,23 @@ static CURLMcode singlesocket(struct Curl_multi *multi, /* fatal */ return CURLM_OUT_OF_MEMORY; } - if(sincebefore && (prevaction != action)) { + if(last_action && (last_action != cur_action)) { /* Socket was used already, but different action now */ - if(prevaction & CURL_POLL_IN) + if(last_action & CURL_POLL_IN) entry->readers--; - if(prevaction & CURL_POLL_OUT) + if(last_action & CURL_POLL_OUT) entry->writers--; - if(action & CURL_POLL_IN) + if(cur_action & CURL_POLL_IN) entry->readers++; - if(action & CURL_POLL_OUT) + if(cur_action & CURL_POLL_OUT) entry->writers++; } - else if(!sincebefore) { - /* a new user */ + else if(!last_action) { + /* a new transfer using this socket */ entry->users++; - if(action & CURL_POLL_IN) + if(cur_action & CURL_POLL_IN) entry->readers++; - if(action & CURL_POLL_OUT) + if(cur_action & CURL_POLL_OUT) entry->writers++; /* add 'data' to the transfer hash on this socket! */ @@ -2980,11 +2925,11 @@ static CURLMcode singlesocket(struct Curl_multi *multi, } } - comboaction = (entry->writers? CURL_POLL_OUT : 0) | + comboaction = (entry->writers ? CURL_POLL_OUT : 0) | (entry->readers ? CURL_POLL_IN : 0); /* socket existed before and has the same action set as before */ - if(sincebefore && ((int)entry->action == comboaction)) + if(last_action && ((int)entry->action == comboaction)) /* same, continue */ continue; @@ -2992,6 +2937,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, set_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, comboaction, multi->socket_userp, entry->socketp); + set_in_callback(multi, FALSE); if(rc == -1) { multi->dead = TRUE; @@ -3002,16 +2948,15 @@ static CURLMcode singlesocket(struct Curl_multi *multi, entry->action = comboaction; /* store the current action state */ } - num = i; /* number of sockets */ - - /* when we've walked over all the sockets we should have right now, we must - make sure to detect sockets that are removed */ - for(i = 0; i< data->numsocks; i++) { - int j; + /* Check for last_poll.sockets that no longer appear in cur_poll.sockets. + * Need to remove the easy handle from the multi->sockhash->transfers and + * remove multi->sockhash entry when this was the last transfer */ + for(i = 0; i< data->last_poll.num; i++) { + unsigned int j; bool stillused = FALSE; - s = data->sockets[i]; - for(j = 0; j < num; j++) { - if(s == socks[j]) { + s = data->last_poll.sockets[i]; + for(j = 0; j < cur_poll.num; j++) { + if(s == cur_poll.sockets[j]) { /* this is still supervised */ stillused = TRUE; break; @@ -3024,7 +2969,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, /* if this is NULL here, the socket has been closed and notified so already by Curl_multi_closed() */ if(entry) { - unsigned char oldactions = data->actions[i]; + unsigned char oldactions = data->last_poll.actions[i]; /* this socket has been removed. Decrease user count */ entry->users--; if(oldactions & CURL_POLL_OUT) @@ -3052,11 +2997,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi, } } } - } /* for loop over numsocks */ + } /* for loop over num */ - memcpy(data->sockets, socks, num*sizeof(curl_socket_t)); - memcpy(data->actions, actions, num*sizeof(char)); - data->numsocks = num; + /* Remember for next time */ + memcpy(&data->last_poll, &cur_poll, sizeof(data->last_poll)); return CURLM_OK; } @@ -3296,6 +3240,7 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, { CURLMcode res = CURLM_OK; va_list param; + unsigned long uarg; if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; @@ -3328,7 +3273,9 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, multi->timer_userp = va_arg(param, void *); break; case CURLMOPT_MAXCONNECTS: - multi->maxconnects = va_arg(param, long); + uarg = va_arg(param, unsigned long); + if(uarg <= UINT_MAX) + multi->maxconnects = (unsigned int)uarg; break; case CURLMOPT_MAX_HOST_CONNECTIONS: multi->max_host_connections = va_arg(param, long); @@ -3350,9 +3297,9 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, case CURLMOPT_MAX_CONCURRENT_STREAMS: { long streams = va_arg(param, long); - if(streams < 1) + if((streams < 1) || (streams > INT_MAX)) streams = 100; - multi->max_concurrent_streams = curlx_sltoui(streams); + multi->max_concurrent_streams = (unsigned int)streams; } break; default: @@ -3782,11 +3729,11 @@ struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi) struct Curl_easy **a = malloc(sizeof(struct Curl_easy *) * (multi->num_easy + 1)); if(a) { - int i = 0; + unsigned int i = 0; struct Curl_easy *e = multi->easyp; while(e) { DEBUGASSERT(i < multi->num_easy); - if(!e->internal) + if(!e->state.internal) a[i++] = e; e = e->next; } diff --git a/lib/multihandle.h b/lib/multihandle.h index 5b16bb605..e03e382e2 100644 --- a/lib/multihandle.h +++ b/lib/multihandle.h @@ -93,9 +93,9 @@ struct Curl_multi { struct Curl_easy *easyp; struct Curl_easy *easylp; /* last node */ - int num_easy; /* amount of entries in the linked list above. */ - int num_alive; /* amount of easy handles that are added but have not yet - reached COMPLETE state */ + unsigned int num_easy; /* amount of entries in the linked list above. */ + unsigned int num_alive; /* amount of easy handles that are added but have + not yet reached COMPLETE state */ struct Curl_llist msglist; /* a list of messages from completed transfers */ @@ -136,9 +136,6 @@ struct Curl_multi { /* Shared connection cache (bundles)*/ struct conncache conn_cache; - long maxconnects; /* if >0, a fixed limit of the maximum number of entries - we're allowed to grow the connection cache to */ - long max_host_connections; /* if >0, a fixed limit of the maximum number of connections per host */ @@ -150,8 +147,6 @@ struct Curl_multi { void *timer_userp; struct curltime timer_lastcall; /* the fixed time for the timeout for the previous callback */ - unsigned int max_concurrent_streams; - #ifdef USE_WINSOCK WSAEVENT wsa_event; /* winsock event used for waits */ #else @@ -160,6 +155,10 @@ struct Curl_multi { 0 is used for read, 1 is used for write */ #endif #endif + unsigned int max_concurrent_streams; + unsigned int maxconnects; /* if >0, a fixed limit of the maximum number of + entries we're allowed to grow the connection + cache to */ #define IPV6_UNKNOWN 0 #define IPV6_DEAD 1 #define IPV6_WORKS 2 diff --git a/lib/netrc.c b/lib/netrc.c index e6a09b187..038c6dca6 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -327,7 +327,7 @@ int Curl_parsenetrc(const char *host, char **loginp, char **passwordp, } retcode = parsenetrc(host, loginp, passwordp, filealloc); free(filealloc); -#ifdef WIN32 +#ifdef _WIN32 if(retcode == NETRC_FILE_MISSING) { /* fallback to the old-style "_netrc" file */ filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR); diff --git a/lib/openldap.c b/lib/openldap.c index 3aff3060a..131f47414 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -319,31 +319,12 @@ static CURLcode oldap_setup_connection(struct Curl_easy *data, { CURLcode result; LDAPURLDesc *lud; - struct ldapconninfo *li; + (void)conn; /* Early URL syntax check. */ result = oldap_url_parse(data, &lud); ldap_free_urldesc(lud); - if(!result) { - li = calloc(1, sizeof(struct ldapconninfo)); - if(!li) - result = CURLE_OUT_OF_MEMORY; - else { - li->proto = ldap_pvt_url_scheme2proto(data->state.up.scheme); - conn->proto.ldapc = li; - connkeep(conn, "OpenLDAP default"); - - /* Initialize the SASL storage */ - Curl_sasl_init(&li->sasl, data, &saslldap); - - /* Clear the TLS upgraded flag */ - conn->bits.tls_upgraded = FALSE; - - result = oldap_parse_login_options(conn); - } - } - return result; } @@ -537,7 +518,7 @@ static CURLcode oldap_perform_starttls(struct Curl_easy *data) static CURLcode oldap_connect(struct Curl_easy *data, bool *done) { struct connectdata *conn = data->conn; - struct ldapconninfo *li = conn->proto.ldapc; + struct ldapconninfo *li; static const int version = LDAP_VERSION3; int rc; char *hosturl; @@ -547,6 +528,26 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done) (void)done; + DEBUGASSERT(!conn->proto.ldapc); + li = calloc(1, sizeof(struct ldapconninfo)); + if(!li) + return CURLE_OUT_OF_MEMORY; + else { + CURLcode result; + li->proto = ldap_pvt_url_scheme2proto(data->state.up.scheme); + conn->proto.ldapc = li; + + /* Initialize the SASL storage */ + Curl_sasl_init(&li->sasl, data, &saslldap); + + /* Clear the TLS upgraded flag */ + conn->bits.tls_upgraded = FALSE; + + result = oldap_parse_login_options(conn); + if(result) + return result; + } + hosturl = aprintf("ldap%s://%s:%d", conn->handler->flags & PROTOPT_SSL? "s": "", conn->host.name, conn->remote_port); @@ -886,6 +887,11 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done) result = oldap_url_parse(data, &lud); if(!result) { + Sockbuf *sb; + /* re-install the libcurl SSL handlers into the sockbuf. */ + ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); + ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data); + rc = ldap_search_ext(li->ld, lud->lud_dn, lud->lud_scope, lud->lud_filter, lud->lud_attrs, 0, NULL, NULL, NULL, 0, &msgid); @@ -947,18 +953,12 @@ static CURLcode client_write(struct Curl_easy *data, if(!len && plen && prefix[plen - 1] == ' ') plen--; result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) prefix, plen); - if(!result) - data->req.bytecount += plen; } if(!result && value) { result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) value, len); - if(!result) - data->req.bytecount += len; } if(!result && suffix) { result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) suffix, slen); - if(!result) - data->req.bytecount += slen; } return result; } diff --git a/lib/pop3.c b/lib/pop3.c index a9d5fdd69..3e0f20a69 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -1088,7 +1088,7 @@ static CURLcode pop3_init(struct Curl_easy *data) CURLcode result = CURLE_OK; struct POP3 *pop3; - pop3 = data->req.p.pop3 = calloc(sizeof(struct POP3), 1); + pop3 = data->req.p.pop3 = calloc(1, sizeof(struct POP3)); if(!pop3) result = CURLE_OUT_OF_MEMORY; diff --git a/lib/progress.c b/lib/progress.c index e783a9c86..e96cbf7af 100644 --- a/lib/progress.c +++ b/lib/progress.c @@ -304,7 +304,7 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, * 'actual' is the time in milliseconds it took to actually download the * last 'size' bytes. */ - actual = Curl_timediff(now, start); + actual = Curl_timediff_ceil(now, start); if(actual < minimum) { /* if it downloaded the data faster than the limit, make it wait the difference */ @@ -319,12 +319,6 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, */ CURLcode Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size) { - if(data->set.max_filesize && (size > data->set.max_filesize)) { - failf(data, "Exceeded the maximum allowed file size " - "(%" CURL_FORMAT_CURL_OFF_T ")", - data->set.max_filesize); - return CURLE_FILESIZE_EXCEEDED; - } data->progress.downloaded = size; return CURLE_OK; } diff --git a/lib/rand.c b/lib/rand.c index 6bd96136f..3383c490b 100644 --- a/lib/rand.c +++ b/lib/rand.c @@ -32,10 +32,6 @@ #ifdef HAVE_ARPA_INET_H #include #endif -#ifdef HAVE_ARC4RANDOM -/* Some platforms might have the prototype missing (ubuntu + libressl) */ -uint32_t arc4random(void); -#endif #include #include "urldata.h" @@ -50,7 +46,7 @@ uint32_t arc4random(void); #include "curl_memory.h" #include "memdebug.h" -#ifdef WIN32 +#ifdef _WIN32 #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 # define HAVE_WIN_BCRYPTGENRANDOM @@ -105,7 +101,6 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length) static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) { - unsigned int r; CURLcode result = CURLE_OK; static unsigned int randseed; static bool seeded = FALSE; @@ -138,7 +133,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) /* ---- non-cryptographic version following ---- */ -#ifdef WIN32 +#ifdef _WIN32 if(!seeded) { result = Curl_win32_random((unsigned char *)rnd, sizeof(*rnd)); if(result != CURLE_NOT_BUILT_IN) @@ -146,12 +141,14 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) } #endif -#ifdef HAVE_ARC4RANDOM - *rnd = (unsigned int)arc4random(); - return CURLE_OK; +#if defined(HAVE_ARC4RANDOM) && !defined(USE_OPENSSL) + if(!seeded) { + *rnd = (unsigned int)arc4random(); + return CURLE_OK; + } #endif -#if defined(RANDOM_FILE) && !defined(WIN32) +#if defined(RANDOM_FILE) && !defined(_WIN32) if(!seeded) { /* if there's a random file to read a seed from, use it */ int fd = open(RANDOM_FILE, O_RDONLY); @@ -175,9 +172,12 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) seeded = TRUE; } - /* Return an unsigned 32-bit pseudo-random number. */ - r = randseed = randseed * 1103515245 + 12345; - *rnd = (r << 16) | ((r >> 16) & 0xFFFF); + { + unsigned int r; + /* Return an unsigned 32-bit pseudo-random number. */ + r = randseed = randseed * 1103515245 + 12345; + *rnd = (r << 16) | ((r >> 16) & 0xFFFF); + } return CURLE_OK; } diff --git a/lib/rand.h b/lib/rand.h index 1d009f52c..bc05239e4 100644 --- a/lib/rand.h +++ b/lib/rand.h @@ -41,7 +41,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, CURLcode Curl_rand_alnum(struct Curl_easy *data, unsigned char *rnd, size_t num); -#ifdef WIN32 +#ifdef _WIN32 /* Random generator shared between the Schannel vtls and Curl_rand*() functions */ CURLcode Curl_win32_random(unsigned char *entropy, size_t length); diff --git a/lib/rename.c b/lib/rename.c index 97a66e947..4c8869806 100644 --- a/lib/rename.c +++ b/lib/rename.c @@ -40,7 +40,7 @@ /* return 0 on success, 1 on error */ int Curl_rename(const char *oldpath, const char *newpath) { -#ifdef WIN32 +#ifdef _WIN32 /* rename() on Windows doesn't overwrite, so we can't use it here. MoveFileEx() will overwrite and is usually atomic, however it fails when there are open handles to the file. */ diff --git a/lib/rtsp.c b/lib/rtsp.c index ccd7264b0..e673bb8dc 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -45,8 +45,8 @@ #include "curl_memory.h" #include "memdebug.h" -#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \ - ((int)((unsigned char)((p)[3])))) +#define RTP_PKT_LENGTH(p) ((((unsigned int)((unsigned char)((p)[2]))) << 8) | \ + ((unsigned int)((unsigned char)((p)[3])))) /* protocol-specific functions set up to be called by the main engine */ static CURLcode rtsp_do(struct Curl_easy *data, bool *done); @@ -59,14 +59,19 @@ static int rtsp_getsock_do(struct Curl_easy *data, /* * Parse and write out any available RTP data. - * - * nread: amount of data left after k->str. will be modified if RTP - * data is parsed and k->str is moved up - * readmore: whether or not the RTP parser needs more data right away + * @param data the transfer + * @param conn the connection + * @param buf data read from connection + * @param blen amount of data in buf + * @param consumed out, number of blen consumed + * @param readmore out, TRUE iff complete buf was consumed and more data + * is needed */ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, struct connectdata *conn, - ssize_t *nread, + const char *buf, + size_t blen, + size_t *pconsumed, bool *readmore); static CURLcode rtsp_setup_connection(struct Curl_easy *data, @@ -88,7 +93,7 @@ static int rtsp_getsock_do(struct Curl_easy *data, struct connectdata *conn, } static -CURLcode rtp_client_write(struct Curl_easy *data, char *ptr, size_t len); +CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, size_t len); static CURLcode rtsp_parse_transport(struct Curl_easy *data, char *transport); @@ -585,153 +590,249 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) return result; } - -static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, - struct connectdata *conn, - ssize_t *nread, - bool *readmore) { - struct SingleRequest *k = &data->req; +static CURLcode rtsp_filter_rtp(struct Curl_easy *data, + struct connectdata *conn, + const char *buf, + size_t blen, + bool in_body, + size_t *pconsumed) +{ struct rtsp_conn *rtspc = &(conn->proto.rtspc); - unsigned char *rtp_channel_mask = data->state.rtp_channel_mask; + CURLcode result = CURLE_OK; - char *rtp; /* moving pointer to rtp data */ - ssize_t rtp_dataleft; /* how much data left to parse in this round */ - CURLcode result; - bool interleaved = false; - size_t skip_size = 0; + *pconsumed = 0; + while(blen) { + switch(rtspc->state) { - if(Curl_dyn_len(&rtspc->buf)) { - /* There was some leftover data the last time. Append new buffers */ - if(Curl_dyn_addn(&rtspc->buf, k->str, *nread)) - return CURLE_OUT_OF_MEMORY; - rtp = Curl_dyn_ptr(&rtspc->buf); - rtp_dataleft = Curl_dyn_len(&rtspc->buf); - } - else { - /* Just parse the request buffer directly */ - rtp = k->str; - rtp_dataleft = *nread; - } - - while(rtp_dataleft > 0) { - if(rtp[0] == '$') { - if(rtp_dataleft > 4) { - unsigned char rtp_channel; - int rtp_length; - int idx; - int off; - - /* Parse the header */ - /* The channel identifier immediately follows and is 1 byte */ - rtp_channel = (unsigned char)rtp[1]; - idx = rtp_channel / 8; - off = rtp_channel % 8; - if(!(rtp_channel_mask[idx] & (1 << off))) { - /* invalid channel number, maybe not an RTP packet */ - rtp++; - rtp_dataleft--; - skip_size++; - continue; + case RTP_PARSE_SKIP: { + DEBUGASSERT(Curl_dyn_len(&rtspc->buf) == 0); + if(in_body && buf[0] != '$') { + /* in BODY and no valid start, do not consume and return */ + goto out; + } + while(blen && buf[0] != '$') { + if(!in_body && buf[0] == 'R' && + data->set.rtspreq != RTSPREQ_RECEIVE) { + if(strncmp(buf, "RTSP/", (blen < 5) ? blen : 5) == 0) { + /* This could be the next response, no consume and return */ + if(*pconsumed) { + DEBUGF(infof(data, "RTP rtsp_filter_rtp[SKIP] RTSP/ prefix, " + "skipping %zd bytes of junk", *pconsumed)); + } + rtspc->state = RTP_PARSE_SKIP; + rtspc->in_header = TRUE; + goto out; + } } - if(skip_size > 0) { - DEBUGF(infof(data, "Skip the malformed interleaved data %lu " - "bytes", skip_size)); + /* junk, consume without buffering */ + *pconsumed += 1; + ++buf; + --blen; + } + if(blen && buf[0] == '$') { + /* possible start of an RTP message, buffer */ + if(Curl_dyn_addn(&rtspc->buf, buf, 1)) { + result = CURLE_OUT_OF_MEMORY; + goto out; } - skip_size = 0; - rtspc->rtp_channel = rtp_channel; - - /* The length is two bytes */ - rtp_length = RTP_PKT_LENGTH(rtp); + *pconsumed += 1; + ++buf; + --blen; + rtspc->state = RTP_PARSE_CHANNEL; + } + break; + } - if(rtp_dataleft < rtp_length + 4) { - /* Need more - incomplete payload */ - *readmore = TRUE; - break; + case RTP_PARSE_CHANNEL: { + int idx = ((unsigned char)buf[0]) / 8; + int off = ((unsigned char)buf[0]) % 8; + DEBUGASSERT(Curl_dyn_len(&rtspc->buf) == 1); + if(!(data->state.rtp_channel_mask[idx] & (1 << off))) { + /* invalid channel number, junk or BODY data */ + rtspc->state = RTP_PARSE_SKIP; + if(in_body) { + /* we do not consume this byte, it is BODY data */ + DEBUGF(infof(data, "RTSP: invalid RTP channel %d in BODY, " + "treating as BODY data", idx)); + if(*pconsumed == 0) { + /* We did not consume the initial '$' in our buffer, but had + * it from an earlier call. We cannot un-consume it and have + * to write it directly as BODY data */ + result = Curl_client_write(data, CLIENTWRITE_BODY, + Curl_dyn_ptr(&rtspc->buf), 1); + Curl_dyn_free(&rtspc->buf); + if(result) + goto out; + } + else { + /* un-consume the '$' and leave */ + Curl_dyn_free(&rtspc->buf); + *pconsumed -= 1; + --buf; + ++blen; + goto out; + } } - interleaved = true; - /* We have the full RTP interleaved packet - * Write out the header including the leading '$' */ - DEBUGF(infof(data, "RTP write channel %d rtp_length %d", - rtspc->rtp_channel, rtp_length)); - result = rtp_client_write(data, &rtp[0], rtp_length + 4); - if(result) { - *readmore = FALSE; - return result; + else { + /* not BODY, forget the junk '$'. Do not consume this byte, + * it might be a start */ + infof(data, "RTSP: invalid RTP channel %d, skipping", idx); + Curl_dyn_free(&rtspc->buf); } + break; + } + /* a valid channel, so we expect this to be a real RTP message */ + rtspc->rtp_channel = (unsigned char)buf[0]; + if(Curl_dyn_addn(&rtspc->buf, buf, 1)) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + *pconsumed += 1; + ++buf; + --blen; + rtspc->state = RTP_PARSE_LEN; + break; + } - /* Move forward in the buffer */ - rtp_dataleft -= rtp_length + 4; - rtp += rtp_length + 4; + case RTP_PARSE_LEN: { + size_t rtp_len = Curl_dyn_len(&rtspc->buf); + const char *rtp_buf; + DEBUGASSERT(rtp_len >= 2 && rtp_len < 4); + if(Curl_dyn_addn(&rtspc->buf, buf, 1)) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + *pconsumed += 1; + ++buf; + --blen; + if(rtp_len == 2) + break; + rtp_buf = Curl_dyn_ptr(&rtspc->buf); + rtspc->rtp_len = RTP_PKT_LENGTH(rtp_buf) + 4; + rtspc->state = RTP_PARSE_DATA; + break; + } - if(data->set.rtspreq == RTSPREQ_RECEIVE) { - /* If we are in a passive receive, give control back - * to the app as often as we can. - */ - k->keepon &= ~KEEP_RECV; + case RTP_PARSE_DATA: { + size_t rtp_len = Curl_dyn_len(&rtspc->buf); + size_t needed; + DEBUGASSERT(rtp_len < rtspc->rtp_len); + needed = rtspc->rtp_len - rtp_len; + if(needed <= blen) { + if(Curl_dyn_addn(&rtspc->buf, buf, needed)) { + result = CURLE_OUT_OF_MEMORY; + goto out; } + *pconsumed += needed; + buf += needed; + blen -= needed; + /* complete RTP message in buffer */ + DEBUGF(infof(data, "RTP write channel %d rtp_len %zu", + rtspc->rtp_channel, rtspc->rtp_len)); + result = rtp_client_write(data, Curl_dyn_ptr(&rtspc->buf), + rtspc->rtp_len); + Curl_dyn_free(&rtspc->buf); + rtspc->state = RTP_PARSE_SKIP; + if(result) + goto out; } else { - /* Need more - incomplete header */ - *readmore = TRUE; - break; - } - } - else { - /* If the following data begins with 'RTSP/', which might be an RTSP - message, we should stop skipping the data. */ - /* If `k-> headerline> 0 && !interleaved` is true, we are maybe in the - middle of an RTSP message. It is difficult to determine this, so we - stop skipping. */ - size_t prefix_len = (rtp_dataleft < 5) ? rtp_dataleft : 5; - if((k->headerline > 0 && !interleaved) || - strncmp(rtp, "RTSP/", prefix_len) == 0) { - if(skip_size > 0) { - DEBUGF(infof(data, "Skip the malformed interleaved data %lu " - "bytes", skip_size)); + if(Curl_dyn_addn(&rtspc->buf, buf, blen)) { + result = CURLE_OUT_OF_MEMORY; + goto out; } - break; /* maybe is an RTSP message */ + *pconsumed += blen; + buf += blen; + blen = 0; } - /* Skip incorrect data util the next RTP packet or RTSP message */ - do { - rtp++; - rtp_dataleft--; - skip_size++; - } while(rtp_dataleft > 0 && rtp[0] != '$' && rtp[0] != 'R'); + break; + } + + default: + DEBUGASSERT(0); + return CURLE_RECV_ERROR; } } +out: + return result; +} + +static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, + struct connectdata *conn, + const char *buf, + size_t blen, + size_t *pconsumed, + bool *readmore) +{ + struct rtsp_conn *rtspc = &(conn->proto.rtspc); + CURLcode result = CURLE_OK; + size_t consumed = 0; + bool in_body; - if(rtp_dataleft && rtp[0] == '$') { - DEBUGF(infof(data, "RTP Rewinding %zd %s", rtp_dataleft, - *readmore ? "(READMORE)" : "")); + if(!data->req.header) + rtspc->in_header = FALSE; + in_body = (data->req.headerline && !rtspc->in_header) && + (data->req.size >= 0) && + (data->req.bytecount < data->req.size); - /* Store the incomplete RTP packet for a "rewind" */ - if(!Curl_dyn_len(&rtspc->buf)) { - /* nothing was stored, add this data */ - if(Curl_dyn_addn(&rtspc->buf, rtp, rtp_dataleft)) - return CURLE_OUT_OF_MEMORY; - } - else { - /* keep the remainder */ - Curl_dyn_tail(&rtspc->buf, rtp_dataleft); - } + *readmore = FALSE; + *pconsumed = 0; + if(!blen) { + goto out; + } - /* As far as the transfer is concerned, this data is consumed */ - *nread = 0; - return CURLE_OK; + /* If header parsing is not onging, extract RTP messages */ + if(!rtspc->in_header) { + result = rtsp_filter_rtp(data, conn, buf, blen, in_body, &consumed); + if(result) + goto out; + *pconsumed += consumed; + buf += consumed; + blen -= consumed; } - /* Fix up k->str to point just after the last RTP packet */ - k->str += *nread - rtp_dataleft; - *nread = rtp_dataleft; + /* we want to parse headers, do so */ + if(data->req.header && blen) { + rtspc->in_header = TRUE; + result = Curl_http_readwrite_headers(data, conn, buf, blen, + &consumed); + if(result) + goto out; + + *pconsumed += consumed; + buf += consumed; + blen -= consumed; + + if(!data->req.header) + rtspc->in_header = FALSE; + + if(!rtspc->in_header) { + /* If header parsing is done and data left, extract RTP messages */ + in_body = (data->req.headerline && !rtspc->in_header) && + (data->req.size >= 0) && + (data->req.bytecount < data->req.size); + result = rtsp_filter_rtp(data, conn, buf, blen, in_body, &consumed); + if(result) + goto out; + *pconsumed += consumed; + } + } - /* If we get here, we have finished with the leftover/merge buffer */ - Curl_dyn_free(&rtspc->buf); + if(rtspc->state != RTP_PARSE_SKIP) + *readmore = TRUE; - return CURLE_OK; +out: + if(!*readmore && data->set.rtspreq == RTSPREQ_RECEIVE) { + /* In special mode RECEIVE, we just process one chunk of network + * data, so we stop the transfer here, if we have no incomplete + * RTP message pending. */ + data->req.keepon &= ~KEEP_RECV; + } + return result; } static -CURLcode rtp_client_write(struct Curl_easy *data, char *ptr, size_t len) +CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, size_t len) { size_t wrote; curl_write_callback writeit; @@ -756,7 +857,7 @@ CURLcode rtp_client_write(struct Curl_easy *data, char *ptr, size_t len) } Curl_set_in_callback(data, true); - wrote = writeit(ptr, 1, len, user_ptr); + wrote = writeit((char *)ptr, 1, len, user_ptr); Curl_set_in_callback(data, false); if(CURL_WRITEFUNC_PAUSE == wrote) { diff --git a/lib/rtsp.h b/lib/rtsp.h index 111bac2a6..237b80f80 100644 --- a/lib/rtsp.h +++ b/lib/rtsp.h @@ -39,6 +39,12 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header); #endif /* CURL_DISABLE_RTSP */ +typedef enum { + RTP_PARSE_SKIP, + RTP_PARSE_CHANNEL, + RTP_PARSE_LEN, + RTP_PARSE_DATA +} rtp_parse_st; /* * RTSP Connection data * @@ -47,6 +53,9 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header); struct rtsp_conn { struct dynbuf buf; int rtp_channel; + size_t rtp_len; + rtp_parse_st state; + BIT(in_header); }; /**************************************************************************** diff --git a/lib/select.c b/lib/select.c index cae9beb6c..d92e745a7 100644 --- a/lib/select.c +++ b/lib/select.c @@ -76,7 +76,7 @@ int Curl_wait_ms(timediff_t timeout_ms) } #if defined(MSDOS) delay(timeout_ms); -#elif defined(WIN32) +#elif defined(_WIN32) /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */ #if TIMEDIFF_T_MAX >= ULONG_MAX if(timeout_ms >= ULONG_MAX) diff --git a/lib/sendf.c b/lib/sendf.c index 0482c5da4..a2fac0c4e 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -50,6 +50,7 @@ #include "strdup.h" #include "http2.h" #include "headers.h" +#include "progress.h" #include "ws.h" /* The last 3 #include files should be in this order */ @@ -57,6 +58,9 @@ #include "curl_memory.h" #include "memdebug.h" + +static CURLcode do_init_stack(struct Curl_easy *data); + #if defined(CURL_DO_LINEEND_CONV) && !defined(CURL_DISABLE_FTP) /* * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF @@ -385,17 +389,17 @@ static CURLcode chop_write(struct Curl_easy *data, the future to leave the original data alone. */ CURLcode Curl_client_write(struct Curl_easy *data, - int type, - char *ptr, - size_t len) + int type, char *buf, size_t blen) { + CURLcode result; + #if !defined(CURL_DISABLE_FTP) && defined(CURL_DO_LINEEND_CONV) /* FTP data may need conversion. */ if((type & CLIENTWRITE_BODY) && (data->conn->handler->protocol & PROTO_FAMILY_FTP) && data->conn->proto.ftpc.transfertype == 'A') { /* convert end-of-line markers */ - len = convert_lineends(data, ptr, len); + blen = convert_lineends(data, buf, blen); } #endif /* it is one of those, at least */ @@ -405,14 +409,14 @@ CURLcode Curl_client_write(struct Curl_easy *data, /* INFO is only INFO */ DEBUGASSERT(!(type & CLIENTWRITE_INFO) || (type == CLIENTWRITE_INFO)); - if(type == CLIENTWRITE_BODY) { - if(data->req.ignorebody) - return CURLE_OK; - - if(data->req.writer_stack && !data->set.http_ce_skip) - return Curl_unencode_write(data, data->req.writer_stack, ptr, len); + if(!data->req.writer_stack) { + result = do_init_stack(data); + if(result) + return result; + DEBUGASSERT(data->req.writer_stack); } - return chop_write(data, type, FALSE, ptr, len); + + return Curl_cwriter_write(data, data->req.writer_stack, type, buf, blen); } CURLcode Curl_client_unpause(struct Curl_easy *data) @@ -449,12 +453,12 @@ CURLcode Curl_client_unpause(struct Curl_easy *data) void Curl_client_cleanup(struct Curl_easy *data) { - struct contenc_writer *writer = data->req.writer_stack; + struct Curl_cwriter *writer = data->req.writer_stack; size_t i; while(writer) { - data->req.writer_stack = writer->downstream; - writer->handler->close_writer(data, writer); + data->req.writer_stack = writer->next; + writer->cwt->do_close(data, writer); free(writer); writer = data->req.writer_stack; } @@ -463,61 +467,222 @@ void Curl_client_cleanup(struct Curl_easy *data) Curl_dyn_free(&data->state.tempwrite[i].b); } data->state.tempcount = 0; + data->req.bytecount = 0; + data->req.headerline = 0; +} +/* Write data using an unencoding writer stack. "nbytes" is not + allowed to be 0. */ +CURLcode Curl_cwriter_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes) +{ + if(!nbytes) + return CURLE_OK; + if(!writer) + return CURLE_WRITE_ERROR; + return writer->cwt->do_write(data, writer, type, buf, nbytes); } -/* Real client writer: no downstream. */ -static CURLcode client_cew_init(struct Curl_easy *data, - struct contenc_writer *writer) +CURLcode Curl_cwriter_def_init(struct Curl_easy *data, + struct Curl_cwriter *writer) { - (void) data; + (void)data; (void)writer; return CURLE_OK; } -static CURLcode client_cew_write(struct Curl_easy *data, - struct contenc_writer *writer, - const char *buf, size_t nbytes) +CURLcode Curl_cwriter_def_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes) { - (void)writer; - if(!nbytes || data->req.ignorebody) - return CURLE_OK; - return chop_write(data, CLIENTWRITE_BODY, FALSE, (char *)buf, nbytes); + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); } -static void client_cew_close(struct Curl_easy *data, - struct contenc_writer *writer) +void Curl_cwriter_def_close(struct Curl_easy *data, + struct Curl_cwriter *writer) { (void) data; (void) writer; } -static const struct content_encoding client_cew = { +/* Real client writer to installed callbacks. */ +static CURLcode cw_client_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes) +{ + (void)writer; + if(!nbytes) + return CURLE_OK; + return chop_write(data, type, FALSE, (char *)buf, nbytes); +} + +static const struct Curl_cwtype cw_client = { + "client", NULL, + Curl_cwriter_def_init, + cw_client_write, + Curl_cwriter_def_close, + sizeof(struct Curl_cwriter) +}; + +static size_t get_max_body_write_len(struct Curl_easy *data, curl_off_t limit) +{ + if(limit != -1) { + /* How much more are we allowed to write? */ + curl_off_t remain_diff; + remain_diff = limit - data->req.bytecount; + if(remain_diff < 0) { + /* already written too much! */ + return 0; + } +#if SIZEOF_CURL_OFF_T > SIZEOF_SIZE_T + else if(remain_diff > SSIZE_T_MAX) { + return SIZE_T_MAX; + } +#endif + else { + return (size_t)remain_diff; + } + } + return SIZE_T_MAX; +} + +/* Download client writer in phase CURL_CW_PROTOCOL that + * sees the "real" download body data. */ +static CURLcode cw_download_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes) +{ + CURLcode result; + size_t nwrite, excess_len = 0; + const char *excess_data = NULL; + + if(!(type & CLIENTWRITE_BODY)) { + if((type & CLIENTWRITE_CONNECT) && data->set.suppress_connect_headers) + return CURLE_OK; + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); + } + + nwrite = nbytes; + if(-1 != data->req.maxdownload) { + size_t wmax = get_max_body_write_len(data, data->req.maxdownload); + if(nwrite > wmax) { + excess_len = nbytes - wmax; + nwrite = wmax; + excess_data = buf + nwrite; + } + + if(nwrite == wmax) { + data->req.download_done = TRUE; + } + } + + if(data->set.max_filesize) { + size_t wmax = get_max_body_write_len(data, data->set.max_filesize); + if(nwrite > wmax) { + nwrite = wmax; + } + } + + data->req.bytecount += nwrite; + ++data->req.bodywrites; + if(!data->req.ignorebody && nwrite) { + result = Curl_cwriter_write(data, writer->next, type, buf, nwrite); + if(result) + return result; + } + result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount); + if(result) + return result; + + if(excess_len) { + if(data->conn->handler->readwrite) { + /* RTSP hack moved from transfer loop to here */ + bool readmore = FALSE; /* indicates data is incomplete, need more */ + size_t consumed = 0; + result = data->conn->handler->readwrite(data, data->conn, + excess_data, excess_len, + &consumed, &readmore); + if(result) + return result; + DEBUGASSERT(consumed <= excess_len); + excess_len -= consumed; + if(readmore) { + data->req.download_done = FALSE; + data->req.keepon |= KEEP_RECV; /* we're not done reading */ + } + } + if(excess_len && !data->req.ignorebody) { + infof(data, + "Excess found writing body:" + " excess = %zu" + ", size = %" CURL_FORMAT_CURL_OFF_T + ", maxdownload = %" CURL_FORMAT_CURL_OFF_T + ", bytecount = %" CURL_FORMAT_CURL_OFF_T, + excess_len, data->req.size, data->req.maxdownload, + data->req.bytecount); + connclose(data->conn, "excess found in a read"); + } + } + else if(nwrite < nbytes) { + failf(data, "Exceeded the maximum allowed file size " + "(%" CURL_FORMAT_CURL_OFF_T ") with %" + CURL_FORMAT_CURL_OFF_T " bytes", + data->set.max_filesize, data->req.bytecount); + return CURLE_FILESIZE_EXCEEDED; + } + + return CURLE_OK; +} + +static const struct Curl_cwtype cw_download = { + "download", NULL, - client_cew_init, - client_cew_write, - client_cew_close, - sizeof(struct contenc_writer) + Curl_cwriter_def_init, + cw_download_write, + Curl_cwriter_def_close, + sizeof(struct Curl_cwriter) +}; + +/* RAW client writer in phase CURL_CW_RAW that + * enabled tracing of raw data. */ +static CURLcode cw_raw_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes) +{ + if(type & CLIENTWRITE_BODY && data->set.verbose && !data->req.ignorebody) { + Curl_debug(data, CURLINFO_DATA_IN, (char *)buf, nbytes); + } + return Curl_cwriter_write(data, writer->next, type, buf, nbytes); +} + +static const struct Curl_cwtype cw_raw = { + "raw", + NULL, + Curl_cwriter_def_init, + cw_raw_write, + Curl_cwriter_def_close, + sizeof(struct Curl_cwriter) }; /* Create an unencoding writer stage using the given handler. */ -CURLcode Curl_client_create_writer(struct contenc_writer **pwriter, +CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, struct Curl_easy *data, - const struct content_encoding *ce_handler, - int order) + const struct Curl_cwtype *cwt, + Curl_cwriter_phase phase) { - struct contenc_writer *writer; + struct Curl_cwriter *writer; CURLcode result = CURLE_OUT_OF_MEMORY; - DEBUGASSERT(ce_handler->writersize >= sizeof(struct contenc_writer)); - writer = (struct contenc_writer *) calloc(1, ce_handler->writersize); + DEBUGASSERT(cwt->cwriter_size >= sizeof(struct Curl_cwriter)); + writer = (struct Curl_cwriter *) calloc(1, cwt->cwriter_size); if(!writer) goto out; - writer->handler = ce_handler; - writer->order = order; - result = ce_handler->init_writer(data, writer); + writer->cwt = cwt; + writer->phase = phase; + result = cwt->do_init(data, writer); out: *pwriter = result? NULL : writer; @@ -526,55 +691,74 @@ CURLcode Curl_client_create_writer(struct contenc_writer **pwriter, return result; } -void Curl_client_free_writer(struct Curl_easy *data, - struct contenc_writer *writer) +void Curl_cwriter_free(struct Curl_easy *data, + struct Curl_cwriter *writer) { if(writer) { - writer->handler->close_writer(data, writer); + writer->cwt->do_close(data, writer); free(writer); } } -/* allow no more than 5 "chained" compression steps */ -#define MAX_ENCODE_STACK 5 +size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase) +{ + struct Curl_cwriter *w; + size_t n = 0; + for(w = data->req.writer_stack; w; w = w->next) { + if(w->phase == phase) + ++n; + } + return n; +} -static CURLcode init_writer_stack(struct Curl_easy *data) +static CURLcode do_init_stack(struct Curl_easy *data) { + struct Curl_cwriter *writer; + CURLcode result; + DEBUGASSERT(!data->req.writer_stack); - return Curl_client_create_writer(&data->req.writer_stack, - data, &client_cew, 0); + result = Curl_cwriter_create(&data->req.writer_stack, + data, &cw_client, CURL_CW_CLIENT); + if(result) + return result; + + result = Curl_cwriter_create(&writer, data, &cw_download, CURL_CW_PROTOCOL); + if(result) + return result; + result = Curl_cwriter_add(data, writer); + if(result) { + Curl_cwriter_free(data, writer); + } + + result = Curl_cwriter_create(&writer, data, &cw_raw, CURL_CW_RAW); + if(result) + return result; + result = Curl_cwriter_add(data, writer); + if(result) { + Curl_cwriter_free(data, writer); + } + return result; } -CURLcode Curl_client_add_writer(struct Curl_easy *data, - struct contenc_writer *writer) +CURLcode Curl_cwriter_add(struct Curl_easy *data, + struct Curl_cwriter *writer) { CURLcode result; + struct Curl_cwriter **anchor = &data->req.writer_stack; - if(!data->req.writer_stack) { - result = init_writer_stack(data); + if(!*anchor) { + result = do_init_stack(data); if(result) return result; } - if(data->req.writer_stack_depth++ >= MAX_ENCODE_STACK) { - failf(data, "Reject response due to more than %u content encodings", - MAX_ENCODE_STACK); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Stack the unencoding stage. */ - if(writer->order >= data->req.writer_stack->order) { - writer->downstream = data->req.writer_stack; - data->req.writer_stack = writer; - } - else { - struct contenc_writer *w = data->req.writer_stack; - while(w->downstream && writer->order < w->downstream->order) - w = w->downstream; - writer->downstream = w->downstream; - w->downstream = writer; - } + /* Insert the writer as first in its phase. + * Skip existing writers of lower phases. */ + while(*anchor && (*anchor)->phase < writer->phase) + anchor = &((*anchor)->next); + writer->next = *anchor; + *anchor = writer; return CURLE_OK; } diff --git a/lib/sendf.h b/lib/sendf.h index 9ee00bb0d..a70189f2f 100644 --- a/lib/sendf.h +++ b/lib/sendf.h @@ -50,43 +50,122 @@ #define CLIENTWRITE_1XX (1<<5) /* a 1xx response related HEADER */ #define CLIENTWRITE_TRAILER (1<<6) /* a trailer HEADER */ +/** + * Write `len` bytes at `prt` to the client. `type` indicates what + * kind of data is being written. + */ CURLcode Curl_client_write(struct Curl_easy *data, int type, char *ptr, size_t len) WARN_UNUSED_RESULT; +/** + * For a paused transfer, there might be buffered data held back. + * Attempt to flush this data to the client. This *may* trigger + * another pause of the transfer. + */ CURLcode Curl_client_unpause(struct Curl_easy *data); + +/** + * Free all resources related to client writing. + */ void Curl_client_cleanup(struct Curl_easy *data); -struct contenc_writer { - const struct content_encoding *handler; /* Encoding handler. */ - struct contenc_writer *downstream; /* Downstream writer. */ - unsigned int order; /* Ordering within writer stack. */ +/** + * Client Writers - a chain passing transfer BODY data to the client. + * Main application: HTTP and related protocols + * Other uses: monitoring of download progress + * + * Writers in the chain are order by their `phase`. First come all + * writers in CURL_CW_RAW, followed by any in CURL_CW_TRANSFER_DECODE, + * followed by any in CURL_CW_PROTOCOL, etc. + * + * When adding a writer, it is inserted as first in its phase. This means + * the order of adding writers of the same phase matters, but writers for + * different phases may be added in any order. + * + * Writers which do modify the BODY data written are expected to be of + * phases TRANSFER_DECODE or CONTENT_DECODE. The other phases are intended + * for monitoring writers. Which do *not* modify the data but gather + * statistics or update progress reporting. + */ + +/* Phase a writer operates at. */ +typedef enum { + CURL_CW_RAW, /* raw data written, before any decoding */ + CURL_CW_TRANSFER_DECODE, /* remove transfer-encodings */ + CURL_CW_PROTOCOL, /* after transfer, but before content decoding */ + CURL_CW_CONTENT_DECODE, /* remove content-encodings */ + CURL_CW_CLIENT /* data written to client */ +} Curl_cwriter_phase; + +/* Client Writer Type, provides the implementation */ +struct Curl_cwtype { + const char *name; /* writer name. */ + const char *alias; /* writer name alias, maybe NULL. */ + CURLcode (*do_init)(struct Curl_easy *data, + struct Curl_cwriter *writer); + CURLcode (*do_write)(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes); + void (*do_close)(struct Curl_easy *data, + struct Curl_cwriter *writer); + size_t cwriter_size; /* sizeof() allocated struct Curl_cwriter */ }; -/* Content encoding writer. */ -struct content_encoding { - const char *name; /* Encoding name. */ - const char *alias; /* Encoding name alias. */ - CURLcode (*init_writer)(struct Curl_easy *data, - struct contenc_writer *writer); - CURLcode (*unencode_write)(struct Curl_easy *data, - struct contenc_writer *writer, - const char *buf, size_t nbytes); - void (*close_writer)(struct Curl_easy *data, - struct contenc_writer *writer); - size_t writersize; +/* Client writer instance */ +struct Curl_cwriter { + const struct Curl_cwtype *cwt; /* type implementation */ + struct Curl_cwriter *next; /* Downstream writer. */ + Curl_cwriter_phase phase; /* phase at which it operates */ }; +/** + * Create a new cwriter instance with given type and phase. Is not + * inserted into the writer chain by this call. + * Invokes `writer->do_init()`. + */ +CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter, + struct Curl_easy *data, + const struct Curl_cwtype *ce_handler, + Curl_cwriter_phase phase); -CURLcode Curl_client_create_writer(struct contenc_writer **pwriter, - struct Curl_easy *data, - const struct content_encoding *ce_handler, - int order); +/** + * Free a cwriter instance. + * Invokes `writer->do_close()`. + */ +void Curl_cwriter_free(struct Curl_easy *data, + struct Curl_cwriter *writer); -void Curl_client_free_writer(struct Curl_easy *data, - struct contenc_writer *writer); +/** + * Count the number of writers installed of the given phase. + */ +size_t Curl_cwriter_count(struct Curl_easy *data, Curl_cwriter_phase phase); -CURLcode Curl_client_add_writer(struct Curl_easy *data, - struct contenc_writer *writer); +/** + * Adds a writer to the transfer's writer chain. + * The writers `phase` determines where in the chain it is inserted. + */ +CURLcode Curl_cwriter_add(struct Curl_easy *data, + struct Curl_cwriter *writer); + +/** + * Convenience method for calling `writer->do_write()` that + * checks for NULL writer. + */ +CURLcode Curl_cwriter_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes); + +/** + * Default implementations for do_init, do_write, do_close that + * do nothing and pass the data through. + */ +CURLcode Curl_cwriter_def_init(struct Curl_easy *data, + struct Curl_cwriter *writer); +CURLcode Curl_cwriter_def_write(struct Curl_easy *data, + struct Curl_cwriter *writer, int type, + const char *buf, size_t nbytes); +void Curl_cwriter_def_close(struct Curl_easy *data, + struct Curl_cwriter *writer); /* internal read-function, does plain socket, SSL and krb4 */ diff --git a/lib/setopt.c b/lib/setopt.c index 0d399adfe..a08140cce 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -50,6 +50,7 @@ #include "multiif.h" #include "altsvc.h" #include "hsts.h" +#include "tftp.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -171,7 +172,7 @@ static CURLcode protocol2num(const char *str, curl_prot_t *val) str = strchr(str, ','); tlen = str? (size_t) (str - token): strlen(token); if(tlen) { - const struct Curl_handler *h = Curl_builtin_scheme(token, tlen); + const struct Curl_handler *h = Curl_getn_scheme_handler(token, tlen); if(!h) return CURLE_UNSUPPORTED_PROTOCOL; @@ -261,43 +262,43 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Set the absolute number of maximum simultaneous alive connection that * libcurl is allowed to have. */ - arg = va_arg(param, long); - if(arg < 0) + uarg = va_arg(param, unsigned long); + if(uarg > UINT_MAX) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.maxconnects = arg; + 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 = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.reuse_forbid = (0 != va_arg(param, long)); 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 = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.reuse_fresh = (0 != va_arg(param, long)); 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 = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.verbose = (0 != va_arg(param, long)); break; case CURLOPT_HEADER: /* * Set to include the header in the general data output stream. */ - data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.include_header = (0 != va_arg(param, long)); break; case CURLOPT_NOPROGRESS: /* * Shut off the internal supported progress meter */ - data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.hide_progress = (0 != va_arg(param, long)); if(data->set.hide_progress) data->progress.flags |= PGRS_HIDE; else @@ -307,7 +308,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Do not include the body part in the output data stream. */ - data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.opt_no_body = (0 != va_arg(param, long)); #ifndef CURL_DISABLE_HTTP if(data->set.opt_no_body) /* in HTTP lingo, no body means using the HEAD request... */ @@ -321,11 +322,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Don't output the >=400 error code HTML-page, but instead only * return error. */ - data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.http_fail_on_error = (0 != va_arg(param, long)); break; case CURLOPT_KEEP_SENDING_ON_ERROR: - data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.http_keep_sending_on_error = (0 != va_arg(param, long)); break; case CURLOPT_UPLOAD: case CURLOPT_PUT: @@ -353,7 +353,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * 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 = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.get_filetime = (0 != va_arg(param, long)); break; case CURLOPT_SERVER_RESPONSE_TIMEOUT: /* @@ -379,7 +379,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * TFTP option that specifies the block size to use for data transmission. */ arg = va_arg(param, long); - if(arg < 0) + if(arg > TFTP_BLKSIZE_MAX || arg < TFTP_BLKSIZE_MIN) return CURLE_BAD_FUNCTION_ARGUMENT; data->set.tftp_blksize = arg; break; @@ -409,7 +409,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * * Transfer using ASCII (instead of BINARY). */ - data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.prefer_ascii = (0 != va_arg(param, long)); break; case CURLOPT_TIMECONDITION: /* @@ -577,7 +577,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Switch on automatic referer that gets set if curl follows locations. */ - data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.http_auto_referer = (0 != va_arg(param, long)); break; case CURLOPT_ACCEPT_ENCODING: @@ -592,28 +592,23 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ argptr = va_arg(param, char *); if(argptr && !*argptr) { - argptr = Curl_all_content_encodings(); - if(!argptr) - result = CURLE_OUT_OF_MEMORY; - else { - result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); - free(argptr); - } + char all[256]; + Curl_all_content_encodings(all, sizeof(all)); + result = Curl_setstropt(&data->set.str[STRING_ENCODING], all); } else result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); break; case CURLOPT_TRANSFER_ENCODING: - data->set.http_transfer_encoding = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.http_transfer_encoding = (0 != va_arg(param, long)); break; case CURLOPT_FOLLOWLOCATION: /* * Follow Location: header hints on an HTTP-server. */ - data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.http_follow_location = (0 != va_arg(param, long)); break; case CURLOPT_UNRESTRICTED_AUTH: @@ -621,8 +616,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Send authentication (user+password) when following locations, even when * hostname changed. */ - data->set.allow_auth_to_other_hosts = - (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.allow_auth_to_other_hosts = (0 != va_arg(param, long)); break; case CURLOPT_MAXREDIRS: @@ -736,7 +730,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Set header option. */ arg = va_arg(param, long); - data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE); + data->set.sep_headers = !!(arg & CURLHEADER_SEPARATE); break; #if !defined(CURL_DISABLE_COOKIES) @@ -760,18 +754,18 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) return CURLE_BAD_FUNCTION_ARGUMENT; /* append the cookie file name to the list of file names, and deal with them later */ - cl = curl_slist_append(data->set.cookielist, argptr); + cl = curl_slist_append(data->state.cookielist, argptr); if(!cl) { - curl_slist_free_all(data->set.cookielist); - data->set.cookielist = NULL; + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; return CURLE_OUT_OF_MEMORY; } - data->set.cookielist = cl; /* store the list for later use */ + data->state.cookielist = cl; /* store the list for later use */ } else { /* clear the list of cookie files */ - curl_slist_free_all(data->set.cookielist); - data->set.cookielist = NULL; + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; if(!data->share || !data->share->cookies) { /* throw away all existing cookies if this isn't a shared cookie @@ -811,17 +805,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * prevent the forthcoming read-cookies-from-file actions to accept * cookies that are marked as being session cookies, as they belong to a * previous session. - * - * In the original Netscape cookie spec, "session cookies" are cookies - * with no expire date set. RFC2109 describes the same action if no - * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds - * a 'Discard' action that can enforce the discard even for cookies that - * have a Max-Age. - * - * We run mostly with the original cookie spec, as hardly anyone implements - * anything else. */ - data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.cookiesession = (0 != va_arg(param, long)); break; case CURLOPT_COOKIELIST: @@ -956,7 +941,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) if(arg) return CURLE_BAD_FUNCTION_ARGUMENT; #else - data->set.http09_allowed = arg ? TRUE : FALSE; + data->set.http09_allowed = !!arg; #endif break; @@ -997,8 +982,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_MIME_OPTIONS: - data->set.mime_options = (unsigned int)va_arg(param, long); - break; + arg = va_arg(param, long); + data->set.mime_formescape = !!(arg & CURLMIMEOPT_FORMESCAPE); + break; # endif #endif @@ -1018,8 +1004,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = - (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); + data->state.authhost.iestyle = !!(auth & CURLAUTH_DIGEST_IE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1072,8 +1057,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Tunnel operations through the proxy instead of normal proxy use */ - data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)); break; case CURLOPT_PROXYPORT: @@ -1102,8 +1086,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* the DIGEST_IE bit is only used to set a special marker, for all the rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = - (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); + data->state.authproxy.iestyle = !!(auth & CURLAUTH_DIGEST_IE); if(auth & CURLAUTH_DIGEST_IE) { auth |= CURLAUTH_DIGEST; /* set standard digest bit */ @@ -1203,7 +1186,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Set flag for NEC SOCK5 support */ - data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.socks5_gssapi_nec = (0 != va_arg(param, long)); break; #endif #ifndef CURL_DISABLE_PROXY @@ -1251,7 +1234,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * 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 = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.list_only = (0 != va_arg(param, long)); break; #endif case CURLOPT_APPEND: @@ -1259,7 +1242,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * We want to upload and append to an existing file. Used for FTP and * SFTP. */ - data->set.remote_append = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.remote_append = (0 != va_arg(param, long)); break; #ifndef CURL_DISABLE_FTP @@ -1270,7 +1253,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftp_filemethod = (unsigned char)(curl_ftpfile)arg; + data->set.ftp_filemethod = (unsigned char)arg; break; case CURLOPT_FTPPORT: /* @@ -1278,26 +1261,26 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ result = Curl_setstropt(&data->set.str[STRING_FTPPORT], va_arg(param, char *)); - data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE; + data->set.ftp_use_port = !!(data->set.str[STRING_FTPPORT]); break; case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ftp_use_eprt = (0 != va_arg(param, long)); break; case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ftp_use_epsv = (0 != va_arg(param, long)); break; case CURLOPT_FTP_USE_PRET: - data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ftp_use_pret = (0 != va_arg(param, long)); break; case CURLOPT_FTP_SSL_CCC: arg = va_arg(param, long); if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ftp_ccc = (unsigned char)(curl_ftpccc)arg; + data->set.ftp_ccc = (unsigned char)arg; break; case CURLOPT_FTP_SKIP_PASV_IP: @@ -1305,7 +1288,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * 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 = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ftp_skip_ip = (0 != va_arg(param, long)); break; case CURLOPT_FTP_ACCOUNT: @@ -1333,7 +1316,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], va_arg(param, char *)); - data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE; + data->set.krb = !!(data->set.str[STRING_KRB_LEVEL]); break; #endif #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) @@ -1867,14 +1850,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Kludgy option to enable CRLF conversions. Subject for removal. */ - data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.crlf = (0 != va_arg(param, long)); break; #ifndef CURL_DISABLE_PROXY case CURLOPT_HAPROXYPROTOCOL: /* * Set to send the HAProxy Proxy Protocol header */ - data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.haproxyprotocol = (0 != va_arg(param, long)); break; case CURLOPT_HAPROXY_CLIENT_IP: /* @@ -1926,22 +1909,17 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Enable peer SSL verifying. */ - data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)); /* Update the current connection ssl_config. */ - if(data->conn) { - data->conn->ssl_config.verifypeer = - data->set.ssl.primary.verifypeer; - } + 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 = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.doh_verifypeer = (0 != va_arg(param, long)); break; #endif #ifndef CURL_DISABLE_PROXY @@ -1953,10 +1931,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) (0 != va_arg(param, long))?TRUE:FALSE; /* Update the current connection proxy_ssl_config. */ - if(data->conn) { - data->conn->proxy_ssl_config.verifypeer = - data->set.proxy_ssl.primary.verifypeer; - } + Curl_ssl_conn_config_update(data, TRUE); break; #endif case CURLOPT_SSL_VERIFYHOST: @@ -1968,13 +1943,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* Obviously people are not reading documentation and too many thought this argument took a boolean when it wasn't and misused it. Treat 1 and 2 the same */ - data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE); + data->set.ssl.primary.verifyhost = !!(arg & 3); /* Update the current connection ssl_config. */ - if(data->conn) { - data->conn->ssl_config.verifyhost = - data->set.ssl.primary.verifyhost; - } + Curl_ssl_conn_config_update(data, FALSE); break; #ifndef CURL_DISABLE_DOH case CURLOPT_DOH_SSL_VERIFYHOST: @@ -1984,7 +1956,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); /* Treat both 1 and 2 as TRUE */ - data->set.doh_verifyhost = (bool)((arg & 3) ? TRUE : FALSE); + data->set.doh_verifyhost = !!(arg & 3); break; #endif #ifndef CURL_DISABLE_PROXY @@ -1996,12 +1968,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* Treat both 1 and 2 as TRUE */ data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE); - /* Update the current connection proxy_ssl_config. */ - if(data->conn) { - data->conn->proxy_ssl_config.verifyhost = - data->set.proxy_ssl.primary.verifyhost; - } + Curl_ssl_conn_config_update(data, TRUE); break; #endif case CURLOPT_SSL_VERIFYSTATUS: @@ -2013,14 +1981,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; } - data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)); /* Update the current connection ssl_config. */ - if(data->conn) { - data->conn->ssl_config.verifystatus = - data->set.ssl.primary.verifystatus; - } + Curl_ssl_conn_config_update(data, FALSE); break; #ifndef CURL_DISABLE_DOH case CURLOPT_DOH_SSL_VERIFYSTATUS: @@ -2032,8 +1996,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; } - data->set.doh_verifystatus = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.doh_verifystatus = (0 != va_arg(param, long)); break; #endif case CURLOPT_SSL_CTX_FUNCTION: @@ -2067,12 +2030,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; } - data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ssl.falsestart = (0 != va_arg(param, long)); break; case CURLOPT_CERTINFO: #ifdef USE_SSL if(Curl_ssl_supports(data, SSLSUPP_CERTINFO)) - data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ssl.certinfo = (0 != va_arg(param, long)); else #endif result = CURLE_NOT_BUILT_IN; @@ -2118,14 +2081,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Specify entire PEM of the CA certificate */ #ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) + if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) { result = Curl_setblobopt(&data->set.blobs[BLOB_CAINFO], va_arg(param, struct curl_blob *)); + break; + } else #endif return CURLE_NOT_BUILT_IN; - - break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CAINFO: /* @@ -2141,13 +2104,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Specify entire PEM of the CA certificate */ #ifdef USE_SSL - if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) + if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) { result = Curl_setblobopt(&data->set.blobs[BLOB_CAINFO_PROXY], va_arg(param, struct curl_blob *)); + break; + } else #endif return CURLE_NOT_BUILT_IN; - break; #endif case CURLOPT_CAPATH: /* @@ -2278,7 +2242,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * The application asks not to set any signal() or alarm() handlers, * even when using a timeout. */ - data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.no_signal = (0 != va_arg(param, long)); break; case CURLOPT_SHARE: @@ -2453,11 +2417,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Enable or disable TCP_NODELAY, which will disable/enable the Nagle * algorithm */ - data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.tcp_nodelay = (0 != va_arg(param, long)); break; case CURLOPT_IGNORE_CONTENT_LENGTH: - data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ignorecl = (0 != va_arg(param, long)); break; case CURLOPT_CONNECT_ONLY: @@ -2532,8 +2496,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_SSL_SESSIONID_CACHE: - data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ? - TRUE : FALSE; + data->set.ssl.primary.sessionid = (0 != va_arg(param, long)); #ifndef CURL_DISABLE_PROXY data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid; #endif @@ -2622,7 +2585,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * disable libcurl transfer encoding is used */ #ifndef USE_HYPER - data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; + data->set.http_te_skip = (0 == va_arg(param, long)); break; #else return CURLE_NOT_BUILT_IN; /* hyper doesn't support */ @@ -2632,7 +2595,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * raw data passed to the application when content encoding is used */ - data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; + data->set.http_ce_skip = (0 == va_arg(param, long)); break; #if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) @@ -2733,7 +2696,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_MAIL_RCPT_ALLOWFAILS: /* allow RCPT TO command to fail for some recipients */ - data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)); break; #endif @@ -2745,7 +2708,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_SASL_IR: /* Enable/disable SASL initial response */ - data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.sasl_ir = (0 != va_arg(param, long)); break; #ifndef CURL_DISABLE_RTSP case CURLOPT_RTSP_REQUEST: @@ -2859,7 +2822,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif #ifndef CURL_DISABLE_FTP case CURLOPT_WILDCARDMATCH: - data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.wildcard_enabled = (0 != va_arg(param, long)); break; case CURLOPT_CHUNK_BGN_FUNCTION: data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); @@ -2942,7 +2905,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif case CURLOPT_TCP_KEEPALIVE: - data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.tcp_keepalive = (0 != va_arg(param, long)); break; case CURLOPT_TCP_KEEPIDLE: arg = va_arg(param, long); @@ -2971,7 +2934,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_SSL_ENABLE_NPN: break; case CURLOPT_SSL_ENABLE_ALPN: - data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.ssl_enable_alpn = (0 != va_arg(param, long)); break; #ifdef USE_UNIX_SOCKETS case CURLOPT_UNIX_SOCKET_PATH: @@ -2987,10 +2950,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif case CURLOPT_PATH_AS_IS: - data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.path_as_is = (0 != va_arg(param, long)); break; case CURLOPT_PIPEWAIT: - data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.pipewait = (0 != va_arg(param, long)); break; case CURLOPT_STREAM_WEIGHT: #if defined(USE_HTTP2) || defined(USE_HTTP3) @@ -3025,12 +2988,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #ifndef CURL_DISABLE_SHUFFLE_DNS case CURLOPT_DNS_SHUFFLE_ADDRESSES: - data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE; + data->set.dns_shuffle_addresses = (0 != va_arg(param, long)); break; #endif case CURLOPT_DISALLOW_USERNAME_IN_URL: - data->set.disallow_username_in_url = - (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.disallow_username_in_url = (0 != va_arg(param, long)); break; #ifndef CURL_DISABLE_DOH case CURLOPT_DOH_URL: @@ -3095,18 +3057,18 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* this needs to build a list of file names to read from, so that it can read them later, as we might get a shared HSTS handle to load them into */ - h = curl_slist_append(data->set.hstslist, argptr); + h = curl_slist_append(data->state.hstslist, argptr); if(!h) { - curl_slist_free_all(data->set.hstslist); - data->set.hstslist = NULL; + curl_slist_free_all(data->state.hstslist); + data->state.hstslist = NULL; return CURLE_OUT_OF_MEMORY; } - data->set.hstslist = h; /* store the list for later use */ + data->state.hstslist = h; /* store the list for later use */ } else { /* clear the list of HSTS files */ - curl_slist_free_all(data->set.hstslist); - data->set.hstslist = NULL; + curl_slist_free_all(data->state.hstslist); + data->state.hstslist = NULL; if(!data->share || !data->share->hsts) /* throw away the HSTS cache unless shared */ Curl_hsts_cleanup(&data->hsts); diff --git a/lib/setup-win32.h b/lib/setup-win32.h index 13948389a..4e034d4bb 100644 --- a/lib/setup-win32.h +++ b/lib/setup-win32.h @@ -53,14 +53,14 @@ # ifndef NOGDI # define NOGDI # endif -# include -# include # ifdef HAVE_WINSOCK2_H # include # ifdef HAVE_WS2TCPIP_H # include # endif # endif +# include +# include # include # ifdef UNICODE typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str); @@ -96,18 +96,12 @@ #ifndef _WIN32_WINNT_WS03 #define _WIN32_WINNT_WS03 0x0502 /* Windows Server 2003 */ #endif -#ifndef _WIN32_WINNT_WIN6 -#define _WIN32_WINNT_WIN6 0x0600 /* Windows Vista */ -#endif #ifndef _WIN32_WINNT_VISTA #define _WIN32_WINNT_VISTA 0x0600 /* Windows Vista */ #endif #ifndef _WIN32_WINNT_WS08 #define _WIN32_WINNT_WS08 0x0600 /* Windows Server 2008 */ #endif -#ifndef _WIN32_WINNT_LONGHORN -#define _WIN32_WINNT_LONGHORN 0x0600 /* Windows Vista */ -#endif #ifndef _WIN32_WINNT_WIN7 #define _WIN32_WINNT_WIN7 0x0601 /* Windows 7 */ #endif @@ -117,9 +111,6 @@ #ifndef _WIN32_WINNT_WINBLUE #define _WIN32_WINNT_WINBLUE 0x0603 /* Windows 8.1 */ #endif -#ifndef _WIN32_WINNT_WINTHRESHOLD -#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 /* Windows 10 */ -#endif #ifndef _WIN32_WINNT_WIN10 #define _WIN32_WINNT_WIN10 0x0A00 /* Windows 10 */ #endif diff --git a/lib/share.h b/lib/share.h index 7f55aac85..632d9198f 100644 --- a/lib/share.h +++ b/lib/share.h @@ -31,14 +31,6 @@ #include "urldata.h" #include "conncache.h" -/* SalfordC says "A structure member may not be volatile". Hence: - */ -#ifdef __SALFORDC__ -#define CURL_VOLATILE -#else -#define CURL_VOLATILE volatile -#endif - #define CURL_GOOD_SHARE 0x7e117a1e #define GOOD_SHARE_HANDLE(x) ((x) && (x)->magic == CURL_GOOD_SHARE) @@ -46,7 +38,7 @@ struct Curl_share { unsigned int magic; /* CURL_GOOD_SHARE */ unsigned int specifier; - CURL_VOLATILE unsigned int dirty; + volatile unsigned int dirty; curl_lock_function lockfunc; curl_unlock_function unlockfunc; diff --git a/lib/smb.c b/lib/smb.c index 32c5137a4..6c8a47c7f 100644 --- a/lib/smb.c +++ b/lib/smb.c @@ -27,7 +27,7 @@ #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) -#ifdef WIN32 +#ifdef _WIN32 #define getpid GetCurrentProcessId #endif @@ -1047,14 +1047,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done) break; } } - data->req.bytecount += len; data->req.offset += len; - result = Curl_pgrsSetDownloadCounter(data, data->req.bytecount); - if(result) { - req->result = result; - next_state = SMB_CLOSE; - break; - } next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD; break; diff --git a/lib/smtp.c b/lib/smtp.c index 81a17e38d..65fbc5b6c 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1320,7 +1320,7 @@ static CURLcode smtp_init(struct Curl_easy *data) CURLcode result = CURLE_OK; struct SMTP *smtp; - smtp = data->req.p.smtp = calloc(sizeof(struct SMTP), 1); + smtp = data->req.p.smtp = calloc(1, sizeof(struct SMTP)); if(!smtp) result = CURLE_OUT_OF_MEMORY; diff --git a/lib/socketpair.c b/lib/socketpair.c index 963e1406f..e3d40ff94 100644 --- a/lib/socketpair.c +++ b/lib/socketpair.c @@ -28,7 +28,7 @@ #include "rand.h" #if !defined(HAVE_SOCKETPAIR) && !defined(CURL_DISABLE_SOCKETPAIR) -#ifdef WIN32 +#ifdef _WIN32 /* * This is a socketpair() implementation for Windows. */ @@ -50,7 +50,7 @@ #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif /* !INADDR_LOOPBACK */ -#endif /* !WIN32 */ +#endif /* !_WIN32 */ #include "nonblock.h" /* for curlx_nonblock */ #include "timeval.h" /* needed before select.h */ @@ -87,7 +87,7 @@ int Curl_socketpair(int domain, int type, int protocol, socks[0] = socks[1] = CURL_SOCKET_BAD; -#if defined(WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) || defined(__CYGWIN__) /* don't set SO_REUSEADDR on Windows */ (void)reuse; #ifdef SO_EXCLUSIVEADDRUSE diff --git a/lib/socketpair.h b/lib/socketpair.h index 306ab5dc4..bd499abbe 100644 --- a/lib/socketpair.h +++ b/lib/socketpair.h @@ -25,6 +25,23 @@ ***************************************************************************/ #include "curl_setup.h" + +#ifdef HAVE_PIPE + +#define wakeup_write write +#define wakeup_read read +#define wakeup_close close +#define wakeup_create pipe + +#else /* HAVE_PIPE */ + +#define wakeup_write swrite +#define wakeup_read sread +#define wakeup_close sclose +#define wakeup_create(p) Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, p) + +#endif /* HAVE_PIPE */ + #ifndef HAVE_SOCKETPAIR #include diff --git a/lib/socks.c b/lib/socks.c index a7b5ab07e..3a396de62 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -339,8 +339,8 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, if(dns) { #ifdef CURLRES_ASYNCH - data->state.async.dns = dns; - data->state.async.done = TRUE; + conn->resolve_async.dns = dns; + conn->resolve_async.done = TRUE; #endif infof(data, "Hostname '%s' was found", sx->hostname); sxstate(sx, data, CONNECT_RESOLVED); @@ -402,8 +402,11 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ if(sx->proxy_user) { size_t plen = strlen(sx->proxy_user); - if(plen >= (size_t)data->set.buffer_size - 8) { - failf(data, "Too long SOCKS proxy user name, can't use"); + if(plen > 255) { + /* there is no real size limit to this field in the protocol, but + SOCKS5 limits the proxy user field to 255 bytes and it seems likely + that a longer field is either a mistake or malicious input */ + failf(data, "Too long SOCKS proxy user name"); return CURLPX_LONG_USER; } /* copy the proxy name WITH trailing zero */ @@ -426,7 +429,8 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, socksreq[7] = 1; /* append hostname */ hostnamelen = strlen(sx->hostname) + 1; /* length including NUL */ - if(hostnamelen <= 255) + if((hostnamelen <= 255) && + (packetsize + hostnamelen < data->set.buffer_size)) strcpy((char *)socksreq + packetsize, sx->hostname); else { failf(data, "SOCKS4: too long host name"); @@ -802,8 +806,8 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, if(dns) { #ifdef CURLRES_ASYNCH - data->state.async.dns = dns; - data->state.async.done = TRUE; + conn->resolve_async.dns = dns; + conn->resolve_async.done = TRUE; #endif infof(data, "SOCKS5: hostname '%s' found", sx->hostname); } @@ -819,10 +823,19 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, /* FALLTHROUGH */ CONNECT_RESOLVED: case CONNECT_RESOLVED: { - char dest[MAX_IPADR_LEN] = "unknown"; /* printable address */ + char dest[MAX_IPADR_LEN]; /* printable address */ struct Curl_addrinfo *hp = NULL; if(dns) hp = dns->addr; +#ifdef ENABLE_IPV6 + if(data->set.ipver != CURL_IPRESOLVE_WHATEVER) { + int wanted_family = data->set.ipver == CURL_IPRESOLVE_V4 ? + AF_INET : AF_INET6; + /* scan for the first proper address */ + while(hp && (hp->ai_family != wanted_family)) + hp = hp->ai_next; + } +#endif if(!hp) { failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", sx->hostname); @@ -1119,7 +1132,7 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, return result; if(!sx) { - sx = calloc(sizeof(*sx), 1); + sx = calloc(1, sizeof(*sx)); if(!sx) return CURLE_OUT_OF_MEMORY; cf->ctx = sx; @@ -1157,32 +1170,29 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, return result; } -static int socks_cf_get_select_socks(struct Curl_cfilter *cf, +static void socks_cf_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { struct socks_state *sx = cf->ctx; - int fds; - fds = cf->next->cft->get_select_socks(cf->next, data, socks); - if(!fds && cf->next->connected && !cf->connected && sx) { + if(!cf->connected && sx) { /* If we are not connected, the filter below is and has nothing * to wait on, we determine what to wait for. */ - socks[0] = Curl_conn_cf_get_socket(cf, data); + curl_socket_t sock = Curl_conn_cf_get_socket(cf, data); switch(sx->state) { case CONNECT_RESOLVING: case CONNECT_SOCKS_READ: case CONNECT_AUTH_READ: case CONNECT_REQ_READ: case CONNECT_REQ_READ_MORE: - fds = GETSOCK_READSOCK(0); + Curl_pollset_set_in_only(data, ps, sock); break; default: - fds = GETSOCK_WRITESOCK(0); + Curl_pollset_set_out_only(data, ps, sock); break; } } - return fds; } static void socks_proxy_cf_close(struct Curl_cfilter *cf, @@ -1227,7 +1237,7 @@ struct Curl_cftype Curl_cft_socks_proxy = { socks_proxy_cf_connect, socks_proxy_cf_close, socks_cf_get_host, - socks_cf_get_select_socks, + socks_cf_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, Curl_cf_def_recv, diff --git a/lib/strdup.c b/lib/strdup.c index 07a61391a..2578441c3 100644 --- a/lib/strdup.c +++ b/lib/strdup.c @@ -26,7 +26,7 @@ #include -#ifdef WIN32 +#ifdef _WIN32 #include #endif @@ -56,7 +56,7 @@ char *Curl_strdup(const char *str) } #endif -#ifdef WIN32 +#ifdef _WIN32 /*************************************************************************** * * Curl_wcsdup(source) @@ -99,6 +99,30 @@ void *Curl_memdup(const void *src, size_t length) return buffer; } +/*************************************************************************** + * + * Curl_strndup(source, length) + * + * Copies the 'source' string to a newly allocated buffer (that is returned). + * Copies not more than 'length' bytes (up to a null terminator) then adds a + * null terminator. + * + * Returns the new pointer or NULL on failure. + * + ***************************************************************************/ +void *Curl_strndup(const char *src, size_t length) +{ + char *buf = memchr(src, '\0', length); + if(buf) + length = buf - src; + buf = malloc(length + 1); + if(!buf) + return NULL; + memcpy(buf, src, length); + buf[length] = 0; + return buf; +} + /*************************************************************************** * * Curl_saferealloc(ptr, size) diff --git a/lib/strdup.h b/lib/strdup.h index c3430b54d..9f12b2548 100644 --- a/lib/strdup.h +++ b/lib/strdup.h @@ -28,10 +28,11 @@ #ifndef HAVE_STRDUP char *Curl_strdup(const char *str); #endif -#ifdef WIN32 +#ifdef _WIN32 wchar_t* Curl_wcsdup(const wchar_t* src); #endif void *Curl_memdup(const void *src, size_t buffer_length); void *Curl_saferealloc(void *ptr, size_t size); +void *Curl_strndup(const char *src, size_t length); #endif /* HEADER_CURL_STRDUP_H */ diff --git a/lib/strerror.c b/lib/strerror.c index be4191414..0d5f9276f 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -48,7 +48,7 @@ #include "curl_memory.h" #include "memdebug.h" -#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(_WIN32) || defined(_WIN32_WCE) #define PRESERVE_WINDOWS_ERROR_CODE #endif @@ -762,7 +762,7 @@ get_winsock_error (int err, char *buf, size_t len) } #endif /* USE_WINSOCK */ -#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(_WIN32) || defined(_WIN32_WCE) /* This is a helper function for Curl_strerror that converts Windows API error * codes (GetLastError) to error messages. * Returns NULL if no error message was found for error code. @@ -804,7 +804,7 @@ get_winapi_error(int err, char *buf, size_t buflen) return (*buf ? buf : NULL); } -#endif /* WIN32 || _WIN32_WCE */ +#endif /* _WIN32 || _WIN32_WCE */ /* * Our thread-safe and smart strerror() replacement. @@ -837,15 +837,15 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) if(!buflen) return NULL; -#ifndef WIN32 +#ifndef _WIN32 DEBUGASSERT(err >= 0); #endif max = buflen - 1; *buf = '\0'; -#if defined(WIN32) || defined(_WIN32_WCE) -#if defined(WIN32) +#if defined(_WIN32) || defined(_WIN32_WCE) +#if defined(_WIN32) /* 'sys_nerr' is the maximum errno number, it is not widely portable */ if(err >= 0 && err < sys_nerr) strncpy(buf, sys_errlist[err], max); @@ -923,7 +923,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) * Curl_winapi_strerror: * Variant of Curl_strerror if the error code is definitely Windows API. */ -#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(_WIN32) || defined(_WIN32_WCE) const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE @@ -958,7 +958,7 @@ const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen) return buf; } -#endif /* WIN32 || _WIN32_WCE */ +#endif /* _WIN32 || _WIN32_WCE */ #ifdef USE_WINDOWS_SSPI /* @@ -986,6 +986,10 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) break; #define SEC2TXT(sec) case sec: txt = #sec; break SEC2TXT(CRYPT_E_REVOKED); + SEC2TXT(CRYPT_E_NO_REVOCATION_DLL); + SEC2TXT(CRYPT_E_NO_REVOCATION_CHECK); + SEC2TXT(CRYPT_E_REVOCATION_OFFLINE); + SEC2TXT(CRYPT_E_NOT_IN_REVOCATION_DATABASE); SEC2TXT(SEC_E_ALGORITHM_MISMATCH); SEC2TXT(SEC_E_BAD_BINDINGS); SEC2TXT(SEC_E_BAD_PKGID); diff --git a/lib/strerror.h b/lib/strerror.h index 399712f8e..680686734 100644 --- a/lib/strerror.h +++ b/lib/strerror.h @@ -29,7 +29,7 @@ #define STRERROR_LEN 256 /* a suitable length */ const char *Curl_strerror(int err, char *buf, size_t buflen); -#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(_WIN32) || defined(_WIN32_WCE) const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen); #endif #ifdef USE_WINDOWS_SSPI diff --git a/lib/system_win32.c b/lib/system_win32.c index 0cdaf3b2f..9408d026b 100644 --- a/lib/system_win32.c +++ b/lib/system_win32.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if defined(WIN32) +#if defined(_WIN32) #include #include "system_win32.h" @@ -238,4 +238,4 @@ HMODULE Curl_load_library(LPCTSTR filename) #endif } -#endif /* WIN32 */ +#endif /* _WIN32 */ diff --git a/lib/system_win32.h b/lib/system_win32.h index 6482643fa..256676668 100644 --- a/lib/system_win32.h +++ b/lib/system_win32.h @@ -26,7 +26,7 @@ #include "curl_setup.h" -#if defined(WIN32) +#if defined(_WIN32) extern LARGE_INTEGER Curl_freq; extern bool Curl_isVistaOrGreater; @@ -42,8 +42,8 @@ extern IF_NAMETOINDEX_FN Curl_if_nametoindex; /* This is used to dynamically load DLLs */ HMODULE Curl_load_library(LPCTSTR filename); -#else /* WIN32 */ +#else /* _WIN32 */ #define Curl_win32_init(x) CURLE_OK -#endif /* !WIN32 */ +#endif /* !_WIN32 */ #endif /* HEADER_CURL_SYSTEM_WIN32_H */ diff --git a/lib/tftp.c b/lib/tftp.c index e78140d52..663015502 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -70,8 +70,6 @@ /* RFC2348 allows the block size to be negotiated */ #define TFTP_BLKSIZE_DEFAULT 512 -#define TFTP_BLKSIZE_MIN 8 -#define TFTP_BLKSIZE_MAX 65464 #define TFTP_OPTION_BLKSIZE "blksize" /* from RFC2349: */ @@ -978,11 +976,9 @@ static CURLcode tftp_connect(struct Curl_easy *data, bool *done) return CURLE_OUT_OF_MEMORY; /* alloc pkt buffers based on specified blksize */ - if(data->set.tftp_blksize) { + if(data->set.tftp_blksize) + /* range checked when set */ blksize = (int)data->set.tftp_blksize; - if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN) - return CURLE_TFTP_ILLEGAL; - } need_blksize = blksize; /* default size is the fallback when no OACK is received */ @@ -1107,7 +1103,6 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; struct tftp_state_data *state = conn->proto.tftpc; - struct SingleRequest *k = &data->req; /* Receive the packet */ fromlen = sizeof(fromaddr); @@ -1141,11 +1136,6 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)state->rpacket.data + 4, state->rbytes-4); - if(!result) { - k->bytecount += state->rbytes-4; - result = Curl_pgrsSetDownloadCounter(data, - (curl_off_t) k->bytecount); - } if(result) { tftp_state_machine(state, TFTP_EVENT_ERROR); return result; diff --git a/lib/tftp.h b/lib/tftp.h index 5d2d5da61..12404bf6d 100644 --- a/lib/tftp.h +++ b/lib/tftp.h @@ -25,6 +25,9 @@ ***************************************************************************/ #ifndef CURL_DISABLE_TFTP extern const struct Curl_handler Curl_handler_tftp; + +#define TFTP_BLKSIZE_MIN 8 +#define TFTP_BLKSIZE_MAX 65464 #endif #endif /* HEADER_CURL_TFTP_H */ diff --git a/lib/timediff.c b/lib/timediff.c index 1b762bbd3..d0824d144 100644 --- a/lib/timediff.c +++ b/lib/timediff.c @@ -53,7 +53,7 @@ struct timeval *curlx_mstotv(struct timeval *tv, timediff_t ms) #endif tv->tv_sec = (time_t)tv_sec; tv->tv_usec = (suseconds_t)tv_usec; -#elif defined(WIN32) /* maybe also others in the future */ +#elif defined(_WIN32) /* maybe also others in the future */ #if TIMEDIFF_T_MAX > LONG_MAX /* tv_sec overflow check on Windows there we know it is long */ if(tv_sec > LONG_MAX) diff --git a/lib/timeval.c b/lib/timeval.c index 026d9d17c..5a6727cbc 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -24,11 +24,10 @@ #include "timeval.h" -#if defined(WIN32) && !defined(MSDOS) +#if defined(_WIN32) -/* set in win32_init() */ -extern LARGE_INTEGER Curl_freq; -extern bool Curl_isVistaOrGreater; +#include +#include "system_win32.h" /* In case of bug fix this function has a counterpart in tool_util.c */ struct curltime Curl_now(void) diff --git a/lib/transfer.c b/lib/transfer.c index 6886764f4..96f1fde75 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -163,9 +163,9 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, { size_t buffersize = bytes; size_t nread; - curl_read_callback readfunc = NULL; void *extra_data = NULL; + int eof_index = 0; #ifndef CURL_DISABLE_HTTP if(data->state.trailers_state == TRAILERS_INITIALIZED) { @@ -223,6 +223,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, */ readfunc = trailers_read; extra_data = (void *)data; + eof_index = 1; } else #endif @@ -231,10 +232,15 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, extra_data = data->state.in; } - Curl_set_in_callback(data, true); - nread = readfunc(data->req.upload_fromhere, 1, - buffersize, extra_data); - Curl_set_in_callback(data, false); + if(!data->req.fread_eof[eof_index]) { + Curl_set_in_callback(data, true); + nread = readfunc(data->req.upload_fromhere, 1, buffersize, extra_data); + Curl_set_in_callback(data, false); + /* make sure the callback is not called again after EOF */ + data->req.fread_eof[eof_index] = !nread; + } + else + nread = 0; if(nread == CURL_READFUNC_ABORT) { failf(data, "operation aborted by callback"); @@ -422,16 +428,15 @@ static CURLcode readwrite_data(struct Curl_easy *data, bool *comeback) { CURLcode result = CURLE_OK; - ssize_t nread; /* number of bytes read */ - size_t excess = 0; /* excess bytes read */ - bool readmore = FALSE; /* used by RTP to signal for more data */ + char *buf; + size_t blen; + size_t consumed; int maxloops = 100; curl_off_t max_recv = data->set.max_recv_speed? data->set.max_recv_speed : CURL_OFF_T_MAX; - char *buf = data->state.buffer; bool data_eof_handled = FALSE; - DEBUGASSERT(buf); + DEBUGASSERT(data->state.buffer); *done = FALSE; *comeback = FALSE; @@ -439,8 +444,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, read or we get a CURLE_AGAIN */ do { bool is_empty_data = FALSE; - size_t buffersize = data->set.buffer_size; - size_t bytestoread = buffersize; + size_t bytestoread = data->set.buffer_size; /* For HTTP/2 and HTTP/3, read data without caring about the content length. This is safe because body in HTTP/2 is always segmented thanks to its framing layer. Meanwhile, we have to call Curl_read @@ -449,31 +453,38 @@ static CURLcode readwrite_data(struct Curl_easy *data, bool is_http3 = Curl_conn_is_http3(data, conn, FIRSTSOCKET); data_eof_handled = is_http3 || Curl_conn_is_http2(data, conn, FIRSTSOCKET); - if(!data_eof_handled && k->size != -1 && !k->header) { - /* make sure we don't read too much */ + /* Each loop iteration starts with a fresh buffer and handles + * all data read into it. */ + buf = data->state.buffer; + blen = 0; + + /* If we are reading BODY data and the connection does NOT handle EOF + * and we know the size of the BODY data, limit the read amount */ + if(!k->header && !data_eof_handled && k->size != -1) { curl_off_t totalleft = k->size - k->bytecount; - if(totalleft < (curl_off_t)bytestoread) + if(totalleft <= 0) + bytestoread = 0; + else if(totalleft < (curl_off_t)bytestoread) bytestoread = (size_t)totalleft; } if(bytestoread) { /* receive data from the network! */ + ssize_t nread; /* number of bytes read */ result = Curl_read(data, conn->sockfd, buf, bytestoread, &nread); - - /* read would've blocked */ if(CURLE_AGAIN == result) { result = CURLE_OK; break; /* get out of loop */ } - - if(result>0) + else if(result) goto out; + DEBUGASSERT(nread >= 0); + blen = (size_t)nread; } else { /* read nothing but since we wanted nothing we consider this an OK situation to proceed from */ DEBUGF(infof(data, "readwrite_data: we're done")); - nread = 0; } if(!k->bytecount) { @@ -485,12 +496,17 @@ static CURLcode readwrite_data(struct Curl_easy *data, *didwhat |= KEEP_RECV; /* indicates data of zero size, i.e. empty file */ - is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE; - - if(0 < nread || is_empty_data) { - buf[nread] = 0; + is_empty_data = ((blen == 0) && (k->bodywrites == 0)) ? TRUE : FALSE; + + if(0 < blen || is_empty_data) { + /* data->state.buffer is allocated 1 byte larger than + * data->set.buffer_size admits. *wink* */ + /* TODO: we should really not rely on this being 0-terminated, since + * the actual data read might contain 0s. */ + buf[blen] = 0; } - if(!nread) { + + if(!blen) { /* if we receive 0 or less here, either the data transfer is done or the server closed the connection and we bail out from this! */ if(data_eof_handled) @@ -502,48 +518,70 @@ static CURLcode readwrite_data(struct Curl_easy *data, break; } - /* Default buffer to use when we write the buffer, it may be changed - in the flow below before the actual storing is done. */ - k->str = buf; - if(conn->handler->readwrite) { - result = conn->handler->readwrite(data, conn, &nread, &readmore); + bool readmore = FALSE; /* indicates data is incomplete, need more */ + consumed = 0; + result = conn->handler->readwrite(data, conn, buf, blen, + &consumed, &readmore); if(result) goto out; if(readmore) break; + buf += consumed; + blen -= consumed; + if(k->download_done) { + /* We've stopped dealing with input, get out of the do-while loop */ + if(blen > 0) { + infof(data, + "Excess found:" + " excess = %zu" + " url = %s (zero-length body)", + blen, data->state.up.path); + } + + /* we make sure that this socket isn't read more now */ + k->keepon &= ~KEEP_RECV; + break; + } } #ifndef CURL_DISABLE_HTTP /* Since this is a two-state thing, we check if we are parsing headers at the moment or not. */ if(k->header) { - /* we are in parse-the-header-mode */ - bool stop_reading = FALSE; - result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading); + consumed = 0; + result = Curl_http_readwrite_headers(data, conn, buf, blen, &consumed); if(result) goto out; + buf += consumed; + blen -= consumed; if(conn->handler->readwrite && - (k->maxdownload <= 0 && nread > 0)) { - result = conn->handler->readwrite(data, conn, &nread, &readmore); + (k->maxdownload <= 0 && blen > 0)) { + bool readmore = FALSE; /* indicates data is incomplete, need more */ + consumed = 0; + result = conn->handler->readwrite(data, conn, buf, blen, + &consumed, &readmore); if(result) goto out; if(readmore) break; + buf += consumed; + blen -= consumed; } - if(stop_reading) { + if(k->download_done) { /* We've stopped dealing with input, get out of the do-while loop */ - - if(nread > 0) { + if(blen > 0) { infof(data, "Excess found:" - " excess = %zd" + " excess = %zu" " url = %s (zero-length body)", - nread, data->state.up.path); + blen, data->state.up.path); } + /* we make sure that this socket isn't read more now */ + k->keepon &= ~KEEP_RECV; break; } } @@ -553,11 +591,13 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* This is not an 'else if' since it may be a rest from the header parsing, where the beginning of the buffer is headers and the end is non-headers. */ - if(!k->header && (nread > 0 || is_empty_data)) { + if(!k->header && (blen > 0 || is_empty_data)) { - if(data->req.no_body) { + if(data->req.no_body && blen > 0) { /* data arrives although we want none, bail out */ streamclose(conn, "ignoring body"); + DEBUGF(infof(data, "did not want a BODY, but seeing %zu bytes", + blen)); *done = TRUE; result = CURLE_WEIRD_SERVER_REPLY; goto out; @@ -576,34 +616,18 @@ static CURLcode readwrite_data(struct Curl_easy *data, } /* this is the first time we write a body part */ #endif /* CURL_DISABLE_HTTP */ - k->bodywrites++; - - /* pass data to the debug function before it gets "dechunked" */ - if(data->set.verbose) { - if(k->badheader) { - Curl_debug(data, CURLINFO_DATA_IN, - Curl_dyn_ptr(&data->state.headerb), - Curl_dyn_len(&data->state.headerb)); - if(k->badheader == HEADER_PARTHEADER) - Curl_debug(data, CURLINFO_DATA_IN, - k->str, (size_t)nread); - } - else - Curl_debug(data, CURLINFO_DATA_IN, - k->str, (size_t)nread); - } - #ifndef CURL_DISABLE_HTTP if(k->chunk) { /* * Here comes a chunked transfer flying and we need to decode this * properly. While the name says read, this function both reads - * and writes away the data. The returned 'nread' holds the number - * of actual data it wrote to the client. + * and writes away the data. */ CURLcode extra; - CHUNKcode res = - Curl_httpchunk_read(data, k->str, nread, &nread, &extra); + CHUNKcode res; + + consumed = 0; + res = Curl_httpchunk_read(data, buf, blen, &consumed, &extra); if(CHUNKE_OK < res) { if(CHUNKE_PASSTHRU_ERROR == res) { @@ -615,9 +639,14 @@ static CURLcode readwrite_data(struct Curl_easy *data, result = CURLE_RECV_ERROR; goto out; } - if(CHUNKE_STOP == res) { + + buf += consumed; + blen -= consumed; + if(CHUNKE_STOP == res) { /* we're done reading chunks! */ k->keepon &= ~KEEP_RECV; /* read no more */ + /* chunks read successfully, download is complete */ + k->download_done = TRUE; /* N number of bytes at the end of the str buffer that weren't written to the client. */ @@ -631,117 +660,57 @@ static CURLcode readwrite_data(struct Curl_easy *data, } #endif /* CURL_DISABLE_HTTP */ - /* Account for body content stored in the header buffer */ - if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) { - size_t headlen = Curl_dyn_len(&data->state.headerb); - DEBUGF(infof(data, "Increasing bytecount by %zu", headlen)); - k->bytecount += headlen; - } - - if((-1 != k->maxdownload) && - (k->bytecount + nread >= k->maxdownload)) { + max_recv -= blen; - excess = (size_t)(k->bytecount + nread - k->maxdownload); - if(excess > 0 && !k->ignorebody) { - infof(data, - "Excess found in a read:" - " excess = %zu" - ", size = %" CURL_FORMAT_CURL_OFF_T - ", maxdownload = %" CURL_FORMAT_CURL_OFF_T - ", bytecount = %" CURL_FORMAT_CURL_OFF_T, - excess, k->size, k->maxdownload, k->bytecount); - connclose(conn, "excess found in a read"); - } - - nread = (ssize_t) (k->maxdownload - k->bytecount); - if(nread < 0) /* this should be unusual */ - nread = 0; - - /* HTTP/3 over QUIC should keep reading until QUIC connection - is closed. In contrast to HTTP/2 which can stop reading - from TCP connection, HTTP/3 over QUIC needs ACK from server - to ensure stream closure. It should keep reading. */ - if(!is_http3) { - k->keepon &= ~KEEP_RECV; /* we're done reading */ - } - } - - k->bytecount += nread; - max_recv -= nread; - - result = Curl_pgrsSetDownloadCounter(data, k->bytecount); - if(result) - goto out; - - if(!k->chunk && (nread || k->badheader || is_empty_data)) { + if(!k->chunk && (blen || k->badheader || is_empty_data)) { /* If this is chunky transfer, it was already written */ - if(k->badheader && !k->ignorebody) { + if(k->badheader) { /* we parsed a piece of data wrongly assuming it was a header and now we output it as body instead */ size_t headlen = Curl_dyn_len(&data->state.headerb); /* Don't let excess data pollute body writes */ - if(k->maxdownload == -1 || (curl_off_t)headlen <= k->maxdownload) - result = Curl_client_write(data, CLIENTWRITE_BODY, - Curl_dyn_ptr(&data->state.headerb), - headlen); - else - result = Curl_client_write(data, CLIENTWRITE_BODY, - Curl_dyn_ptr(&data->state.headerb), - (size_t)k->maxdownload); + if(k->maxdownload != -1 && (curl_off_t)headlen > k->maxdownload) + headlen = (size_t)k->maxdownload; + result = Curl_client_write(data, CLIENTWRITE_BODY, + Curl_dyn_ptr(&data->state.headerb), + headlen); if(result) goto out; } - if(k->badheader < HEADER_ALLBAD) { - /* This switch handles various content encodings. If there's an - error here, be sure to check over the almost identical code - in http_chunks.c. - Make sure that ALL_CONTENT_ENCODINGS contains all the - encodings handled here. */ - if(!k->ignorebody && nread) { + + if(blen) { #ifndef CURL_DISABLE_POP3 - if(conn->handler->protocol & PROTO_FAMILY_POP3) - result = Curl_pop3_write(data, k->str, nread); - else -#endif /* CURL_DISABLE_POP3 */ - result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, - nread); + if(conn->handler->protocol & PROTO_FAMILY_POP3) { + result = k->ignorebody? CURLE_OK : + Curl_pop3_write(data, buf, blen); } + else +#endif /* CURL_DISABLE_POP3 */ + result = Curl_client_write(data, CLIENTWRITE_BODY, buf, blen); } - k->badheader = HEADER_NORMAL; /* taken care of now */ + k->badheader = FALSE; /* taken care of now */ if(result) goto out; } - } /* if(!header and data to read) */ - - if(conn->handler->readwrite && excess) { - /* Parse the excess data */ - k->str += nread; - - if(&k->str[excess] > &buf[data->set.buffer_size]) { - /* the excess amount was too excessive(!), make sure - it doesn't read out of buffer */ - excess = &buf[data->set.buffer_size] - k->str; + if(k->download_done && !is_http3) { + /* HTTP/3 over QUIC should keep reading until QUIC connection + is closed. In contrast to HTTP/2 which can stop reading + from TCP connection, HTTP/3 over QUIC needs ACK from server + to ensure stream closure. It should keep reading. */ + k->keepon &= ~KEEP_RECV; /* we're done reading */ } - nread = (ssize_t)excess; - - result = conn->handler->readwrite(data, conn, &nread, &readmore); - if(result) - goto out; - - if(readmore) - k->keepon |= KEEP_RECV; /* we're not done reading */ - break; - } + } /* if(!header and data to read) */ if(is_empty_data) { /* if we received nothing, the server closed the connection and we are done */ k->keepon &= ~KEEP_RECV; + k->download_done = TRUE; } if((k->keepon & KEEP_RECV_PAUSE) || !(k->keepon & KEEP_RECV)) { @@ -764,6 +733,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, on from our side, we need to stop that immediately. */ infof(data, "we are done reading and this is set to close, stop send"); k->keepon &= ~KEEP_SEND; /* no writing anymore either */ + k->keepon &= ~KEEP_SEND_PAUSE; /* no pausing anymore either */ } out: @@ -783,7 +753,7 @@ CURLcode Curl_done_sending(struct Curl_easy *data, return CURLE_OK; } -#if defined(WIN32) && defined(USE_WINSOCK) +#if defined(_WIN32) && defined(USE_WINSOCK) #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B #endif @@ -977,7 +947,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, if(result) return result; -#if defined(WIN32) && defined(USE_WINSOCK) +#if defined(_WIN32) && defined(USE_WINSOCK) { struct curltime n = Curl_now(); if(Curl_timediff(n, k->last_sndbuf_update) > 1000) { @@ -1430,8 +1400,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) return CURLE_OUT_OF_MEMORY; } wc = data->wildcard; - if((wc->state < CURLWC_INIT) || - (wc->state >= CURLWC_CLEAN)) { + if(wc->state < CURLWC_INIT) { if(wc->ftpwc) wc->dtor(wc->ftpwc); Curl_safefree(wc->pattern); @@ -1635,7 +1604,7 @@ CURLcode Curl_follow(struct Curl_easy *data, return Curl_uc_to_curlcode(uc); } - p = Curl_builtin_scheme(scheme, CURL_ZERO_TERMINATED); + p = Curl_get_scheme_handler(scheme); if(p && (p->protocol != data->info.conn_protocol)) { infof(data, "Clear auth, redirects scheme from %s to %s", data->info.conn_scheme, scheme); diff --git a/lib/url.c b/lib/url.c index 61dad442d..b81785fe2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -168,130 +168,6 @@ static curl_prot_t get_protocol_family(const struct Curl_handler *h) return h->family; } - -/* - * Protocol table. Schemes (roughly) in 2019 popularity order: - * - * HTTPS, HTTP, FTP, FTPS, SFTP, FILE, SCP, SMTP, LDAP, IMAPS, TELNET, IMAP, - * LDAPS, SMTPS, TFTP, SMB, POP3, GOPHER POP3S, RTSP, RTMP, SMBS, DICT - */ -static const struct Curl_handler * const protocols[] = { - -#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) - &Curl_handler_https, -#endif - -#ifndef CURL_DISABLE_HTTP - &Curl_handler_http, -#endif - -#ifdef USE_WEBSOCKETS -#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) - &Curl_handler_wss, -#endif - -#ifndef CURL_DISABLE_HTTP - &Curl_handler_ws, -#endif -#endif - -#ifndef CURL_DISABLE_FTP - &Curl_handler_ftp, -#endif - -#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) - &Curl_handler_ftps, -#endif - -#if defined(USE_SSH) - &Curl_handler_sftp, -#endif - -#ifndef CURL_DISABLE_FILE - &Curl_handler_file, -#endif - -#if defined(USE_SSH) && !defined(USE_WOLFSSH) - &Curl_handler_scp, -#endif - -#ifndef CURL_DISABLE_SMTP - &Curl_handler_smtp, -#ifdef USE_SSL - &Curl_handler_smtps, -#endif -#endif - -#ifndef CURL_DISABLE_LDAP - &Curl_handler_ldap, -#if !defined(CURL_DISABLE_LDAPS) && \ - ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ - (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) - &Curl_handler_ldaps, -#endif -#endif - -#ifndef CURL_DISABLE_IMAP - &Curl_handler_imap, -#ifdef USE_SSL - &Curl_handler_imaps, -#endif -#endif - -#ifndef CURL_DISABLE_TELNET - &Curl_handler_telnet, -#endif - -#ifndef CURL_DISABLE_TFTP - &Curl_handler_tftp, -#endif - -#ifndef CURL_DISABLE_POP3 - &Curl_handler_pop3, -#ifdef USE_SSL - &Curl_handler_pop3s, -#endif -#endif - -#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ - (SIZEOF_CURL_OFF_T > 4) - &Curl_handler_smb, -#ifdef USE_SSL - &Curl_handler_smbs, -#endif -#endif - -#ifndef CURL_DISABLE_RTSP - &Curl_handler_rtsp, -#endif - -#ifndef CURL_DISABLE_MQTT - &Curl_handler_mqtt, -#endif - -#ifndef CURL_DISABLE_GOPHER - &Curl_handler_gopher, -#ifdef USE_SSL - &Curl_handler_gophers, -#endif -#endif - -#ifdef USE_LIBRTMP - &Curl_handler_rtmp, - &Curl_handler_rtmpt, - &Curl_handler_rtmpe, - &Curl_handler_rtmpte, - &Curl_handler_rtmps, - &Curl_handler_rtmpts, -#endif - -#ifndef CURL_DISABLE_DICT - &Curl_handler_dict, -#endif - - (struct Curl_handler *) NULL -}; - void Curl_freeset(struct Curl_easy *data) { /* Free all dynamic strings stored in the data->set substructure. */ @@ -320,8 +196,8 @@ void Curl_freeset(struct Curl_easy *data) Curl_mime_cleanpart(&data->set.mimepost); #ifndef CURL_DISABLE_COOKIES - curl_slist_free_all(data->set.cookielist); - data->set.cookielist = NULL; + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; #endif } @@ -363,16 +239,18 @@ CURLcode Curl_close(struct Curl_easy **datap) /* 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->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->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) { - /* 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; + if(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; + } } data->magic = 0; /* force a clear AFTER the possibly enforced removal from @@ -412,7 +290,7 @@ CURLcode Curl_close(struct Curl_easy **datap) #ifndef CURL_DISABLE_HSTS if(!data->share || !data->share->hsts) Curl_hsts_cleanup(&data->hsts); - curl_slist_free_all(data->set.hstslist); /* clean up list */ + curl_slist_free_all(data->state.hstslist); /* clean up list */ #endif #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) Curl_http_auth_cleanup_digest(data); @@ -420,10 +298,6 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_safefree(data->info.contenttype); Curl_safefree(data->info.wouldredirect); - /* this destroys the channel and we cannot use it anymore after this */ - Curl_resolver_cancel(data); - Curl_resolver_cleanup(data->state.async.resolver); - data_priority_cleanup(data); /* No longer a dirty share, if it exists */ @@ -457,8 +331,8 @@ CURLcode Curl_close(struct Curl_easy **datap) } #endif - Curl_mime_cleanpart(data->state.formp); #ifndef CURL_DISABLE_HTTP + Curl_mime_cleanpart(data->state.formp); Curl_safefree(data->state.formp); #endif @@ -530,26 +404,16 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) Curl_mime_initpart(&set->mimepost); - /* - * libcurl 7.10 introduced SSL verification *by default*! This needs to be - * switched off unless wanted. - */ + Curl_ssl_easy_config_init(data); #ifndef CURL_DISABLE_DOH set->doh_verifyhost = TRUE; set->doh_verifypeer = TRUE; #endif - set->ssl.primary.verifypeer = TRUE; - set->ssl.primary.verifyhost = TRUE; #ifdef USE_SSH /* defaults to any auth type */ set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; set->new_directory_perms = 0755; /* Default permissions */ #endif - set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by - default */ -#ifndef CURL_DISABLE_PROXY - set->proxy_ssl = set->ssl; -#endif set->new_file_perms = 0644; /* Default permissions */ set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL; @@ -650,13 +514,6 @@ CURLcode Curl_open(struct Curl_easy **curl) data->magic = CURLEASY_MAGIC_NUMBER; - result = Curl_resolver_init(data, &data->state.async.resolver); - if(result) { - DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); - free(data); - return result; - } - result = Curl_init_userdefined(data); if(!result) { Curl_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER); @@ -673,7 +530,6 @@ CURLcode Curl_open(struct Curl_easy **curl) } if(result) { - Curl_resolver_cleanup(data->state.async.resolver); Curl_dyn_free(&data->state.headerb); Curl_freeset(data); free(data); @@ -707,6 +563,7 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn) Curl_conn_cf_discard_all(data, conn, (int)i); } + Curl_resolver_cleanup(conn->resolve_async.resolver); Curl_free_idnconverted_hostname(&conn->host); Curl_free_idnconverted_hostname(&conn->conn_to_host); #ifndef CURL_DISABLE_PROXY @@ -718,7 +575,6 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn) Curl_safefree(conn->socks_proxy.passwd); Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ - Curl_free_primary_ssl_config(&conn->proxy_ssl_config); #endif Curl_safefree(conn->user); Curl_safefree(conn->passwd); @@ -733,7 +589,7 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn) Curl_safefree(conn->hostname_resolve); Curl_safefree(conn->secondaryhostname); Curl_safefree(conn->localdev); - Curl_free_primary_ssl_config(&conn->ssl_config); + Curl_ssl_conn_config_cleanup(conn); #ifdef USE_UNIX_SOCKETS Curl_safefree(conn->unix_domain_socket); @@ -807,6 +663,7 @@ void Curl_disconnect(struct Curl_easy *data, conn->handler->disconnect(data, conn, dead_connection); conn_shutdown(data); + Curl_resolver_cancel(data); /* detach it again */ Curl_detach_connection(data); @@ -1059,11 +916,11 @@ ConnectionExists(struct Curl_easy *data, bool *force_reuse, bool *waitpipe) { - struct connectdata *check; - struct connectdata *chosen = 0; + struct connectdata *chosen = NULL; bool foundPendingCandidate = FALSE; - bool canmultiplex = IsMultiplexingPossible(data, needle); + bool canmultiplex = FALSE; struct connectbundle *bundle; + struct Curl_llist_element *curr; #ifdef USE_NTLM bool wantNTLMhttp = ((data->state.authhost.want & @@ -1082,395 +939,368 @@ ConnectionExists(struct Curl_easy *data, bool h2upgrade = (data->state.httpwant == CURL_HTTP_VERSION_2_0) && (needle->handler->protocol & CURLPROTO_HTTP); + *usethis = NULL; *force_reuse = FALSE; *waitpipe = FALSE; /* Look up the bundle with all the connections to this particular host. Locks the connection cache, beware of early returns! */ bundle = Curl_conncache_find_bundle(data, needle, data->state.conn_cache); - if(bundle) { - /* Max pipe length is zero (unlimited) for multiplexed connections */ - struct Curl_llist_element *curr; - - infof(data, "Found bundle for host: %p [%s]", - (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? - "can multiplex" : "serially")); - - /* We can't multiplex if we don't know anything about the server */ - if(canmultiplex) { - if(bundle->multiuse == BUNDLE_UNKNOWN) { - if(data->set.pipewait) { - infof(data, "Server doesn't support multiplex yet, wait"); - *waitpipe = TRUE; - CONNCACHE_UNLOCK(data); - return FALSE; /* no reuse */ - } - - infof(data, "Server doesn't support multiplex (yet)"); - canmultiplex = FALSE; + if(!bundle) { + CONNCACHE_UNLOCK(data); + return FALSE; + } + infof(data, "Found bundle for host: %p [%s]", + (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? + "can multiplex" : "serially")); + + /* We can only multiplex iff the transfer allows it AND we know + * that the server we want to talk to supports it as well. */ + canmultiplex = FALSE; + if(IsMultiplexingPossible(data, needle)) { + if(bundle->multiuse == BUNDLE_UNKNOWN) { + if(data->set.pipewait) { + infof(data, "Server doesn't support multiplex yet, wait"); + *waitpipe = TRUE; + CONNCACHE_UNLOCK(data); + return FALSE; /* no reuse */ } - if((bundle->multiuse == BUNDLE_MULTIPLEX) && - !Curl_multiplex_wanted(data->multi)) { + infof(data, "Server doesn't support multiplex (yet)"); + } + else if(bundle->multiuse == BUNDLE_MULTIPLEX) { + if(Curl_multiplex_wanted(data->multi)) + canmultiplex = TRUE; + else infof(data, "Could multiplex, but not asked to"); - canmultiplex = FALSE; - } - if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { - infof(data, "Can not multiplex, even if we wanted to"); - canmultiplex = FALSE; - } } + else if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { + infof(data, "Can not multiplex, even if we wanted to"); + } + } - curr = bundle->conn_list.head; - while(curr) { - bool match = FALSE; - size_t multiplexed = 0; + curr = bundle->conn_list.head; + while(curr) { + struct connectdata *check = curr->ptr; + /* Get next node now. We might remove a dead `check` connection which + * would invalidate `curr` as well. */ + curr = curr->next; - /* - * Note that if we use an HTTP proxy in normal mode (no tunneling), we - * check connections to that proxy and not to the actual remote server. - */ - check = curr->ptr; - curr = curr->next; + /* Note that if we use an HTTP proxy in normal mode (no tunneling), we + * check connections to that proxy and not to the actual remote server. + */ + if(check->connect_only || check->bits.close) + /* connect-only or to-be-closed connections will not be reused */ + continue; - if(check->connect_only || check->bits.close) - /* connect-only or to-be-closed connections will not be reused */ - continue; + if(data->set.ipver != CURL_IPRESOLVE_WHATEVER + && data->set.ipver != check->ip_version) { + /* skip because the connection is not via the requested IP version */ + continue; + } - if(extract_if_dead(check, data)) { - /* disconnect it */ - Curl_disconnect(data, check, TRUE); + if(!canmultiplex) { + if(Curl_resolver_asynch() && + /* primary_ip[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't reuse this connection */ + !check->primary_ip[0]) continue; - } + } - if(data->set.ipver != CURL_IPRESOLVE_WHATEVER - && data->set.ipver != check->ip_version) { - /* skip because the connection is not via the requested IP version */ + if(CONN_INUSE(check)) { + if(!canmultiplex) { + /* transfer can't be multiplexed and check is in use */ continue; } - - if(bundle->multiuse == BUNDLE_MULTIPLEX) - multiplexed = CONN_INUSE(check); - - if(!canmultiplex) { - if(multiplexed) { - /* can only happen within multi handles, and means that another easy - handle is using this connection */ - continue; - } - - if(Curl_resolver_asynch() && - /* primary_ip[0] is NUL only if the resolving of the name hasn't - completed yet and until then we don't reuse this connection */ - !check->primary_ip[0]) + else { + /* Could multiplex, but not when check belongs to another multi */ + struct Curl_llist_element *e = check->easyq.head; + struct Curl_easy *entry = e->ptr; + if(entry->multi != data->multi) continue; } + } - if(!Curl_conn_is_connected(check, FIRSTSOCKET)) { - foundPendingCandidate = TRUE; - /* Don't pick a connection that hasn't connected yet */ - infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T - " isn't open enough, can't reuse", check->connection_id); - continue; - } + if(!Curl_conn_is_connected(check, FIRSTSOCKET)) { + foundPendingCandidate = TRUE; + /* Don't pick a connection that hasn't connected yet */ + infof(data, "Connection #%" CURL_FORMAT_CURL_OFF_T + " isn't open enough, can't reuse", check->connection_id); + continue; + } + + /* `check` is connected. if it is in use and does not support multiplex, + * we cannot use it. */ + if(!check->bits.multiplex && CONN_INUSE(check)) + continue; #ifdef USE_UNIX_SOCKETS - if(needle->unix_domain_socket) { - if(!check->unix_domain_socket) - continue; - if(strcmp(needle->unix_domain_socket, check->unix_domain_socket)) - continue; - if(needle->bits.abstract_unix_socket != - check->bits.abstract_unix_socket) - continue; - } - else if(check->unix_domain_socket) + if(needle->unix_domain_socket) { + if(!check->unix_domain_socket) continue; -#endif - - if((needle->handler->flags&PROTOPT_SSL) != - (check->handler->flags&PROTOPT_SSL)) - /* don't do mixed SSL and non-SSL connections */ - if(get_protocol_family(check->handler) != - needle->handler->protocol || !check->bits.tls_upgraded) - /* except protocols that have been upgraded via TLS */ - continue; - -#ifndef CURL_DISABLE_PROXY - if(needle->bits.httpproxy != check->bits.httpproxy || - needle->bits.socksproxy != check->bits.socksproxy) + if(strcmp(needle->unix_domain_socket, check->unix_domain_socket)) continue; - - if(needle->bits.socksproxy && - !socks_proxy_info_matches(&needle->socks_proxy, - &check->socks_proxy)) + if(needle->bits.abstract_unix_socket != + check->bits.abstract_unix_socket) continue; + } + else if(check->unix_domain_socket) + continue; #endif - if(needle->bits.conn_to_host != check->bits.conn_to_host) - /* don't mix connections that use the "connect to host" feature and - * connections that don't use this feature */ - continue; - if(needle->bits.conn_to_port != check->bits.conn_to_port) - /* don't mix connections that use the "connect to port" feature and - * connections that don't use this feature */ + if((needle->handler->flags&PROTOPT_SSL) != + (check->handler->flags&PROTOPT_SSL)) + /* don't do mixed SSL and non-SSL connections */ + if(get_protocol_family(check->handler) != + needle->handler->protocol || !check->bits.tls_upgraded) + /* except protocols that have been upgraded via TLS */ continue; -#ifndef CURL_DISABLE_PROXY - if(needle->bits.httpproxy) { - if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy)) - continue; + if(needle->bits.conn_to_host != check->bits.conn_to_host) + /* don't mix connections that use the "connect to host" feature and + * connections that don't use this feature */ + continue; - if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy) - continue; + if(needle->bits.conn_to_port != check->bits.conn_to_port) + /* don't mix connections that use the "connect to port" feature and + * connections that don't use this feature */ + continue; - if(IS_HTTPS_PROXY(needle->http_proxy.proxytype)) { - /* use https proxy */ - if(needle->http_proxy.proxytype != - check->http_proxy.proxytype) - continue; - else if(needle->handler->flags&PROTOPT_SSL) { - /* use double layer ssl */ - if(!Curl_ssl_config_matches(&needle->proxy_ssl_config, - &check->proxy_ssl_config)) - continue; - } - else if(!Curl_ssl_config_matches(&needle->ssl_config, - &check->ssl_config)) - continue; - } - } -#endif +#ifndef CURL_DISABLE_PROXY + if(needle->bits.httpproxy != check->bits.httpproxy || + needle->bits.socksproxy != check->bits.socksproxy) + continue; - if(h2upgrade && !check->httpversion && canmultiplex) { - if(data->set.pipewait) { - infof(data, "Server upgrade doesn't support multiplex yet, wait"); - *waitpipe = TRUE; - CONNCACHE_UNLOCK(data); - return FALSE; /* no reuse */ - } - infof(data, "Server upgrade cannot be used"); - continue; /* can't be used atm */ - } + if(needle->bits.socksproxy && + !socks_proxy_info_matches(&needle->socks_proxy, + &check->socks_proxy)) + continue; - if(!canmultiplex && CONN_INUSE(check)) - /* this request can't be multiplexed but the checked connection is - already in use so we skip it */ + if(needle->bits.httpproxy) { + if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy) continue; - if(CONN_INUSE(check)) { - /* Subject for multiplex use if 'checks' belongs to the same multi - handle as 'data' is. */ - struct Curl_llist_element *e = check->easyq.head; - struct Curl_easy *entry = e->ptr; - if(entry->multi != data->multi) - continue; - } + if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy)) + continue; - if(needle->localdev || needle->localport) { - /* If we are bound to a specific local end (IP+port), we must not - reuse a random other one, although if we didn't ask for a - particular one we can reuse one that was bound. - - This comparison is a bit rough and too strict. Since the input - parameters can be specified in numerous ways and still end up the - same it would take a lot of processing to make it really accurate. - Instead, this matching will assume that reuses of bound connections - will most likely also reuse the exact same binding parameters and - missing out a few edge cases shouldn't hurt anyone very much. - */ - if((check->localport != needle->localport) || - (check->localportrange != needle->localportrange) || - (needle->localdev && - (!check->localdev || strcmp(check->localdev, needle->localdev)))) + if(IS_HTTPS_PROXY(needle->http_proxy.proxytype)) { + /* https proxies come in different types, http/1.1, h2, ... */ + if(needle->http_proxy.proxytype != check->http_proxy.proxytype) continue; - } - - if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { - /* This protocol requires credentials per connection, - so verify that we're using the same name and password as well */ - if(Curl_timestrcmp(needle->user, check->user) || - Curl_timestrcmp(needle->passwd, check->passwd) || - Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) || - Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) { - /* one of them was different */ + /* match SSL config to proxy */ + if(!Curl_ssl_conn_config_match(data, check, TRUE)) { + DEBUGF(infof(data, + "Connection #%" CURL_FORMAT_CURL_OFF_T + " has different SSL proxy parameters, can't reuse", + check->connection_id)); continue; } + /* the SSL config to the server, which may apply here is checked + * further below */ } + } +#endif - /* GSS delegation differences do not actually affect every connection - and auth method, but this check takes precaution before efficiency */ - if(needle->gssapi_delegation != check->gssapi_delegation) + if(h2upgrade && !check->httpversion && canmultiplex) { + if(data->set.pipewait) { + infof(data, "Server upgrade doesn't support multiplex yet, wait"); + *waitpipe = TRUE; + CONNCACHE_UNLOCK(data); + return FALSE; /* no reuse */ + } + infof(data, "Server upgrade cannot be used"); + continue; /* can't be used atm */ + } + + if(needle->localdev || needle->localport) { + /* If we are bound to a specific local end (IP+port), we must not + reuse a random other one, although if we didn't ask for a + particular one we can reuse one that was bound. + + This comparison is a bit rough and too strict. Since the input + parameters can be specified in numerous ways and still end up the + same it would take a lot of processing to make it really accurate. + Instead, this matching will assume that reuses of bound connections + will most likely also reuse the exact same binding parameters and + missing out a few edge cases shouldn't hurt anyone very much. + */ + if((check->localport != needle->localport) || + (check->localportrange != needle->localportrange) || + (needle->localdev && + (!check->localdev || strcmp(check->localdev, needle->localdev)))) continue; + } - /* If multiplexing isn't enabled on the h2 connection and h1 is - explicitly requested, handle it: */ - if((needle->handler->protocol & PROTO_FAMILY_HTTP) && - (((check->httpversion >= 20) && - (data->state.httpwant < CURL_HTTP_VERSION_2_0)) - || ((check->httpversion >= 30) && - (data->state.httpwant < CURL_HTTP_VERSION_3)))) + if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { + /* This protocol requires credentials per connection, + so verify that we're using the same name and password as well */ + if(Curl_timestrcmp(needle->user, check->user) || + Curl_timestrcmp(needle->passwd, check->passwd) || + Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) || + Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) { + /* one of them was different */ continue; -#ifdef USE_SSH - else if(get_protocol_family(needle->handler) & PROTO_FAMILY_SSH) { - if(!ssh_config_matches(needle, check)) - continue; } + } + + /* GSS delegation differences do not actually affect every connection + and auth method, but this check takes precaution before efficiency */ + if(needle->gssapi_delegation != check->gssapi_delegation) + continue; + + /* If looking for HTTP and the HTTP version we want is less + * than the HTTP version of the check connection, continue looking */ + if((needle->handler->protocol & PROTO_FAMILY_HTTP) && + (((check->httpversion >= 20) && + (data->state.httpwant < CURL_HTTP_VERSION_2_0)) + || ((check->httpversion >= 30) && + (data->state.httpwant < CURL_HTTP_VERSION_3)))) + continue; +#ifdef USE_SSH + else if(get_protocol_family(needle->handler) & PROTO_FAMILY_SSH) { + if(!ssh_config_matches(needle, check)) + continue; + } #endif #ifndef CURL_DISABLE_FTP - else if(get_protocol_family(needle->handler) & PROTO_FAMILY_FTP) { - /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */ - if(Curl_timestrcmp(needle->proto.ftpc.account, - check->proto.ftpc.account) || - Curl_timestrcmp(needle->proto.ftpc.alternative_to_user, - check->proto.ftpc.alternative_to_user) || - (needle->proto.ftpc.use_ssl != check->proto.ftpc.use_ssl) || - (needle->proto.ftpc.ccc != check->proto.ftpc.ccc)) - continue; - } + else if(get_protocol_family(needle->handler) & PROTO_FAMILY_FTP) { + /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */ + if(Curl_timestrcmp(needle->proto.ftpc.account, + check->proto.ftpc.account) || + Curl_timestrcmp(needle->proto.ftpc.alternative_to_user, + check->proto.ftpc.alternative_to_user) || + (needle->proto.ftpc.use_ssl != check->proto.ftpc.use_ssl) || + (needle->proto.ftpc.ccc != check->proto.ftpc.ccc)) + continue; + } #endif - if((needle->handler->flags&PROTOPT_SSL) + /* Additional match requirements if talking TLS OR + * not talking to a HTTP proxy OR using a tunnel through a proxy */ + if((needle->handler->flags&PROTOPT_SSL) #ifndef CURL_DISABLE_PROXY - || !needle->bits.httpproxy || needle->bits.tunnel_proxy -#endif - ) { - /* The requested connection does not use an HTTP proxy or it uses SSL - or it is a non-SSL protocol tunneled or it is a non-SSL protocol - which is allowed to be upgraded via TLS */ - - if((strcasecompare(needle->handler->scheme, check->handler->scheme) || - (get_protocol_family(check->handler) == - needle->handler->protocol && check->bits.tls_upgraded)) && - (!needle->bits.conn_to_host || strcasecompare( - needle->conn_to_host.name, check->conn_to_host.name)) && - (!needle->bits.conn_to_port || - needle->conn_to_port == check->conn_to_port) && - strcasecompare(needle->host.name, check->host.name) && - needle->remote_port == check->remote_port) { - /* The schemes match or the protocol family is the same and the - previous connection was TLS upgraded, and the hostname and host - port match */ - if(needle->handler->flags & PROTOPT_SSL) { - /* This is a SSL connection so verify that we're using the same - SSL options as well */ - if(!Curl_ssl_config_matches(&needle->ssl_config, - &check->ssl_config)) { - DEBUGF(infof(data, - "Connection #%" CURL_FORMAT_CURL_OFF_T - " has different SSL parameters, can't reuse", - check->connection_id)); - continue; - } - } - match = TRUE; - } - } - else { - /* The requested connection is using the same HTTP proxy in normal - mode (no tunneling) */ - match = TRUE; + || !needle->bits.httpproxy || needle->bits.tunnel_proxy +#endif + ) { + /* Talking the same protocol scheme or a TLS upgraded protocol in the + * same protocol family? */ + if(!strcasecompare(needle->handler->scheme, check->handler->scheme) && + (get_protocol_family(check->handler) != + needle->handler->protocol || !check->bits.tls_upgraded)) + continue; + + /* If needle has "conn_to_*" set, check must match this */ + if((needle->bits.conn_to_host && !strcasecompare( + needle->conn_to_host.name, check->conn_to_host.name)) || + (needle->bits.conn_to_port && + needle->conn_to_port != check->conn_to_port)) + continue; + + /* hostname and port must match */ + if(!strcasecompare(needle->host.name, check->host.name) || + needle->remote_port != check->remote_port) + continue; + + /* If talking TLS, check needs to use the same SSL options. */ + if((needle->handler->flags & PROTOPT_SSL) && + !Curl_ssl_conn_config_match(data, check, FALSE)) { + DEBUGF(infof(data, + "Connection #%" CURL_FORMAT_CURL_OFF_T + " has different SSL parameters, can't reuse", + check->connection_id)); + continue; } + } - if(match) { #if defined(USE_NTLM) - /* If we are looking for an HTTP+NTLM connection, check if this is - already authenticating with the right credentials. If not, keep - looking so that we can reuse NTLM connections if - possible. (Especially we must not reuse the same connection if - partway through a handshake!) */ - if(wantNTLMhttp) { - if(Curl_timestrcmp(needle->user, check->user) || - Curl_timestrcmp(needle->passwd, check->passwd)) { - - /* we prefer a credential match, but this is at least a connection - that can be reused and "upgraded" to NTLM */ - if(check->http_ntlm_state == NTLMSTATE_NONE) - chosen = check; - continue; - } - } - else if(check->http_ntlm_state != NTLMSTATE_NONE) { - /* Connection is using NTLM auth but we don't want NTLM */ - continue; - } - -#ifndef CURL_DISABLE_PROXY - /* Same for Proxy NTLM authentication */ - if(wantProxyNTLMhttp) { - /* Both check->http_proxy.user and check->http_proxy.passwd can be - * NULL */ - if(!check->http_proxy.user || !check->http_proxy.passwd) - continue; - - if(Curl_timestrcmp(needle->http_proxy.user, - check->http_proxy.user) || - Curl_timestrcmp(needle->http_proxy.passwd, - check->http_proxy.passwd)) - continue; - } - else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { - /* Proxy connection is using NTLM auth but we don't want NTLM */ - continue; - } -#endif - if(wantNTLMhttp || wantProxyNTLMhttp) { - /* Credentials are already checked, we can use this connection */ + /* If we are looking for an HTTP+NTLM connection, check if this is + already authenticating with the right credentials. If not, keep + looking so that we can reuse NTLM connections if + possible. (Especially we must not reuse the same connection if + partway through a handshake!) */ + if(wantNTLMhttp) { + if(Curl_timestrcmp(needle->user, check->user) || + Curl_timestrcmp(needle->passwd, check->passwd)) { + + /* we prefer a credential match, but this is at least a connection + that can be reused and "upgraded" to NTLM */ + if(check->http_ntlm_state == NTLMSTATE_NONE) chosen = check; + continue; + } + } + else if(check->http_ntlm_state != NTLMSTATE_NONE) { + /* Connection is using NTLM auth but we don't want NTLM */ + continue; + } - if((wantNTLMhttp && - (check->http_ntlm_state != NTLMSTATE_NONE)) || - (wantProxyNTLMhttp && - (check->proxy_ntlm_state != NTLMSTATE_NONE))) { - /* We must use this connection, no other */ - *force_reuse = TRUE; - break; - } +#ifndef CURL_DISABLE_PROXY + /* Same for Proxy NTLM authentication */ + if(wantProxyNTLMhttp) { + /* Both check->http_proxy.user and check->http_proxy.passwd can be + * NULL */ + if(!check->http_proxy.user || !check->http_proxy.passwd) + continue; - /* Continue look up for a better connection */ - continue; - } + if(Curl_timestrcmp(needle->http_proxy.user, + check->http_proxy.user) || + Curl_timestrcmp(needle->http_proxy.passwd, + check->http_proxy.passwd)) + continue; + } + else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { + /* Proxy connection is using NTLM auth but we don't want NTLM */ + continue; + } +#endif + if(wantNTLMhttp || wantProxyNTLMhttp) { + /* Credentials are already checked, we may use this connection. + * With NTLM being weird as it is, we MUST use a + * connection where it has already been fully negotiated. + * If it has not, we keep on looking for a better one. */ + chosen = check; + + if((wantNTLMhttp && + (check->http_ntlm_state != NTLMSTATE_NONE)) || + (wantProxyNTLMhttp && + (check->proxy_ntlm_state != NTLMSTATE_NONE))) { + /* We must use this connection, no other */ + *force_reuse = TRUE; + break; + } + /* Continue look up for a better connection */ + continue; + } #endif - if(canmultiplex) { - /* We can multiplex if we want to. Let's continue looking for - the optimal connection to use. */ - - if(!multiplexed) { - /* We have the optimal connection. Let's stop looking. */ - chosen = check; - break; - } -#ifdef USE_NGHTTP2 - /* If multiplexed, make sure we don't go over concurrency limit */ - if(check->bits.multiplex) { - if(multiplexed >= Curl_conn_get_max_concurrent(data, check, - FIRSTSOCKET)) { - infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)", - multiplexed); - continue; - } - else if(multiplexed >= - Curl_multi_max_concurrent_streams(data->multi)) { - infof(data, "client side MAX_CONCURRENT_STREAMS reached" - ", skip (%zu)", - multiplexed); - continue; - } - } -#endif - /* When not multiplexed, we have a match here! */ - chosen = check; - infof(data, "Multiplexed connection found"); - break; - } - else { - /* We have found a connection. Let's stop searching. */ - chosen = check; - break; - } + if(CONN_INUSE(check)) { + DEBUGASSERT(canmultiplex); + DEBUGASSERT(check->bits.multiplex); + /* If multiplexed, make sure we don't go over concurrency limit */ + if(CONN_INUSE(check) >= + Curl_multi_max_concurrent_streams(data->multi)) { + infof(data, "client side MAX_CONCURRENT_STREAMS reached" + ", skip (%zu)", CONN_INUSE(check)); + continue; } + if(CONN_INUSE(check) >= + Curl_conn_get_max_concurrent(data, check, FIRSTSOCKET)) { + infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)", + CONN_INUSE(check)); + continue; + } + /* When not multiplexed, we have a match here! */ + infof(data, "Multiplexed connection found"); + } + else if(extract_if_dead(check, data)) { + /* disconnect it */ + Curl_disconnect(data, check, TRUE); + continue; } - } + + /* We have found a connection. Let's stop searching. */ + chosen = check; + break; + } /* loop over connection bundle */ if(chosen) { /* mark it as used before releasing the lock */ @@ -1560,17 +1390,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) #ifndef CURL_DISABLE_FTP conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; -#endif - conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus; - conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer; - conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost; - conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options; -#ifndef CURL_DISABLE_PROXY - conn->proxy_ssl_config.verifystatus = - data->set.proxy_ssl.primary.verifystatus; - conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer; - conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; - conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options; #endif conn->ip_version = data->set.ipver; conn->connect_only = data->set.connect_only; @@ -1615,30 +1434,231 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) return NULL; } -/* returns the handler if the given scheme is built-in */ -const struct Curl_handler *Curl_builtin_scheme(const char *scheme, - size_t schemelen) +const struct Curl_handler *Curl_get_scheme_handler(const char *scheme) { - const struct Curl_handler * const *pp; - const struct Curl_handler *p; - /* Scan protocol handler table and match against 'scheme'. The handler may - be changed later when the protocol specific setup function is called. */ - if(schemelen == CURL_ZERO_TERMINATED) - schemelen = strlen(scheme); - for(pp = protocols; (p = *pp) != NULL; pp++) - if(strncasecompare(p->scheme, scheme, schemelen) && !p->scheme[schemelen]) - /* Protocol found in table. */ - return p; - return NULL; /* not found */ + return Curl_getn_scheme_handler(scheme, strlen(scheme)); } +/* returns the handler if the given scheme is built-in */ +const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme, + size_t len) +{ + /* table generated by schemetable.c: + 1. gcc schemetable.c && ./a.out + 2. check how small the table gets + 3. tweak the hash algorithm, then rerun from 1 + 4. when the table is good enough + 5. copy the table into this source code + 6. make sure this function uses the same hash function that worked for + schemetable.c + 7. if needed, adjust the #ifdefs in schemetable.c and rerun + */ + static const struct Curl_handler * const protocols[67] = { +#ifndef CURL_DISABLE_FILE + &Curl_handler_file, +#else + NULL, +#endif + NULL, NULL, +#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER) + &Curl_handler_gophers, +#else + NULL, +#endif + NULL, +#ifdef USE_LIBRTMP + &Curl_handler_rtmpe, +#else + NULL, +#endif +#ifndef CURL_DISABLE_SMTP + &Curl_handler_smtp, +#else + NULL, +#endif +#if defined(USE_SSH) + &Curl_handler_sftp, +#else + NULL, +#endif +#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ + (SIZEOF_CURL_OFF_T > 4) + &Curl_handler_smb, +#else + NULL, +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) + &Curl_handler_smtps, +#else + NULL, +#endif +#ifndef CURL_DISABLE_TELNET + &Curl_handler_telnet, +#else + NULL, +#endif +#ifndef CURL_DISABLE_GOPHER + &Curl_handler_gopher, +#else + NULL, +#endif +#ifndef CURL_DISABLE_TFTP + &Curl_handler_tftp, +#else + NULL, +#endif + NULL, NULL, NULL, +#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) + &Curl_handler_ftps, +#else + NULL, +#endif +#ifndef CURL_DISABLE_HTTP + &Curl_handler_http, +#else + NULL, +#endif +#ifndef CURL_DISABLE_IMAP + &Curl_handler_imap, +#else + NULL, +#endif +#ifdef USE_LIBRTMP + &Curl_handler_rtmps, +#else + NULL, +#endif +#ifdef USE_LIBRTMP + &Curl_handler_rtmpt, +#else + NULL, +#endif + NULL, NULL, NULL, +#if !defined(CURL_DISABLE_LDAP) && \ + !defined(CURL_DISABLE_LDAPS) && \ + ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ + (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) + &Curl_handler_ldaps, +#else + NULL, +#endif +#if defined(USE_WEBSOCKETS) && \ + defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + &Curl_handler_wss, +#else + NULL, +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + &Curl_handler_https, +#else + NULL, +#endif + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#ifndef CURL_DISABLE_RTSP + &Curl_handler_rtsp, +#else + NULL, +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \ + defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4) + &Curl_handler_smbs, +#else + NULL, +#endif +#if defined(USE_SSH) && !defined(USE_WOLFSSH) + &Curl_handler_scp, +#else + NULL, +#endif + NULL, NULL, NULL, +#ifndef CURL_DISABLE_POP3 + &Curl_handler_pop3, +#else + NULL, +#endif + NULL, NULL, +#ifdef USE_LIBRTMP + &Curl_handler_rtmp, +#else + NULL, +#endif + NULL, NULL, NULL, +#ifdef USE_LIBRTMP + &Curl_handler_rtmpte, +#else + NULL, +#endif + NULL, NULL, NULL, +#ifndef CURL_DISABLE_DICT + &Curl_handler_dict, +#else + NULL, +#endif + NULL, NULL, NULL, +#ifndef CURL_DISABLE_MQTT + &Curl_handler_mqtt, +#else + NULL, +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) + &Curl_handler_pop3s, +#else + NULL, +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) + &Curl_handler_imaps, +#else + NULL, +#endif + NULL, +#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP) + &Curl_handler_ws, +#else + NULL, +#endif + NULL, +#ifdef USE_LIBRTMP + &Curl_handler_rtmpts, +#else + NULL, +#endif +#ifndef CURL_DISABLE_LDAP + &Curl_handler_ldap, +#else + NULL, +#endif + NULL, NULL, +#ifndef CURL_DISABLE_FTP + &Curl_handler_ftp, +#else + NULL, +#endif + }; + + if(len && (len <= 7)) { + const char *s = scheme; + size_t l = len; + const struct Curl_handler *h; + unsigned int c = 978; + while(l) { + c <<= 5; + c += Curl_raw_tolower(*s); + s++; + l--; + } + + h = protocols[c % 67]; + if(h && strncasecompare(scheme, h->scheme, len) && !h->scheme[len]) + return h; + } + return NULL; +} static CURLcode findprotocol(struct Curl_easy *data, struct connectdata *conn, const char *protostr) { - const struct Curl_handler *p = Curl_builtin_scheme(protostr, - CURL_ZERO_TERMINATED); + const struct Curl_handler *p = Curl_get_scheme_handler(protostr); if(p && /* Protocol found in table. Check if allowed */ (data->set.allowed_protocols & p->protocol)) { @@ -1652,7 +1672,6 @@ static CURLcode findprotocol(struct Curl_easy *data, else { /* Perform setup complement if some. */ conn->handler = conn->given = p; - /* 'port' and 'remote_port' are set in setup_connection_internals() */ return CURLE_OK; } @@ -1705,14 +1724,14 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data, conn->scope_id = (unsigned int)scope; #if defined(HAVE_IF_NAMETOINDEX) else { -#elif defined(WIN32) +#elif defined(_WIN32) else if(Curl_if_nametoindex) { #endif -#if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32) +#if defined(HAVE_IF_NAMETOINDEX) || defined(_WIN32) /* Zone identifier is not numeric */ unsigned int scopeidx = 0; -#if defined(WIN32) +#if defined(_WIN32) scopeidx = Curl_if_nametoindex(zoneid); #else scopeidx = if_nametoindex(zoneid); @@ -1727,7 +1746,7 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data, else conn->scope_id = scopeidx; } -#endif /* HAVE_IF_NAMETOINDEX || WIN32 */ +#endif /* HAVE_IF_NAMETOINDEX || _WIN32 */ free(zoneid); } @@ -3596,85 +3615,10 @@ static CURLcode create_conn(struct Curl_easy *data, conn->send[SECONDARYSOCKET] = Curl_conn_send; conn->bits.tcp_fastopen = data->set.tcp_fastopen; - /* Get a cloned copy of the SSL config situation stored in the - connection struct. But to get this going nicely, we must first make - sure that the strings in the master copy are pointing to the correct - strings in the session handle strings array! - - Keep in mind that the pointers in the master copy are pointing to strings - that will be freed as part of the Curl_easy struct, but all cloned - copies will be separately allocated. - */ - data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; - data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; - data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; - data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; - data->set.ssl.primary.cipher_list = - data->set.str[STRING_SSL_CIPHER_LIST]; - data->set.ssl.primary.cipher_list13 = - data->set.str[STRING_SSL_CIPHER13_LIST]; - data->set.ssl.primary.pinned_key = - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; - data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT]; - data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; - data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES]; - -#ifndef CURL_DISABLE_PROXY - data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; - data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; - data->set.proxy_ssl.primary.cipher_list = - data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; - data->set.proxy_ssl.primary.cipher_list13 = - data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; - data->set.proxy_ssl.primary.pinned_key = - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; - data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; - data->set.proxy_ssl.primary.ca_info_blob = - data->set.blobs[BLOB_CAINFO_PROXY]; - data->set.proxy_ssl.primary.issuercert = - data->set.str[STRING_SSL_ISSUERCERT_PROXY]; - data->set.proxy_ssl.primary.issuercert_blob = - data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; - data->set.proxy_ssl.primary.CRLfile = - data->set.str[STRING_SSL_CRLFILE_PROXY]; - data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; - data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; - data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; - data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; - data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; - data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; -#endif - data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; - data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; - data->set.ssl.key = data->set.str[STRING_KEY]; - data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE]; - data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD]; - data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; -#ifdef USE_TLS_SRP - data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; - data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; -#ifndef CURL_DISABLE_PROXY - data->set.proxy_ssl.primary.username = - data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; - data->set.proxy_ssl.primary.password = - data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; -#endif -#endif - data->set.ssl.key_blob = data->set.blobs[BLOB_KEY]; - - if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, - &conn->ssl_config)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - -#ifndef CURL_DISABLE_PROXY - if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary, - &conn->proxy_ssl_config)) { - result = CURLE_OUT_OF_MEMORY; + /* Complete the easy's SSL configuration for connection cache matching */ + result = Curl_ssl_easy_config_complete(data); + if(result) goto out; - } -#endif prune_dead_connections(data); @@ -3789,7 +3733,41 @@ static CURLcode create_conn(struct Curl_easy *data, * This is a brand new connection, so let's store it in the connection * cache of ours! */ + result = Curl_ssl_conn_config_init(data, conn); + if(result) { + DEBUGF(fprintf(stderr, "Error: init connection ssl config\n")); + goto out; + } + + result = Curl_resolver_init(data, &conn->resolve_async.resolver); + if(result) { + DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); + goto out; + } + Curl_attach_connection(data, conn); + +#ifdef USE_ARES + result = Curl_set_dns_servers(data, data->set.str[STRING_DNS_SERVERS]); + if(result && result != CURLE_NOT_BUILT_IN) + goto out; + + result = Curl_set_dns_interface(data, + data->set.str[STRING_DNS_INTERFACE]); + if(result && result != CURLE_NOT_BUILT_IN) + goto out; + + result = Curl_set_dns_local_ip4(data, + data->set.str[STRING_DNS_LOCAL_IP4]); + if(result && result != CURLE_NOT_BUILT_IN) + goto out; + + result = Curl_set_dns_local_ip6(data, + data->set.str[STRING_DNS_LOCAL_IP6]); + if(result && result != CURLE_NOT_BUILT_IN) + goto out; +#endif /* USE_ARES */ + result = Curl_conncache_add_conn(data); if(result) goto out; @@ -3976,6 +3954,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) k->bytecount = 0; k->ignorebody = FALSE; + Curl_client_cleanup(data); Curl_speedinit(data); Curl_pgrsSetUploadCounter(data, 0); Curl_pgrsSetDownloadCounter(data, 0); diff --git a/lib/url.h b/lib/url.h index f6a5b2573..7c1a29bc3 100644 --- a/lib/url.h +++ b/lib/url.h @@ -46,8 +46,13 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, char **userptr, char **passwdptr, char **optionsptr); -const struct Curl_handler *Curl_builtin_scheme(const char *scheme, - size_t schemelen); +/* Get protocol handler for a URI scheme + * @param scheme URI scheme, case-insensitive + * @return NULL of handler not found + */ +const struct Curl_handler *Curl_get_scheme_handler(const char *scheme); +const struct Curl_handler *Curl_getn_scheme_handler(const char *scheme, + size_t len); #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */ #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless diff --git a/lib/urlapi.c b/lib/urlapi.c index 4efab611c..0d11e48c9 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -206,7 +206,7 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, (void)buflen; /* only used in debug-builds */ if(buf) buf[0] = 0; /* always leave a defined value in buf */ -#ifdef WIN32 +#ifdef _WIN32 if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url)) return 0; #endif @@ -446,7 +446,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, /* if this is a known scheme, get some details */ if(u->scheme) - h = Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED); + h = Curl_get_scheme_handler(u->scheme); /* We could use the login information in the URL so extract it. Only parse options if the handler says we should. Note that 'h' might be NULL! */ @@ -1056,7 +1056,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) ptr += 9; /* now points to the slash after the host */ } else { -#if defined(WIN32) +#if defined(_WIN32) size_t len; /* the host name, NetBIOS computer name, can not contain disallowed @@ -1095,7 +1095,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) /* no host for file: URLs by default */ Curl_dyn_reset(&host); -#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) +#if !defined(_WIN32) && !defined(MSDOS) && !defined(__CYGWIN__) /* Don't allow Windows drive letters when not in Windows. * This catches both "file:/c:" and "file:c:" */ if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || @@ -1129,7 +1129,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) } schemep = schemebuf; - if(!Curl_builtin_scheme(schemep, CURL_ZERO_TERMINATED) && + if(!Curl_get_scheme_handler(schemep) && !(flags & CURLU_NON_SUPPORT_SCHEME)) { result = CURLUE_UNSUPPORTED_SCHEME; goto fail; @@ -1224,14 +1224,14 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) if(flags & CURLU_URLENCODE) { struct dynbuf enc; Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); - if(urlencode_str(&enc, fragment + 1, fraglen, TRUE, FALSE)) { + if(urlencode_str(&enc, fragment + 1, fraglen - 1, TRUE, FALSE)) { result = CURLUE_OUT_OF_MEMORY; goto fail; } u->fragment = Curl_dyn_ptr(&enc); } else { - u->fragment = Curl_memdup(fragment + 1, fraglen); + u->fragment = Curl_strndup(fragment + 1, fraglen - 1); if(!u->fragment) { result = CURLUE_OUT_OF_MEMORY; goto fail; @@ -1260,12 +1260,11 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) u->query = Curl_dyn_ptr(&enc); } else { - u->query = Curl_memdup(query + 1, qlen); + u->query = Curl_strndup(query + 1, qlen - 1); if(!u->query) { result = CURLUE_OUT_OF_MEMORY; goto fail; } - u->query[qlen - 1] = 0; } } else { @@ -1295,12 +1294,11 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) } else { if(!u->path) { - u->path = Curl_memdup(path, pathlen + 1); + u->path = Curl_strndup(path, pathlen); if(!u->path) { result = CURLUE_OUT_OF_MEMORY; goto fail; } - u->path[pathlen] = 0; path = u->path; } else if(flags & CURLU_URLENCODE) @@ -1352,7 +1350,7 @@ static CURLUcode parseurl_and_replace(const char *url, CURLU *u, */ CURLU *curl_url(void) { - return calloc(sizeof(struct Curl_URL), 1); + return calloc(1, sizeof(struct Curl_URL)); } void curl_url_cleanup(CURLU *u) @@ -1374,7 +1372,7 @@ void curl_url_cleanup(CURLU *u) CURLU *curl_url_dup(const CURLU *in) { - struct Curl_URL *u = calloc(sizeof(struct Curl_URL), 1); + struct Curl_URL *u = calloc(1, sizeof(struct Curl_URL)); if(u) { DUP(u, in, scheme); DUP(u, in, user); @@ -1447,8 +1445,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { /* there's no stored port number, but asked to deliver a default one for the scheme */ - const struct Curl_handler *h = - Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED); + const struct Curl_handler *h = Curl_get_scheme_handler(u->scheme); if(h) { msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); ptr = portbuf; @@ -1457,8 +1454,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, else if(ptr && u->scheme) { /* there is a stored port number, but ask to inhibit if it matches the default one for the scheme */ - const struct Curl_handler *h = - Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED); + const struct Curl_handler *h = Curl_get_scheme_handler(u->scheme); if(h && (h->defport == u->portnum) && (flags & CURLU_NO_DEFAULT_PORT)) ptr = NULL; @@ -1503,7 +1499,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, else return CURLUE_NO_SCHEME; - h = Curl_builtin_scheme(scheme, CURL_ZERO_TERMINATED); + h = Curl_get_scheme_handler(scheme); if(!port && (flags & CURLU_DEFAULT_PORT)) { /* there's no stored port number, but asked to deliver a default one for the scheme */ @@ -1596,7 +1592,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, if(ptr) { size_t partlen = strlen(ptr); size_t i = 0; - *part = Curl_memdup(ptr, partlen + 1); + *part = Curl_strndup(ptr, partlen); if(!*part) return CURLUE_OUT_OF_MEMORY; if(plusdecode) { @@ -1743,9 +1739,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, if((plen > MAX_SCHEME_LEN) || (plen < 1)) /* too long or too short */ return CURLUE_BAD_SCHEME; - if(!(flags & CURLU_NON_SUPPORT_SCHEME) && - /* verify that it is a fine scheme */ - !Curl_builtin_scheme(part, CURL_ZERO_TERMINATED)) + /* verify that it is a fine scheme */ + if(!(flags & CURLU_NON_SUPPORT_SCHEME) && !Curl_get_scheme_handler(part)) return CURLUE_UNSUPPORTED_SCHEME; storep = &u->scheme; urlencode = FALSE; /* never */ @@ -1905,7 +1900,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } newp = Curl_dyn_ptr(&enc); - if(appendquery) { + if(appendquery && newp) { /* Append the 'newp' string onto the old query. Add a '&' separator if none is present at the end of the existing query already */ @@ -1934,8 +1929,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } } - if(what == CURLUPART_HOST) { - size_t n = strlen(newp); + else if(what == CURLUPART_HOST) { + size_t n = Curl_dyn_len(&enc); if(!n && (flags & CURLU_NO_AUTHORITY)) { /* Skip hostname check, it's allowed to be empty. */ } diff --git a/lib/urldata.h b/lib/urldata.h index dff26e6b4..ff661482e 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -266,6 +266,13 @@ typedef enum { /* SSL backend-specific data; declared differently by each SSL backend */ struct ssl_backend_data; +struct ssl_peer { + char *hostname; /* hostname for verification */ + char *dispname; /* display version of hostname */ + char *sni; /* SNI version of hostname or NULL if not usable */ + BIT(is_ip_address); /* if hostname is an IPv4|6 address */ +}; + struct ssl_primary_config { char *CApath; /* certificate dir (doesn't work on windows) */ char *CAfile; /* certificate to verify peer against */ @@ -571,6 +578,13 @@ struct hostname { #define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE) #define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE) +/* transfer wants to send is not PAUSE or HOLD */ +#define CURL_WANT_SEND(data) \ + (((data)->req.keepon & KEEP_SENDBITS) == KEEP_SEND) +/* transfer receive is not on PAUSE or HOLD */ +#define CURL_WANT_RECV(data) \ + (!((data)->req.keepon & (KEEP_RECV_PAUSE|KEEP_RECV_HOLD))) + #if defined(CURLRES_ASYNCH) || !defined(CURL_DISABLE_DOH) #define USE_CURL_ASYNC struct Curl_async { @@ -589,6 +603,15 @@ struct Curl_async { #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]; +}; + enum expect100 { EXP100_SEND_DATA, /* enough waiting, just send the body now */ EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */ @@ -649,16 +672,8 @@ struct SingleRequest { counter to make only a 100 reply (without a following second response code) result in a CURLE_GOT_NOTHING error code */ - enum { - HEADER_NORMAL, /* no bad header at all */ - HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest - is normal data */ - HEADER_ALLBAD /* all was believed to be header */ - } badheader; /* the header was deemed bad and will be - written as body */ int headerline; /* counts header lines to better track the first one */ - char *str; /* within buf */ curl_off_t offset; /* possible resume offset read from the Content-Range: header */ int httpcode; /* error code from the 'HTTP/1.? XXX' or @@ -669,7 +684,7 @@ struct SingleRequest { enum upgrade101 upgr101; /* 101 upgrade state */ /* Content unencoding stack. See sec 3.5, RFC2616. */ - struct contenc_writer *writer_stack; + struct Curl_cwriter *writer_stack; time_t timeofdoc; long bodywrites; char *location; /* This points to an allocated version of the Location: @@ -706,16 +721,20 @@ struct SingleRequest { #ifndef CURL_DISABLE_DOH struct dohdata *doh; /* DoH specific data for this request */ #endif -#if defined(WIN32) && defined(USE_WINSOCK) +#if defined(_WIN32) && defined(USE_WINSOCK) struct curltime last_sndbuf_update; /* last time readwrite_upload called win_update_buffer_size */ #endif + char fread_eof[2]; /* the body read callback (index 0) returned EOF or + the trailer read callback (index 1) returned EOF */ #ifndef CURL_DISABLE_COOKIES unsigned char setcookies; #endif unsigned char writer_stack_depth; /* Unencoding stack depth. */ BIT(header); /* incoming data has HTTP header */ + BIT(badheader); /* header parsing found sth not a header */ BIT(content_range); /* set TRUE if Content-Range: was found */ + BIT(download_done); /* set to TRUE when download is complete */ BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding upload and we're uploading the last chunk */ BIT(ignorebody); /* we read a response-body but we ignore it! */ @@ -799,7 +818,8 @@ struct Curl_handler { /* If used, this function gets called from transfer.c:readwrite_data() to allow the protocol to do extra reads/writes */ CURLcode (*readwrite)(struct Curl_easy *data, struct connectdata *conn, - ssize_t *nread, bool *readmore); + const char *buf, size_t blen, + size_t *pconsumed, bool *readmore); /* This function can perform various checks on the connection. See CONNCHECK_* for more information about the checks that can be performed, @@ -901,6 +921,9 @@ struct connectdata { multi_done(). This entry will be NULL if the connection is reused as then there is no name resolve done. */ struct Curl_dns_entry *dns_entry; +#ifdef USE_CURL_ASYNC + struct Curl_async resolve_async; /* asynchronous name resolver data */ +#endif /* 'remote_addr' is the particular IP we connected to. it is owned, set * and NULLed by the connected socket filter (if there is one). */ @@ -1325,7 +1348,8 @@ struct UrlState { curl_off_t recent_conn_id; /* The most recent connection used, might no * longer exist */ struct dynbuf headerb; /* buffer to store headers in */ - + struct curl_slist *hstslist; /* list of HSTS files set by + curl_easy_setopt(HSTS) calls */ char *buffer; /* download buffer */ char *ulbuf; /* allocated upload buffer or NULL */ curl_off_t current_speed; /* the ProgressShow() function sets this, @@ -1358,9 +1382,6 @@ struct UrlState { #endif struct auth authhost; /* auth details for host */ struct auth authproxy; /* auth details for proxy */ -#ifdef USE_CURL_ASYNC - struct Curl_async async; /* asynchronous name resolver data */ -#endif #if defined(USE_OPENSSL) /* void instead of ENGINE to avoid bleeding OpenSSL into this header */ @@ -1373,7 +1394,7 @@ struct UrlState { /* a place to store the most recently set (S)FTP entrypath */ char *most_recent_ftp_entrypath; -#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) +#if !defined(_WIN32) && !defined(MSDOS) && !defined(__EMX__) /* do FTP line-end conversions on most platforms */ #define CURL_DO_LINEEND_CONV /* for FTP downloads: track CRLF sequences that span blocks */ @@ -1411,7 +1432,7 @@ struct UrlState { this should be dealt with in pretransfer */ #ifndef CURL_DISABLE_HTTP curl_mimepart *mimepost; - curl_mimepart *formp; /* storage for old API form-posting, alloced on + curl_mimepart *formp; /* storage for old API form-posting, allocated on demand */ size_t trailers_bytes_sent; struct dynbuf trailers_buf; /* a buffer containing the compiled trailing @@ -1422,6 +1443,10 @@ struct UrlState { trailers_state trailers_state; /* whether we are sending trailers and what stage are we at */ #endif +#ifndef CURL_DISABLE_COOKIES + struct curl_slist *cookielist; /* list of cookie files set by + curl_easy_setopt(COOKIEFILE) calls */ +#endif #ifdef USE_HYPER bool hconnect; /* set if a CONNECT request */ CURLcode hresult; /* used to pass return codes back from hyper callbacks */ @@ -1498,6 +1523,9 @@ struct UrlState { though it will be discarded. We must call the data rewind callback before trying to send again. */ BIT(upload); /* upload request */ + BIT(internal); /* internal: true if this easy handle was created for + internal use and the user does not have ownership of the + handle. */ }; /* @@ -1674,13 +1702,7 @@ struct UserDefined { void *prereq_userp; /* pre-initial request user data */ void *seek_client; /* pointer to pass to the seek callback */ -#ifndef CURL_DISABLE_COOKIES - struct curl_slist *cookielist; /* list of cookie files set by - curl_easy_setopt(COOKIEFILE) calls */ -#endif #ifndef CURL_DISABLE_HSTS - struct curl_slist *hstslist; /* list of HSTS files set by - curl_easy_setopt(HSTS) calls */ curl_hstsread_callback hsts_read; void *hsts_read_userp; curl_hstswrite_callback hsts_write; @@ -1780,9 +1802,6 @@ struct UserDefined { #endif curl_prot_t allowed_protocols; curl_prot_t redir_protocols; -#ifndef CURL_DISABLE_MIME - unsigned int mime_options; /* Mime option flags. */ -#endif #ifndef CURL_DISABLE_RTSP void *rtp_out; /* write RTP to this if non-NULL */ /* Common RTSP header options */ @@ -1805,8 +1824,6 @@ struct UserDefined { int tcp_keepidle; /* seconds in idle before sending keepalive probe */ int tcp_keepintvl; /* seconds between TCP keepalive probes */ - size_t maxconnects; /* Max idle connections in the connection cache */ - long expect_100_timeout; /* in milliseconds */ #if defined(USE_HTTP2) || defined(USE_HTTP3) struct Curl_data_priority priority; @@ -1831,10 +1848,14 @@ struct UserDefined { BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some recipients */ #endif + unsigned int maxconnects; /* Max idle connections in the connection cache */ unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or POP3 or others! (type: curl_usessl)*/ unsigned char connect_only; /* make connection/request, then let application use the socket */ +#ifndef CURL_DISABLE_MIME + BIT(mime_formescape); +#endif BIT(is_fread_set); /* has read callback been set to non-NULL? */ #ifndef CURL_DISABLE_TFTP BIT(tftp_no_options); /* do not send TFTP options requests */ @@ -1971,10 +1992,7 @@ struct Curl_easy { particular order. Note that all sockets are added to the sockhash, where the state etc are also kept. This array is mostly used to detect when a socket is to be removed from the hash. See singlesocket(). */ - curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; - unsigned char actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in - sockets[] */ - int numsocks; + struct easy_pollset last_poll; struct Names dns; struct Curl_multi *multi; /* if non-NULL, points to the multi handle @@ -2013,10 +2031,6 @@ struct Curl_easy { #ifdef USE_HYPER struct hyptransfer hyp; #endif - - /* internal: true if this easy handle was created for internal use and the - user does not have ownership of the handle. */ - bool internal; }; #define LIBCURL_NAME "libcurl" diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c index 12c6f7dd5..416da0fcc 100644 --- a/lib/vauth/digest.c +++ b/lib/vauth/digest.c @@ -125,7 +125,6 @@ bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, } else return FALSE; - break; } } diff --git a/lib/version.c b/lib/version.c index 47304259e..f957f085d 100644 --- a/lib/version.c +++ b/lib/version.c @@ -39,7 +39,7 @@ #ifdef USE_ARES # if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ - defined(WIN32) + defined(_WIN32) # define CARES_STATICLIB # endif # include @@ -409,7 +409,8 @@ static int idn_present(curl_version_info_data *info) #define idn_present NULL #endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) +#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) && \ + !defined(CURL_DISABLE_HTTP) static int https_proxy_present(curl_version_info_data *info) { (void) info; @@ -454,13 +455,14 @@ static const struct feat features_table[] = { #ifndef CURL_DISABLE_HSTS FEATURE("HSTS", NULL, CURL_VERSION_HSTS), #endif -#if defined(USE_NGHTTP2) || defined(USE_HYPER) +#if defined(USE_NGHTTP2) FEATURE("HTTP2", NULL, CURL_VERSION_HTTP2), #endif #if defined(ENABLE_QUIC) FEATURE("HTTP3", NULL, CURL_VERSION_HTTP3), #endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_PROXY) +#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_LIBIDN2) || defined(USE_WIN32_IDN) @@ -510,7 +512,7 @@ static const struct feat features_table[] = { #ifdef CURLDEBUG FEATURE("TrackMemory", NULL, CURL_VERSION_CURLDEBUG), #endif -#if defined(WIN32) && defined(UNICODE) && defined(_UNICODE) +#if defined(_WIN32) && defined(UNICODE) && defined(_UNICODE) FEATURE("Unicode", NULL, CURL_VERSION_UNICODE), #endif #ifdef USE_UNIX_SOCKETS diff --git a/lib/version_win32.c b/lib/version_win32.c index 872d5b4f3..e0f239e15 100644 --- a/lib/version_win32.c +++ b/lib/version_win32.c @@ -24,7 +24,7 @@ #include "curl_setup.h" -#if defined(WIN32) +#if defined(_WIN32) #include #include "version_win32.h" @@ -316,4 +316,4 @@ bool curlx_verify_windows_version(const unsigned int majorVersion, return matched; } -#endif /* WIN32 */ +#endif /* _WIN32 */ diff --git a/lib/version_win32.h b/lib/version_win32.h index 3899174a3..95c066112 100644 --- a/lib/version_win32.h +++ b/lib/version_win32.h @@ -26,7 +26,7 @@ #include "curl_setup.h" -#if defined(WIN32) +#if defined(_WIN32) /* Version condition */ typedef enum { @@ -51,6 +51,6 @@ bool curlx_verify_windows_version(const unsigned int majorVersion, const PlatformIdentifier platform, const VersionCondition condition); -#endif /* WIN32 */ +#endif /* _WIN32 */ #endif /* HEADER_CURL_VERSION_WIN32_H */ diff --git a/lib/vquic/curl_msh3.c b/lib/vquic/curl_msh3.c index 6bd0d2331..8ae367240 100644 --- a/lib/vquic/curl_msh3.c +++ b/lib/vquic/curl_msh3.c @@ -38,6 +38,7 @@ #include "http1.h" #include "curl_msh3.h" #include "socketpair.h" +#include "vtls/vtls.h" #include "vquic/vquic.h" /* The last 3 #include files should be in this order */ @@ -45,6 +46,10 @@ #include "curl_memory.h" #include "memdebug.h" +#ifdef CURL_DISABLE_SOCKETPAIR +#error "MSH3 cannot be build with CURL_DISABLE_SOCKETPAIR set" +#endif + #define H3_STREAM_WINDOW_SIZE (128 * 1024) #define H3_STREAM_CHUNK_SIZE (16 * 1024) #define H3_STREAM_RECV_CHUNKS \ @@ -672,31 +677,25 @@ static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data, return nwritten; } -static int cf_msh3_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks) +static void cf_msh3_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_msh3_ctx *ctx = cf->ctx; struct stream_ctx *stream = H3_STREAM_CTX(data); - int bitmap = GETSOCK_BLANK; struct cf_call_data save; CF_DATA_SAVE(save, cf, data); if(stream && ctx->sock[SP_LOCAL] != CURL_SOCKET_BAD) { - socks[0] = ctx->sock[SP_LOCAL]; - if(stream->recv_error) { - bitmap |= GETSOCK_READSOCK(0); + Curl_pollset_add_in(data, ps, ctx->sock[SP_LOCAL]); drain_stream(cf, data); } else if(stream->req) { - bitmap |= GETSOCK_READSOCK(0); + Curl_pollset_add_out(data, ps, ctx->sock[SP_LOCAL]); drain_stream(cf, data); } } - CURL_TRC_CF(data, cf, "select_sock -> %d", bitmap); - CF_DATA_RESTORE(cf, save); - return bitmap; } static bool cf_msh3_data_pending(struct Curl_cfilter *cf, @@ -802,14 +801,20 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_msh3_ctx *ctx = cf->ctx; - bool verify = !!cf->conn->ssl_config.verifypeer; + struct ssl_primary_config *conn_config; MSH3_ADDR addr = {0}; CURLcode result; + bool verify; + + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) + return CURLE_FAILED_INIT; + verify = !!conn_config->verifypeer; memcpy(&addr, &ctx->addr.sa_addr, ctx->addr.addrlen); MSH3_SET_PORT(&addr, (uint16_t)cf->conn->remote_port); - if(verify && (cf->conn->ssl_config.CAfile || cf->conn->ssl_config.CApath)) { + if(verify && (conn_config->CAfile || conn_config->CApath)) { /* TODO: need a way to provide trust anchors to MSH3 */ #ifdef DEBUGBUILD /* we need this for our test cases to run */ @@ -1025,7 +1030,7 @@ struct Curl_cftype Curl_cft_http3 = { cf_msh3_connect, cf_msh3_close, Curl_cf_def_get_host, - cf_msh3_get_select_socks, + cf_msh3_adjust_pollset, cf_msh3_data_pending, cf_msh3_send, cf_msh3_recv, @@ -1047,7 +1052,7 @@ CURLcode Curl_cf_msh3_create(struct Curl_cfilter **pcf, (void)data; (void)conn; (void)ai; /* TODO: msh3 resolves itself? */ - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c index 7d681e585..f09b10bef 100644 --- a/lib/vquic/curl_ngtcp2.c +++ b/lib/vquic/curl_ngtcp2.c @@ -78,7 +78,6 @@ #define QUIC_MAX_STREAMS (256*1024) #define QUIC_MAX_DATA (1*1024*1024) -#define QUIC_IDLE_TIMEOUT (60*NGTCP2_SECONDS) #define QUIC_HANDSHAKE_TIMEOUT (10*NGTCP2_SECONDS) /* A stream window is the maximum amount we need to buffer for @@ -134,6 +133,7 @@ void Curl_ngtcp2_ver(char *p, size_t len) struct cf_ngtcp2_ctx { struct cf_quic_ctx q; + struct ssl_peer peer; ngtcp2_path connected_path; ngtcp2_conn *qconn; ngtcp2_cid dcid; @@ -161,6 +161,7 @@ struct cf_ngtcp2_ctx { struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ size_t max_stream_window; /* max flow window for one stream */ + uint64_t max_idle_ms; /* max idle time for QUIC connection */ int qlogfd; BIT(got_first_byte); /* if first byte was received */ #ifdef USE_OPENSSL @@ -191,6 +192,7 @@ struct h3_stream_ctx { bool closed; /* TRUE on stream close */ bool reset; /* TRUE on stream reset */ bool send_closed; /* stream is local closed */ + BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */ }; #define H3_STREAM_CTX(d) ((struct h3_stream_ctx *)(((d) && (d)->req.p.http)? \ @@ -236,11 +238,21 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf, static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) { + struct cf_ngtcp2_ctx *ctx = cf->ctx; struct h3_stream_ctx *stream = H3_STREAM_CTX(data); (void)cf; if(stream) { CURL_TRC_CF(data, cf, "[%"PRId64"] easy handle is done", stream->id); + if(ctx->h3conn && !stream->closed) { + nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream->id); + nghttp3_conn_close_stream(ctx->h3conn, stream->id, + NGHTTP3_H3_REQUEST_CANCELLED); + nghttp3_conn_set_stream_user_data(ctx->h3conn, stream->id, NULL); + ngtcp2_conn_set_stream_user_data(ctx->qconn, stream->id, NULL); + stream->closed = TRUE; + } + Curl_bufq_free(&stream->sendbuf); Curl_bufq_free(&stream->recvbuf); Curl_h1_req_parse_free(&stream->h1); @@ -249,6 +261,43 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) } } +static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf, + struct Curl_easy *data, + int64_t stream_id) +{ + struct Curl_easy *sdata; + + (void)cf; + if(H3_STREAM_ID(data) == stream_id) { + return data; + } + else { + DEBUGASSERT(data->multi); + for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + if((sdata->conn == data->conn) && H3_STREAM_ID(sdata) == stream_id) { + return sdata; + } + } + } + return NULL; +} + +static void h3_drain_stream(struct Curl_cfilter *cf, + struct Curl_easy *data) +{ + struct h3_stream_ctx *stream = H3_STREAM_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.dselect_bits != bits) { + data->state.dselect_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 @@ -261,10 +310,14 @@ struct pkt_io_ctx { ngtcp2_path_storage ps; }; -static ngtcp2_tstamp timestamp(void) +static void pktx_update_time(struct pkt_io_ctx *pktx, + struct Curl_cfilter *cf) { - struct curltime ct = Curl_now(); - return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS; + struct cf_ngtcp2_ctx *ctx = cf->ctx; + + vquic_ctx_update_time(&ctx->q); + pktx->ts = ctx->q.last_op.tv_sec * NGTCP2_SECONDS + + ctx->q.last_op.tv_usec * NGTCP2_MICROSECONDS; } static void pktx_init(struct pkt_io_ctx *pktx, @@ -273,9 +326,9 @@ static void pktx_init(struct pkt_io_ctx *pktx, { pktx->cf = cf; pktx->data = data; - pktx->ts = timestamp(); pktx->pkt_count = 0; ngtcp2_path_storage_zero(&pktx->ps); + pktx_update_time(pktx, cf); } static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, @@ -354,7 +407,7 @@ static void quic_settings(struct cf_ngtcp2_ctx *ctx, t->initial_max_stream_data_uni = ctx->max_stream_window; t->initial_max_streams_bidi = QUIC_MAX_STREAMS; t->initial_max_streams_uni = QUIC_MAX_STREAMS; - t->max_idle_timeout = QUIC_IDLE_TIMEOUT; + t->max_idle_timeout = (ctx->max_idle_ms * NGTCP2_MILLISECONDS); if(ctx->qlogfd != -1) { s->qlog_write = qlog_callback; } @@ -398,14 +451,19 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx, struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct connectdata *conn = cf->conn; + struct ssl_primary_config *conn_config; CURLcode result = CURLE_FAILED_INIT; - SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method()); + SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method()); if(!ssl_ctx) { result = CURLE_OUT_OF_MEMORY; goto out; } + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) { + result = CURLE_FAILED_INIT; + goto out; + } #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) if(ngtcp2_crypto_boringssl_configure_client_context(ssl_ctx) != 0) { @@ -422,8 +480,8 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx, SSL_CTX_set_default_verify_paths(ssl_ctx); { - const char *curves = conn->ssl_config.curves ? - conn->ssl_config.curves : QUIC_GROUPS; + const char *curves = conn_config->curves ? + conn_config->curves : QUIC_GROUPS; if(!SSL_CTX_set1_curves_list(ssl_ctx, curves)) { failf(data, "failed setting curves list for QUIC: '%s'", curves); return CURLE_SSL_CIPHER; @@ -432,8 +490,8 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx, #ifndef OPENSSL_IS_BORINGSSL { - const char *ciphers13 = conn->ssl_config.cipher_list13 ? - conn->ssl_config.cipher_list13 : QUIC_CIPHERS; + const char *ciphers13 = conn_config->cipher_list13 ? + conn_config->cipher_list13 : QUIC_CIPHERS; if(SSL_CTX_set_ciphersuites(ssl_ctx, ciphers13) != 1) { failf(data, "failed setting QUIC cipher suite: %s", ciphers13); return CURLE_SSL_CIPHER; @@ -452,7 +510,7 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx, * fail to connect if the verification fails, or if it should continue * anyway. In the latter case the result of the verification is checked with * SSL_get_verify_result() below. */ - SSL_CTX_set_verify(ssl_ctx, conn->ssl_config.verifypeer ? + SSL_CTX_set_verify(ssl_ctx, conn_config->verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); /* give application a chance to interfere with SSL set up. */ @@ -491,7 +549,7 @@ static CURLcode quic_set_client_cert(struct Curl_cfilter *cf, SSL_CTX *ssl_ctx = ctx->sslctx; const struct ssl_config_data *ssl_config; - ssl_config = Curl_ssl_get_config(data, FIRSTSOCKET); + ssl_config = Curl_ssl_cf_get_config(cf, data); DEBUGASSERT(ssl_config); if(ssl_config->primary.clientcert || ssl_config->primary.cert_blob @@ -514,7 +572,6 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf, struct cf_ngtcp2_ctx *ctx = cf->ctx; const uint8_t *alpn = NULL; size_t alpnlen = 0; - unsigned char checkip[16]; DEBUGASSERT(!ctx->ssl); ctx->ssl = SSL_new(ctx->sslctx); @@ -529,13 +586,8 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf, SSL_set_alpn_protos(ctx->ssl, alpn, (int)alpnlen); /* set SNI */ - if((0 == Curl_inet_pton(AF_INET, cf->conn->host.name, checkip)) -#ifdef ENABLE_IPV6 - && (0 == Curl_inet_pton(AF_INET6, cf->conn->host.name, checkip)) -#endif - ) { - char *snihost = Curl_ssl_snihost(data, cf->conn->host.name, NULL); - if(!snihost || !SSL_set_tlsext_host_name(ctx->ssl, snihost)) { + if(ctx->peer.sni) { + if(!SSL_set_tlsext_host_name(ctx->ssl, ctx->peer.sni)) { failf(data, "Failed set SNI"); SSL_free(ctx->ssl); ctx->ssl = NULL; @@ -549,20 +601,24 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_ngtcp2_ctx *ctx = cf->ctx; + struct ssl_primary_config *conn_config; CURLcode result; gnutls_datum_t alpn[2]; /* this will need some attention when HTTPS proxy over QUIC get fixed */ - const char * const hostname = cf->conn->host.name; long * const pverifyresult = &data->set.ssl.certverifyresult; int rc; + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) + return CURLE_FAILED_INIT; + DEBUGASSERT(ctx->gtls == NULL); ctx->gtls = calloc(1, sizeof(*(ctx->gtls))); if(!ctx->gtls) return CURLE_OUT_OF_MEMORY; - result = gtls_client_init(data, &cf->conn->ssl_config, &data->set.ssl, - hostname, ctx->gtls, pverifyresult); + result = gtls_client_init(data, conn_config, &data->set.ssl, + &ctx->peer, ctx->gtls, pverifyresult); if(result) return result; @@ -602,10 +658,17 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf, static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx, struct Curl_cfilter *cf, struct Curl_easy *data) { - struct connectdata *conn = cf->conn; CURLcode result = CURLE_FAILED_INIT; - WOLFSSL_CTX *ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); + struct ssl_primary_config *conn_config; + WOLFSSL_CTX *ssl_ctx = NULL; + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) { + result = CURLE_FAILED_INIT; + goto out; + } + + ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); if(!ssl_ctx) { result = CURLE_OUT_OF_MEMORY; goto out; @@ -613,13 +676,14 @@ static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx, if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) { failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed"); + result = CURLE_FAILED_INIT; goto out; } wolfSSL_CTX_set_default_verify_paths(ssl_ctx); - if(wolfSSL_CTX_set_cipher_list(ssl_ctx, conn->ssl_config.cipher_list13 ? - conn->ssl_config.cipher_list13 : + if(wolfSSL_CTX_set_cipher_list(ssl_ctx, conn_config->cipher_list13 ? + conn_config->cipher_list13 : QUIC_CIPHERS) != 1) { char error_buffer[256]; ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); @@ -627,8 +691,8 @@ static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx, goto out; } - if(wolfSSL_CTX_set1_groups_list(ssl_ctx, conn->ssl_config.curves ? - conn->ssl_config.curves : + if(wolfSSL_CTX_set1_groups_list(ssl_ctx, conn_config->curves ? + conn_config->curves : (char *)QUIC_GROUPS) != 1) { failf(data, "wolfSSL failed to set curves"); goto out; @@ -645,9 +709,9 @@ static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx, #endif } - if(conn->ssl_config.verifypeer) { - const char * const ssl_cafile = conn->ssl_config.CAfile; - const char * const ssl_capath = conn->ssl_config.CApath; + if(conn_config->verifypeer) { + const char * const ssl_cafile = conn_config->CAfile; + const char * const ssl_capath = conn_config->CApath; wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); if(ssl_cafile || ssl_capath) { @@ -786,6 +850,12 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, CURL_TRC_CF(data, cf, "[%" PRId64 "] read_stream(len=%zu) -> %zd", stream_id, buflen, nconsumed); if(nconsumed < 0) { + if(!data) { + struct Curl_easy *cdata = CF_DATA_CURRENT(cf); + CURL_TRC_CF(cdata, cf, "[%" PRId64 "] nghttp3 error on stream not " + "used by us, ignored", stream_id); + return 0; + } ngtcp2_ccerr_set_application_error( &ctx->last_error, nghttp3_err_infer_quic_app_error_code((int)nconsumed), NULL, 0); @@ -816,7 +886,7 @@ cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_add_ack_offset(ctx->h3conn, stream_id, datalen); - if(rv) { + if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -844,7 +914,7 @@ static int cb_stream_close(ngtcp2_conn *tconn, uint32_t flags, app_error_code); CURL_TRC_CF(data, cf, "[%" PRId64 "] quic close(err=%" PRIu64 ") -> %d", stream3_id, app_error_code, rv); - if(rv) { + if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { ngtcp2_ccerr_set_application_error( &ctx->last_error, nghttp3_err_infer_quic_app_error_code(rv), NULL, 0); return NGTCP2_ERR_CALLBACK_FAILURE; @@ -868,7 +938,7 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id, rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id); CURL_TRC_CF(data, cf, "[%" PRId64 "] reset -> %d", stream_id, rv); - if(rv) { + if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -887,7 +957,7 @@ static int cb_stream_stop_sending(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_shutdown_stream_read(ctx->h3conn, stream_id); - if(rv) { + if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -911,16 +981,25 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, { struct Curl_cfilter *cf = user_data; struct cf_ngtcp2_ctx *ctx = cf->ctx; + struct Curl_easy *data = CF_DATA_CURRENT(cf); + struct Curl_easy *s_data; + struct h3_stream_ctx *stream; int rv; (void)tconn; (void)max_data; (void)stream_user_data; rv = nghttp3_conn_unblock_stream(ctx->h3conn, stream_id); - if(rv) { + if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { return NGTCP2_ERR_CALLBACK_FAILURE; } - + s_data = get_stream_easy(cf, data, stream_id); + stream = H3_STREAM_CTX(s_data); + if(stream && stream->quic_flow_blocked) { + CURL_TRC_CF(data, cf, "[%" PRId64 "] unblock quic flow", stream_id); + stream->quic_flow_blocked = FALSE; + h3_drain_stream(cf, data); + } return 0; } @@ -1038,7 +1117,7 @@ static CURLcode check_and_set_expiry(struct Curl_cfilter *cf, pktx = &local_pktx; } else { - pktx->ts = timestamp(); + pktx_update_time(pktx, cf); } expiry = ngtcp2_conn_get_expiry(ctx->qconn); @@ -1073,46 +1152,29 @@ static CURLcode check_and_set_expiry(struct Curl_cfilter *cf, return CURLE_OK; } -static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf, +static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { struct cf_ngtcp2_ctx *ctx = cf->ctx; - struct SingleRequest *k = &data->req; - int rv = GETSOCK_BLANK; - struct h3_stream_ctx *stream = H3_STREAM_CTX(data); - struct cf_call_data save; - - CF_DATA_SAVE(save, cf, data); - socks[0] = ctx->q.sockfd; + bool want_recv = CURL_WANT_RECV(data); + bool want_send = CURL_WANT_SEND(data); - /* in HTTP/3 we can always get a frame, so check read */ - rv |= GETSOCK_READSOCK(0); - - /* we're still uploading or the HTTP/2 layer wants to send data */ - if((k->keepon & KEEP_SENDBITS) == KEEP_SEND && - ngtcp2_conn_get_cwnd_left(ctx->qconn) && - ngtcp2_conn_get_max_data_left(ctx->qconn) && - stream && nghttp3_conn_is_stream_writable(ctx->h3conn, stream->id)) - rv |= GETSOCK_WRITESOCK(0); - - CF_DATA_RESTORE(cf, save); - return rv; -} - -static void h3_drain_stream(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct h3_stream_ctx *stream = H3_STREAM_CTX(data); - unsigned char bits; + if(ctx->qconn && (want_recv || want_send)) { + struct h3_stream_ctx *stream = H3_STREAM_CTX(data); + struct cf_call_data save; + bool c_exhaust, s_exhaust; - (void)cf; - bits = CURL_CSELECT_IN; - if(stream && stream->upload_left && !stream->send_closed) - bits |= CURL_CSELECT_OUT; - if(data->state.dselect_bits != bits) { - data->state.dselect_bits = bits; - Curl_expire(data, 0, EXPIRE_RUN_NOW); + CF_DATA_SAVE(save, cf, data); + c_exhaust = !ngtcp2_conn_get_cwnd_left(ctx->qconn) || + !ngtcp2_conn_get_max_data_left(ctx->qconn); + s_exhaust = stream && stream->id >= 0 && stream->quic_flow_blocked; + want_recv = (want_recv || c_exhaust || s_exhaust); + 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); + CF_DATA_RESTORE(cf, save); } } @@ -1141,7 +1203,6 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, else { CURL_TRC_CF(data, cf, "[%" PRId64 "] CLOSED", stream->id); } - data->req.keepon &= ~KEEP_SEND_HOLD; h3_drain_stream(cf, data); return 0; } @@ -1570,15 +1631,9 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id, /* Everything ACKed, we resume upload processing */ if(!stream->sendbuf_len_in_flight) { int rv = nghttp3_conn_resume_stream(conn, stream_id); - if(rv) { + if(rv && rv != NGHTTP3_ERR_STREAM_NOT_FOUND) { return NGTCP2_ERR_CALLBACK_FAILURE; } - if((data->req.keepon & KEEP_SEND_HOLD) && - (data->req.keepon & KEEP_SEND)) { - data->req.keepon &= ~KEEP_SEND_HOLD; - h3_drain_stream(cf, data); - CURL_TRC_CF(data, cf, "[%" PRId64 "] unpausing acks", stream_id); - } } return 0; } @@ -1676,6 +1731,10 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, goto out; stream = H3_STREAM_CTX(data); DEBUGASSERT(stream); + if(!stream) { + *err = CURLE_FAILED_INIT; + goto out; + } nwritten = Curl_h1_req_parse_read(&stream->h1, buf, len, NULL, 0, err); if(nwritten < 0) @@ -1711,7 +1770,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf, nva[i].flags = NGHTTP3_NV_FLAG_NONE; } - rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &stream->id, NULL); + rc = ngtcp2_conn_open_bidi_stream(ctx->qconn, &stream->id, data); if(rc) { failf(data, "can get bidi streams"); *err = CURLE_SEND_ERROR; @@ -1860,15 +1919,13 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, if(stream && sent > 0 && stream->sendbuf_len_in_flight) { /* We have unacknowledged DATA and cannot report success to our * caller. Instead we EAGAIN and remember how much we have already - * "written" into our various internal connection buffers. - * We put the stream upload on HOLD, until this gets ACKed. */ + * "written" into our various internal connection buffers. */ stream->upload_blocked_len = sent; CURL_TRC_CF(data, cf, "[%" PRId64 "] cf_send(len=%zu), " "%zu bytes in flight -> EGAIN", stream->id, len, stream->sendbuf_len_in_flight); *err = CURLE_AGAIN; sent = -1; - data->req.keepon |= KEEP_SEND_HOLD; } out: @@ -1887,40 +1944,37 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_ngtcp2_ctx *ctx = cf->ctx; + struct ssl_primary_config *conn_config; CURLcode result = CURLE_OK; - const char *hostname, *disp_hostname; - int port; - char *snihost; - Curl_conn_get_host(data, cf->sockindex, &hostname, &disp_hostname, &port); - snihost = Curl_ssl_snihost(data, hostname, NULL); - if(!snihost) - return CURLE_PEER_FAILED_VERIFICATION; + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) + return CURLE_FAILED_INIT; cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->httpversion = 30; cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; - if(cf->conn->ssl_config.verifyhost) { + if(conn_config->verifyhost) { #ifdef USE_OPENSSL X509 *server_cert; - server_cert = SSL_get_peer_certificate(ctx->ssl); + server_cert = SSL_get1_peer_certificate(ctx->ssl); if(!server_cert) { return CURLE_PEER_FAILED_VERIFICATION; } - result = Curl_ossl_verifyhost(data, cf->conn, server_cert); + result = Curl_ossl_verifyhost(data, cf->conn, &ctx->peer, server_cert); X509_free(server_cert); if(result) return result; #elif defined(USE_GNUTLS) result = Curl_gtls_verifyserver(data, ctx->gtls->session, - &cf->conn->ssl_config, &data->set.ssl, - hostname, disp_hostname, + conn_config, &data->set.ssl, &ctx->peer, data->set.str[STRING_SSL_PINNEDPUBLICKEY]); if(result) return result; #elif defined(USE_WOLFSSL) - if(wolfSSL_check_domain_name(ctx->ssl, snihost) == SSL_FAILURE) + if(!ctx->peer.sni || + wolfSSL_check_domain_name(ctx->ssl, ctx->peer.sni) == SSL_FAILURE) return CURLE_PEER_FAILED_VERIFICATION; #endif infof(data, "Verified certificate just fine"); @@ -1955,8 +2009,8 @@ static CURLcode recv_pkt(const unsigned char *pkt, size_t pktlen, rv = ngtcp2_conn_read_pkt(ctx->qconn, &path, &pi, pkt, pktlen, pktx->ts); if(rv) { - CURL_TRC_CF(pktx->data, pktx->cf, "ingress, read_pkt -> %s", - ngtcp2_strerror(rv)); + CURL_TRC_CF(pktx->data, pktx->cf, "ingress, read_pkt -> %s (%d)", + ngtcp2_strerror(rv), rv); if(!ctx->last_error.error_code) { if(rv == NGTCP2_ERR_CRYPTO) { ngtcp2_ccerr_set_tls_alert(&ctx->last_error, @@ -1993,7 +2047,7 @@ static CURLcode cf_progress_ingress(struct Curl_cfilter *cf, pktx = &local_pktx; } else { - pktx->ts = timestamp(); + pktx_update_time(pktx, cf); } #ifdef USE_OPENSSL @@ -2081,11 +2135,18 @@ static ssize_t read_pkt_to_send(void *userp, } else if(n < 0) { switch(n) { - case NGTCP2_ERR_STREAM_DATA_BLOCKED: + case NGTCP2_ERR_STREAM_DATA_BLOCKED: { + struct h3_stream_ctx *stream = H3_STREAM_CTX(x->data); DEBUGASSERT(ndatalen == -1); nghttp3_conn_block_stream(ctx->h3conn, stream_id); + CURL_TRC_CF(x->data, x->cf, "[%" PRId64 "] block quic flow", + stream_id); + DEBUGASSERT(stream); + if(stream) + stream->quic_flow_blocked = TRUE; n = 0; break; + } case NGTCP2_ERR_STREAM_SHUT_WR: DEBUGASSERT(ndatalen == -1); nghttp3_conn_shutdown_stream_write(ctx->h3conn, stream_id); @@ -2145,7 +2206,7 @@ static CURLcode cf_progress_egress(struct Curl_cfilter *cf, pktx = &local_pktx; } else { - pktx->ts = timestamp(); + pktx_update_time(pktx, cf); ngtcp2_path_storage_zero(&pktx->ps); } @@ -2282,10 +2343,12 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf, case CF_CTRL_DATA_PAUSE: result = h3_data_pause(cf, data, (arg1 != 0)); break; - case CF_CTRL_DATA_DONE: { + case CF_CTRL_DATA_DETACH: + h3_data_done(cf, data); + break; + case CF_CTRL_DATA_DONE: h3_data_done(cf, data); break; - } case CF_CTRL_DATA_DONE_SEND: { struct h3_stream_ctx *stream = H3_STREAM_CTX(data); if(stream && !stream->send_closed) { @@ -2344,6 +2407,7 @@ static void cf_ngtcp2_ctx_clear(struct cf_ngtcp2_ctx *ctx) if(ctx->qconn) ngtcp2_conn_del(ctx->qconn); Curl_bufcp_free(&ctx->stream_bufcp); + Curl_ssl_peer_cleanup(&ctx->peer); memset(ctx, 0, sizeof(*ctx)); ctx->qlogfd = -1; @@ -2358,15 +2422,15 @@ static void cf_ngtcp2_close(struct Curl_cfilter *cf, struct Curl_easy *data) CF_DATA_SAVE(save, cf, data); if(ctx && ctx->qconn) { char buffer[NGTCP2_MAX_UDP_PAYLOAD_SIZE]; - ngtcp2_tstamp ts; + struct pkt_io_ctx pktx; ngtcp2_ssize rc; CURL_TRC_CF(data, cf, "close"); - ts = timestamp(); + pktx_init(&pktx, cf, data); rc = ngtcp2_conn_write_connection_close(ctx->qconn, NULL, /* path */ NULL, /* pkt_info */ (uint8_t *)buffer, sizeof(buffer), - &ctx->last_error, ts); + &ctx->last_error, pktx.ts); if(rc > 0) { while((send(ctx->q.sockfd, buffer, (SEND_TYPE_ARG3)rc, 0) == -1) && SOCKERRNO == EINTR); @@ -2411,9 +2475,14 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, ctx->version = NGTCP2_PROTO_VER_MAX; ctx->max_stream_window = H3_STREAM_WINDOW_SIZE; + ctx->max_idle_ms = CURL_QUIC_MAX_IDLE_MS; Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, H3_STREAM_POOL_SPARES); + result = Curl_ssl_peer_init(&ctx->peer, cf); + if(result) + return result; + #ifdef USE_OPENSSL result = quic_ssl_ctx(&ctx->sslctx, cf, data); if(result) @@ -2559,27 +2628,9 @@ static CURLcode cf_ngtcp2_connect(struct Curl_cfilter *cf, ngtcp2_conn_in_draining_period(ctx->qconn)) { /* When a QUIC server instance is shutting down, it may send us a * CONNECTION_CLOSE right away. Our connection then enters the DRAINING - * state. - * This may be a stopping of the service or it may be that the server - * is reloading and a new instance will start serving soon. - * In any case, we tear down our socket and start over with a new one. - * We re-open the underlying UDP cf right now, but do not start - * connecting until called again. - */ - int reconn_delay_ms = 200; - - CURL_TRC_CF(data, cf, "connect, remote closed, reconnect after %dms", - reconn_delay_ms); - Curl_conn_cf_close(cf->next, data); - cf_ngtcp2_ctx_clear(ctx); - result = Curl_conn_cf_connect(cf->next, data, FALSE, done); - if(!result && *done) { - *done = FALSE; - ctx->reconnect_at = now; - ctx->reconnect_at.tv_usec += reconn_delay_ms * 1000; - Curl_expire(data, reconn_delay_ms, EXPIRE_QUIC); - result = CURLE_OK; - } + * state. The CONNECT may work in the near future again. Indicate + * that as a "weird" reply. */ + result = CURLE_WEIRD_SERVER_REPLY; } #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -2657,24 +2708,51 @@ static bool cf_ngtcp2_conn_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data, bool *input_pending) { - bool alive = TRUE; + struct cf_ngtcp2_ctx *ctx = cf->ctx; + bool alive = FALSE; + const ngtcp2_transport_params *rp; + struct cf_call_data save; + CF_DATA_SAVE(save, cf, data); *input_pending = FALSE; + if(!ctx->qconn) + goto out; + + /* Both sides of the QUIC connection announce they max idle times in + * the transport parameters. Look at the minimum of both and if + * we exceed this, regard the connection as dead. The other side + * may have completely purged it and will no longer respond + * to any packets from us. */ + rp = ngtcp2_conn_get_remote_transport_params(ctx->qconn); + if(rp) { + timediff_t idletime; + uint64_t idle_ms = ctx->max_idle_ms; + + if(rp->max_idle_timeout && + (rp->max_idle_timeout / NGTCP2_MILLISECONDS) < idle_ms) + idle_ms = (rp->max_idle_timeout / NGTCP2_MILLISECONDS); + idletime = Curl_timediff(Curl_now(), ctx->q.last_io); + if(idletime > 0 && (uint64_t)idletime > idle_ms) + goto out; + } + if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) - return FALSE; + goto out; + alive = TRUE; if(*input_pending) { + CURLcode result; /* This happens before we've sent off a request and the connection is not in use by any other transfer, there shouldn't be any data here, only "protocol frames" */ *input_pending = FALSE; - if(cf_progress_ingress(cf, data, NULL)) - alive = FALSE; - else { - alive = TRUE; - } + result = cf_progress_ingress(cf, data, NULL); + CURL_TRC_CF(data, cf, "is_alive, progress ingress -> %d", result); + alive = result? FALSE : TRUE; } +out: + CF_DATA_RESTORE(cf, save); return alive; } @@ -2686,7 +2764,7 @@ struct Curl_cftype Curl_cft_http3 = { cf_ngtcp2_connect, cf_ngtcp2_close, Curl_cf_def_get_host, - cf_ngtcp2_get_select_socks, + cf_ngtcp2_adjust_pollset, cf_ngtcp2_data_pending, cf_ngtcp2_send, cf_ngtcp2_recv, @@ -2706,7 +2784,7 @@ CURLcode Curl_cf_ngtcp2_create(struct Curl_cfilter **pcf, CURLcode result; (void)data; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c index 3f5d32743..7123d63ca 100644 --- a/lib/vquic/curl_quiche.c +++ b/lib/vquic/curl_quiche.c @@ -55,10 +55,10 @@ #include "curl_memory.h" #include "memdebug.h" -/* #define DEBUG_QUICHE */ +/* HTTP/3 error values defined in RFC 9114, ch. 8.1 */ +#define CURL_H3_NO_ERROR (0x0100) #define QUIC_MAX_STREAMS (100) -#define QUIC_IDLE_TIMEOUT (60 * 1000) /* milliseconds */ #define H3_STREAM_WINDOW_SIZE (128 * 1024) #define H3_STREAM_CHUNK_SIZE (16 * 1024) @@ -92,6 +92,7 @@ static void keylog_callback(const SSL *ssl, const char *line) struct cf_quiche_ctx { struct cf_quic_ctx q; + struct ssl_peer peer; quiche_conn *qconn; quiche_config *cfg; quiche_h3_conn *h3c; @@ -105,7 +106,7 @@ struct cf_quiche_ctx { struct curltime reconnect_at; /* time the next attempt should start */ struct bufc_pool stream_bufcp; /* chunk pool for streams */ curl_off_t data_recvd; - size_t sends_on_hold; /* # of streams with SEND_HOLD set */ + uint64_t max_idle_ms; /* max idle time for QUIC conn */ BIT(goaway); /* got GOAWAY from server */ BIT(got_first_byte); /* if first byte was received */ BIT(x509_store_setup); /* if x509 store has been set up */ @@ -132,6 +133,8 @@ static void cf_quiche_ctx_clear(struct cf_quiche_ctx *ctx) if(ctx->cfg) quiche_config_free(ctx->cfg); Curl_bufcp_free(&ctx->stream_bufcp); + Curl_ssl_peer_cleanup(&ctx->peer); + memset(ctx, 0, sizeof(*ctx)); } } @@ -140,11 +143,16 @@ static CURLcode quic_x509_store_setup(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_quiche_ctx *ctx = cf->ctx; + struct ssl_primary_config *conn_config; + + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) + return CURLE_FAILED_INIT; if(!ctx->x509_store_setup) { - if(cf->conn->ssl_config.verifypeer) { - const char * const ssl_cafile = cf->conn->ssl_config.CAfile; - const char * const ssl_capath = cf->conn->ssl_config.CApath; + if(conn_config->verifypeer) { + const char * const ssl_cafile = conn_config->CAfile; + const char * const ssl_capath = conn_config->CApath; if(ssl_cafile || ssl_capath) { SSL_CTX_set_verify(ctx->sslctx, SSL_VERIFY_PEER, NULL); /* tell OpenSSL where to find CA certificates that are used to verify @@ -177,9 +185,16 @@ static CURLcode quic_x509_store_setup(struct Curl_cfilter *cf, static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_quiche_ctx *ctx = cf->ctx; - unsigned char checkip[16]; - struct connectdata *conn = data->conn; - const char *curves = conn->ssl_config.curves; + struct ssl_primary_config *conn_config; + CURLcode result; + + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) + return CURLE_FAILED_INIT; + + result = Curl_ssl_peer_init(&ctx->peer, cf); + if(result) + return result; DEBUGASSERT(!ctx->sslctx); ctx->sslctx = SSL_CTX_new(TLS_method()); @@ -198,8 +213,10 @@ static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data) SSL_CTX_set_keylog_callback(ctx->sslctx, keylog_callback); } - if(curves && !SSL_CTX_set1_curves_list(ctx->sslctx, curves)) { - failf(data, "failed setting curves list for QUIC: '%s'", curves); + if(conn_config->curves && + !SSL_CTX_set1_curves_list(ctx->sslctx, conn_config->curves)) { + failf(data, "failed setting curves list for QUIC: '%s'", + conn_config->curves); return CURLE_SSL_CIPHER; } @@ -209,13 +226,8 @@ static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data) SSL_set_app_data(ctx->ssl, cf); - if((0 == Curl_inet_pton(AF_INET, cf->conn->host.name, checkip)) -#ifdef ENABLE_IPV6 - && (0 == Curl_inet_pton(AF_INET6, cf->conn->host.name, checkip)) -#endif - ) { - char *snihost = Curl_ssl_snihost(data, cf->conn->host.name, NULL); - if(!snihost || !SSL_set_tlsext_host_name(ctx->ssl, snihost)) { + if(ctx->peer.sni) { + if(!SSL_set_tlsext_host_name(ctx->ssl, ctx->peer.sni)) { failf(data, "Failed set SNI"); SSL_free(ctx->ssl); ctx->ssl = NULL; @@ -240,6 +252,7 @@ struct stream_ctx { bool send_closed; /* stream is locally closed */ bool resp_hds_complete; /* complete, final response has been received */ bool resp_got_header; /* TRUE when h3 stream has recvd some HEADER */ + BIT(quic_flow_blocked); /* stream is blocked by QUIC flow control */ }; #define H3_STREAM_CTX(d) ((struct stream_ctx *)(((d) && (d)->req.p.http)? \ @@ -249,56 +262,20 @@ struct stream_ctx { #define H3_STREAM_ID(d) (H3_STREAM_CTX(d)? \ H3_STREAM_CTX(d)->id : -2) -static bool stream_send_is_suspended(struct Curl_easy *data) -{ - return (data->req.keepon & KEEP_SEND_HOLD); -} - -static void stream_send_suspend(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - - if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) { - data->req.keepon |= KEEP_SEND_HOLD; - ++ctx->sends_on_hold; - if(H3_STREAM_ID(data) >= 0) - CURL_TRC_CF(data, cf, "[%"PRId64"] suspend sending", - H3_STREAM_ID(data)); - else - CURL_TRC_CF(data, cf, "[%s] suspend sending", data->state.url); - } -} - -static void stream_send_resume(struct Curl_cfilter *cf, - struct Curl_easy *data) -{ - struct cf_quiche_ctx *ctx = cf->ctx; - - if(stream_send_is_suspended(data)) { - data->req.keepon &= ~KEEP_SEND_HOLD; - --ctx->sends_on_hold; - if(H3_STREAM_ID(data) >= 0) - CURL_TRC_CF(data, cf, "[%"PRId64"] resume sending", - H3_STREAM_ID(data)); - else - CURL_TRC_CF(data, cf, "[%s] resume sending", data->state.url); - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } -} - static void check_resumes(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct cf_quiche_ctx *ctx = cf->ctx; struct Curl_easy *sdata; - - if(ctx->sends_on_hold) { - DEBUGASSERT(data->multi); - for(sdata = data->multi->easyp; - sdata && ctx->sends_on_hold; sdata = sdata->next) { - if(stream_send_is_suspended(sdata)) { - stream_send_resume(cf, sdata); + struct stream_ctx *stream; + + DEBUGASSERT(data->multi); + for(sdata = data->multi->easyp; sdata; sdata = sdata->next) { + if(sdata->conn == data->conn) { + stream = H3_STREAM_CTX(sdata); + if(stream && stream->quic_flow_blocked) { + stream->quic_flow_blocked = FALSE; + Curl_expire(data, 0, EXPIRE_RUN_NOW); + CURL_TRC_CF(data, cf, "[%"PRId64"] unblock", stream->id); } } } @@ -333,9 +310,15 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data) (void)cf; if(stream) { CURL_TRC_CF(data, cf, "[%"PRId64"] easy handle is done", stream->id); - if(stream_send_is_suspended(data)) { - data->req.keepon &= ~KEEP_SEND_HOLD; - --ctx->sends_on_hold; + if(ctx->qconn && !stream->closed) { + quiche_conn_stream_shutdown(ctx->qconn, stream->id, + QUICHE_SHUTDOWN_READ, CURL_H3_NO_ERROR); + if(!stream->send_closed) { + quiche_conn_stream_shutdown(ctx->qconn, stream->id, + QUICHE_SHUTDOWN_WRITE, CURL_H3_NO_ERROR); + stream->send_closed = TRUE; + } + stream->closed = TRUE; } Curl_bufq_free(&stream->recvbuf); Curl_h1_req_parse_free(&stream->h1); @@ -590,7 +573,6 @@ static CURLcode h3_process_event(struct Curl_cfilter *cf, } stream->closed = TRUE; streamclose(cf->conn, "End of stream"); - data->req.keepon &= ~KEEP_SEND_HOLD; break; case QUICHE_H3_EVENT_GOAWAY: @@ -883,6 +865,8 @@ static ssize_t cf_quiche_recv(struct Curl_cfilter *cf, struct Curl_easy *data, ssize_t nread = -1; CURLcode result; + vquic_ctx_update_time(&ctx->q); + if(!stream) { *err = CURLE_RECV_ERROR; return -1; @@ -1035,9 +1019,8 @@ static ssize_t h3_open_stream(struct Curl_cfilter *cf, 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, "send_request(%s) rejected with BLOCKED", - data->state.url); - stream_send_suspend(cf, data); + CURL_TRC_CF(data, cf, "[%"PRId64"] blocked", stream->id); + stream->quic_flow_blocked = TRUE; *err = CURLE_AGAIN; nwritten = -1; goto out; @@ -1081,6 +1064,8 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, CURLcode result; ssize_t nwritten; + vquic_ctx_update_time(&ctx->q); + *err = cf_process_ingress(cf, data); if(*err) { nwritten = -1; @@ -1104,7 +1089,7 @@ static ssize_t cf_quiche_send(struct Curl_cfilter *cf, struct Curl_easy *data, if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) { CURL_TRC_CF(data, cf, "[%" PRId64 "] send_body(len=%zu) " "-> window exhausted", stream->id, len); - stream_send_suspend(cf, data); + stream->quic_flow_blocked = TRUE; } *err = CURLE_AGAIN; nwritten = -1; @@ -1173,30 +1158,32 @@ static bool stream_is_writeable(struct Curl_cfilter *cf, struct cf_quiche_ctx *ctx = cf->ctx; struct stream_ctx *stream = H3_STREAM_CTX(data); - return stream && - quiche_conn_stream_writable(ctx->qconn, (uint64_t)stream->id, 1); + return stream && (quiche_conn_stream_writable(ctx->qconn, + (uint64_t)stream->id, 1) > 0); } -static int cf_quiche_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks) +static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { struct cf_quiche_ctx *ctx = cf->ctx; - struct SingleRequest *k = &data->req; - int rv = GETSOCK_BLANK; - - socks[0] = ctx->q.sockfd; + bool want_recv = CURL_WANT_RECV(data); + bool want_send = CURL_WANT_SEND(data); - /* in an HTTP/3 connection we can basically always get a frame so we should - always be ready for one */ - rv |= GETSOCK_READSOCK(0); + if(ctx->qconn && (want_recv || want_send)) { + struct stream_ctx *stream = H3_STREAM_CTX(data); + bool c_exhaust, s_exhaust; - /* we're still uploading or the HTTP/3 layer wants to send data */ - if(((k->keepon & KEEP_SENDBITS) == KEEP_SEND) - && stream_is_writeable(cf, data)) - rv |= GETSOCK_WRITESOCK(0); + c_exhaust = FALSE; /* Have not found any call in quiche that tells + us if the connection itself is blocked */ + s_exhaust = stream && stream->id >= 0 && + (stream->quic_flow_blocked || !stream_is_writeable(cf, data)); + want_recv = (want_recv || c_exhaust || s_exhaust); + want_send = (!s_exhaust && want_send) || + !Curl_bufq_is_empty(&ctx->q.sendbuf); - return rv; + Curl_pollset_set(data, ps, ctx->q.sockfd, want_recv, want_send); + } } /* @@ -1238,10 +1225,12 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf, case CF_CTRL_DATA_PAUSE: result = h3_data_pause(cf, data, (arg1 != 0)); break; - case CF_CTRL_DATA_DONE: { + case CF_CTRL_DATA_DETACH: + h3_data_done(cf, data); + break; + case CF_CTRL_DATA_DONE: h3_data_done(cf, data); break; - } case CF_CTRL_DATA_DONE_SEND: { struct stream_ctx *stream = H3_STREAM_CTX(data); if(stream && !stream->send_closed) { @@ -1276,20 +1265,25 @@ static CURLcode cf_verify_peer(struct Curl_cfilter *cf, struct Curl_easy *data) { struct cf_quiche_ctx *ctx = cf->ctx; + struct ssl_primary_config *conn_config; CURLcode result = CURLE_OK; + conn_config = Curl_ssl_cf_get_primary_config(cf); + if(!conn_config) + return CURLE_FAILED_INIT; + cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->httpversion = 30; cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; - if(cf->conn->ssl_config.verifyhost) { + if(conn_config->verifyhost) { X509 *server_cert; server_cert = SSL_get_peer_certificate(ctx->ssl); if(!server_cert) { result = CURLE_PEER_FAILED_VERIFICATION; goto out; } - result = Curl_ossl_verifyhost(data, cf->conn, server_cert); + result = Curl_ossl_verifyhost(data, cf->conn, &ctx->peer, server_cert); X509_free(server_cert); if(result) goto out; @@ -1345,6 +1339,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, debug_log_init = 1; } #endif + ctx->max_idle_ms = CURL_QUIC_MAX_IDLE_MS; Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE, H3_STREAM_POOL_SPARES); ctx->data_recvd = 0; @@ -1359,7 +1354,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, return CURLE_FAILED_INIT; } quiche_config_enable_pacing(ctx->cfg, false); - quiche_config_set_max_idle_timeout(ctx->cfg, QUIC_IDLE_TIMEOUT); + quiche_config_set_max_idle_timeout(ctx->cfg, ctx->max_idle_ms * 1000); quiche_config_set_initial_max_data(ctx->cfg, (1 * 1024 * 1024) /* (QUIC_MAX_STREAMS/2) * H3_STREAM_WINDOW_SIZE */); quiche_config_set_initial_max_streams_bidi(ctx->cfg, QUIC_MAX_STREAMS); @@ -1411,7 +1406,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, } /* Known to not work on Windows */ -#if !defined(WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD) +#if !defined(_WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD) { int qfd; (void)Curl_qlogdir(data, ctx->scid, sizeof(ctx->scid), &qfd); @@ -1449,7 +1444,6 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, { struct cf_quiche_ctx *ctx = cf->ctx; CURLcode result = CURLE_OK; - struct curltime now; if(cf->connected) { *done = TRUE; @@ -1464,9 +1458,10 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, } *done = FALSE; - now = Curl_now(); + vquic_ctx_update_time(&ctx->q); - if(ctx->reconnect_at.tv_sec && Curl_timediff(now, ctx->reconnect_at) < 0) { + if(ctx->reconnect_at.tv_sec && + Curl_timediff(ctx->q.last_op, ctx->reconnect_at) < 0) { /* Not time yet to attempt the next connect */ CURL_TRC_CF(data, cf, "waiting for reconnect time"); goto out; @@ -1476,7 +1471,7 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, result = cf_connect_start(cf, data); if(result) goto out; - ctx->started_at = now; + ctx->started_at = ctx->q.last_op; result = cf_flush_egress(cf, data); /* we do not expect to be able to recv anything yet */ goto out; @@ -1491,9 +1486,9 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, goto out; if(quiche_conn_is_established(ctx->qconn)) { + ctx->handshake_at = ctx->q.last_op; CURL_TRC_CF(data, cf, "handshake complete after %dms", - (int)Curl_timediff(now, ctx->started_at)); - ctx->handshake_at = now; + (int)Curl_timediff(ctx->handshake_at, ctx->started_at)); result = cf_verify_peer(cf, data); if(!result) { CURL_TRC_CF(data, cf, "peer verified"); @@ -1506,27 +1501,9 @@ static CURLcode cf_quiche_connect(struct Curl_cfilter *cf, else if(quiche_conn_is_draining(ctx->qconn)) { /* When a QUIC server instance is shutting down, it may send us a * CONNECTION_CLOSE right away. Our connection then enters the DRAINING - * state. - * This may be a stopping of the service or it may be that the server - * is reloading and a new instance will start serving soon. - * In any case, we tear down our socket and start over with a new one. - * We re-open the underlying UDP cf right now, but do not start - * connecting until called again. - */ - int reconn_delay_ms = 200; - - CURL_TRC_CF(data, cf, "connect, remote closed, reconnect after %dms", - reconn_delay_ms); - Curl_conn_cf_close(cf->next, data); - cf_quiche_ctx_clear(ctx); - result = Curl_conn_cf_connect(cf->next, data, FALSE, done); - if(!result && *done) { - *done = FALSE; - ctx->reconnect_at = Curl_now(); - ctx->reconnect_at.tv_usec += reconn_delay_ms * 1000; - Curl_expire(data, reconn_delay_ms, EXPIRE_QUIC); - result = CURLE_OK; - } + * state. The CONNECT may work in the near future again. Indicate + * that as a "weird" reply. */ + result = CURLE_WEIRD_SERVER_REPLY; } out: @@ -1550,6 +1527,7 @@ static void cf_quiche_close(struct Curl_cfilter *cf, struct Curl_easy *data) if(ctx) { if(ctx->qconn) { + vquic_ctx_update_time(&ctx->q); (void)quiche_conn_close(ctx->qconn, TRUE, 0, NULL, 0); /* flushing the egress is not a failsafe way to deliver all the outstanding packets, but we also don't want to get stuck here... */ @@ -1617,9 +1595,32 @@ static bool cf_quiche_conn_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data, bool *input_pending) { + struct cf_quiche_ctx *ctx = cf->ctx; bool alive = TRUE; *input_pending = FALSE; + if(!ctx->qconn) + return FALSE; + + /* Both sides of the QUIC connection announce they max idle times in + * the transport parameters. Look at the minimum of both and if + * we exceed this, regard the connection as dead. The other side + * may have completely purged it and will no longer respond + * to any packets from us. */ + { + quiche_transport_params qpeerparams; + timediff_t idletime; + uint64_t idle_ms = ctx->max_idle_ms; + + if(quiche_conn_peer_transport_params(ctx->qconn, &qpeerparams) && + qpeerparams.peer_max_idle_timeout && + qpeerparams.peer_max_idle_timeout < idle_ms) + idle_ms = qpeerparams.peer_max_idle_timeout; + idletime = Curl_timediff(Curl_now(), cf->conn->lastused); + if(idletime > 0 && (uint64_t)idletime > idle_ms) + return FALSE; + } + if(!cf->next || !cf->next->cft->is_alive(cf->next, data, input_pending)) return FALSE; @@ -1646,7 +1647,7 @@ struct Curl_cftype Curl_cft_http3 = { cf_quiche_connect, cf_quiche_close, Curl_cf_def_get_host, - cf_quiche_get_select_socks, + cf_quiche_adjust_pollset, cf_quiche_data_pending, cf_quiche_send, cf_quiche_recv, @@ -1667,7 +1668,7 @@ CURLcode Curl_cf_quiche_create(struct Curl_cfilter **pcf, (void)data; (void)conn; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c index 9a1a1bbb3..523b807bc 100644 --- a/lib/vquic/vquic.c +++ b/lib/vquic/vquic.c @@ -100,6 +100,7 @@ CURLcode vquic_ctx_init(struct cf_quic_ctx *qctx) } } #endif + vquic_ctx_update_time(qctx); return CURLE_OK; } @@ -109,6 +110,11 @@ void vquic_ctx_free(struct cf_quic_ctx *qctx) Curl_bufq_free(&qctx->sendbuf); } +void vquic_ctx_update_time(struct cf_quic_ctx *qctx) +{ + qctx->last_op = Curl_now(); +} + static CURLcode send_packet_no_gso(struct Curl_cfilter *cf, struct Curl_easy *data, struct cf_quic_ctx *qctx, @@ -242,6 +248,7 @@ static CURLcode vquic_send_packets(struct Curl_cfilter *cf, const uint8_t *pkt, size_t pktlen, size_t gsolen, size_t *psent) { + CURLcode result; #ifdef DEBUGBUILD /* simulate network blocking/partial writes */ if(qctx->wblock_percent > 0) { @@ -254,10 +261,14 @@ static CURLcode vquic_send_packets(struct Curl_cfilter *cf, } #endif if(qctx->no_gso && pktlen > gsolen) { - return send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent); + result = send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent); } - - return do_sendmsg(cf, data, qctx, pkt, pktlen, gsolen, psent); + else { + result = do_sendmsg(cf, data, qctx, pkt, pktlen, gsolen, psent); + } + if(!result) + qctx->last_io = qctx->last_op; + return result; } CURLcode vquic_flush(struct Curl_cfilter *cf, struct Curl_easy *data, @@ -524,13 +535,17 @@ CURLcode vquic_recv_packets(struct Curl_cfilter *cf, size_t max_pkts, vquic_recv_pkt_cb *recv_cb, void *userp) { + CURLcode result; #if defined(HAVE_SENDMMSG) - return recvmmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); + result = recvmmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); #elif defined(HAVE_SENDMSG) - return recvmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); + result = recvmsg_packets(cf, data, qctx, max_pkts, recv_cb, userp); #else - return recvfrom_packets(cf, data, qctx, max_pkts, recv_cb, userp); + result = recvfrom_packets(cf, data, qctx, max_pkts, recv_cb, userp); #endif + if(!result) + qctx->last_io = qctx->last_op; + return result; } /* diff --git a/lib/vquic/vquic_int.h b/lib/vquic/vquic_int.h index dbcd009d7..a820f39ae 100644 --- a/lib/vquic/vquic_int.h +++ b/lib/vquic/vquic_int.h @@ -31,6 +31,8 @@ #define MAX_PKT_BURST 10 #define MAX_UDP_PAYLOAD_SIZE 1452 +/* Default QUIC connection timeout we announce from our side */ +#define CURL_QUIC_MAX_IDLE_MS (120 * 1000) struct cf_quic_ctx { curl_socket_t sockfd; /* connected UDP socket */ @@ -38,6 +40,8 @@ struct cf_quic_ctx { socklen_t local_addrlen; /* length of local address */ struct bufq sendbuf; /* buffer for sending one or more packets */ + struct curltime last_op; /* last (attempted) send/recv operation */ + struct curltime last_io; /* last successful socket IO */ size_t gsolen; /* length of individual packets in send buf */ size_t split_len; /* if != 0, buffer length after which GSO differs */ size_t split_gsolen; /* length of individual packets after split_len */ @@ -50,6 +54,8 @@ struct cf_quic_ctx { CURLcode vquic_ctx_init(struct cf_quic_ctx *qctx); void vquic_ctx_free(struct cf_quic_ctx *qctx); +void vquic_ctx_update_time(struct cf_quic_ctx *qctx); + void vquic_push_blocked_pkt(struct Curl_cfilter *cf, struct cf_quic_ctx *qctx, const uint8_t *pkt, size_t pktlen, size_t gsolen); diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index b0f49d60c..97143c477 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -93,6 +93,7 @@ #if defined(__GNUC__) && \ (LIBSSH_VERSION_MINOR >= 10) || \ (LIBSSH_VERSION_MAJOR > 0) +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -1159,13 +1160,23 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } else if(statvfs) { + #ifdef _MSC_VER + #define LIBSSH_VFS_SIZE_MASK "I64u" + #else + #define LIBSSH_VFS_SIZE_MASK PRIu64 + #endif char *tmp = aprintf("statvfs:\n" - "f_bsize: %llu\n" "f_frsize: %llu\n" - "f_blocks: %llu\n" "f_bfree: %llu\n" - "f_bavail: %llu\n" "f_files: %llu\n" - "f_ffree: %llu\n" "f_favail: %llu\n" - "f_fsid: %llu\n" "f_flag: %llu\n" - "f_namemax: %llu\n", + "f_bsize: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_frsize: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_blocks: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_bfree: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_bavail: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_files: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_ffree: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_favail: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_fsid: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_flag: %" LIBSSH_VFS_SIZE_MASK "\n" + "f_namemax: %" LIBSSH_VFS_SIZE_MASK "\n", statvfs->f_bsize, statvfs->f_frsize, statvfs->f_blocks, statvfs->f_bfree, statvfs->f_bavail, statvfs->f_files, @@ -1466,13 +1477,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_STOP); break; } - /* since this counts what we send to the client, we include the - newline in this counter */ - data->req.bytecount += sshc->readdir_len + 1; - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_OUT, (char *)sshc->readdir_filename, - sshc->readdir_len); } else { if(Curl_dyn_add(&sshc->readdir_buf, sshc->readdir_longentry)) { @@ -1564,12 +1569,6 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) Curl_dyn_ptr(&sshc->readdir_buf), Curl_dyn_len(&sshc->readdir_buf)); - if(!result) { - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_OUT, Curl_dyn_ptr(&sshc->readdir_buf), - Curl_dyn_len(&sshc->readdir_buf)); - data->req.bytecount += Curl_dyn_len(&sshc->readdir_buf); - } ssh_string_free_char(sshc->readdir_tmp); sshc->readdir_tmp = NULL; @@ -1963,10 +1962,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) ssh_disconnect(sshc->ssh_session); if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) { /* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back, - explicitly mark it as closed with the memdebug macro. This libssh + tell the connection to forget about it. This libssh bug is fixed in 0.10.0. */ - fake_sclose(conn->sock[FIRSTSOCKET]); - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; + Curl_conn_forget_socket(data, FIRSTSOCKET); } SSH_STRING_FREE_CHAR(sshc->homedir); @@ -2959,4 +2957,10 @@ void Curl_ssh_version(char *buffer, size_t buflen) (void)msnprintf(buffer, buflen, "libssh/%s", ssh_version(0)); } +#if defined(__GNUC__) && \ + (LIBSSH_VERSION_MINOR >= 10) || \ + (LIBSSH_VERSION_MAJOR > 0) +#pragma GCC diagnostic pop +#endif + #endif /* USE_LIBSSH */ diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index f539b393b..11f5f4fd5 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -1537,139 +1537,137 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_SFTP_NEXT_QUOTE); 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 command '%s', missing parameter", - cmd); + + /* + * 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 command '%s', missing parameter", + cmd); + state(data, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + + /* + * 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 to '%s'", cmd); + state(data, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + + /* + * SFTP is a binary protocol, so we don't send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh2 + * functions. + */ + if(strncasecompare(cmd, "chgrp ", 6) || + strncasecompare(cmd, "chmod ", 6) || + strncasecompare(cmd, "chown ", 6) || + strncasecompare(cmd, "atime ", 6) || + strncasecompare(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 %s: Bad second parameter", cmd); + Curl_safefree(sshc->quote_path1); state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + sshc->actualcode = result; break; } - - /* - * 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); + memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + state(data, SSH_SFTP_QUOTE_STAT); + break; + } + if(strncasecompare(cmd, "ln ", 3) || + strncasecompare(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: Bad first parameter to '%s'", cmd); + failf(data, + "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; break; } - - /* - * SFTP is a binary protocol, so we don't send text commands - * to the server. Instead, we scan for commands used by - * OpenSSH's sftp program and call the appropriate libssh2 - * functions. - */ - if(strncasecompare(cmd, "chgrp ", 6) || - strncasecompare(cmd, "chmod ", 6) || - strncasecompare(cmd, "chown ", 6) || - strncasecompare(cmd, "atime ", 6) || - strncasecompare(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 %s: Bad second parameter", cmd); - Curl_safefree(sshc->quote_path1); - state(data, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - state(data, SSH_SFTP_QUOTE_STAT); - break; - } - if(strncasecompare(cmd, "ln ", 3) || - strncasecompare(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); - state(data, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - state(data, SSH_SFTP_QUOTE_SYMLINK); - break; - } - else if(strncasecompare(cmd, "mkdir ", 6)) { - /* create dir */ - state(data, SSH_SFTP_QUOTE_MKDIR); - break; - } - else if(strncasecompare(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); - state(data, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - state(data, SSH_SFTP_QUOTE_RENAME); - break; - } - else if(strncasecompare(cmd, "rmdir ", 6)) { - /* delete dir */ - state(data, SSH_SFTP_QUOTE_RMDIR); - break; - } - else if(strncasecompare(cmd, "rm ", 3)) { - state(data, SSH_SFTP_QUOTE_UNLINK); + state(data, SSH_SFTP_QUOTE_SYMLINK); + break; + } + else if(strncasecompare(cmd, "mkdir ", 6)) { + /* create dir */ + state(data, SSH_SFTP_QUOTE_MKDIR); + break; + } + else if(strncasecompare(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); + state(data, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; break; } + state(data, SSH_SFTP_QUOTE_RENAME); + break; + } + else if(strncasecompare(cmd, "rmdir ", 6)) { + /* delete dir */ + state(data, SSH_SFTP_QUOTE_RMDIR); + break; + } + else if(strncasecompare(cmd, "rm ", 3)) { + state(data, SSH_SFTP_QUOTE_UNLINK); + break; + } #ifdef HAS_STATVFS_SUPPORT - else if(strncasecompare(cmd, "statvfs ", 8)) { - state(data, SSH_SFTP_QUOTE_STATVFS); - break; - } -#endif - - failf(data, "Unknown SFTP command"); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - state(data, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; + else if(strncasecompare(cmd, "statvfs ", 8)) { + state(data, SSH_SFTP_QUOTE_STATVFS); break; } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + state(data, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; } - break; case SSH_SFTP_NEXT_QUOTE: Curl_safefree(sshc->quote_path1); @@ -1962,13 +1960,23 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) break; } else if(rc == 0) { + #ifdef _MSC_VER + #define LIBSSH2_VFS_SIZE_MASK "I64u" + #else + #define LIBSSH2_VFS_SIZE_MASK "llu" + #endif char *tmp = aprintf("statvfs:\n" - "f_bsize: %llu\n" "f_frsize: %llu\n" - "f_blocks: %llu\n" "f_bfree: %llu\n" - "f_bavail: %llu\n" "f_files: %llu\n" - "f_ffree: %llu\n" "f_favail: %llu\n" - "f_fsid: %llu\n" "f_flag: %llu\n" - "f_namemax: %llu\n", + "f_bsize: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_frsize: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_blocks: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_bfree: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_bavail: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_files: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_ffree: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_favail: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_fsid: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_flag: %" LIBSSH2_VFS_SIZE_MASK "\n" + "f_namemax: %" LIBSSH2_VFS_SIZE_MASK "\n", statvfs.f_bsize, statvfs.f_frsize, statvfs.f_blocks, statvfs.f_bfree, statvfs.f_bavail, statvfs.f_files, @@ -2341,14 +2349,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_STOP); break; } - /* since this counts what we send to the client, we include the - newline in this counter */ - data->req.bytecount += readdir_len + 1; - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_IN, sshp->readdir_filename, - readdir_len); - Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1); } else { result = Curl_dyn_add(&sshp->readdir, sshp->readdir_longentry); @@ -2427,13 +2428,6 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) Curl_dyn_ptr(&sshp->readdir), Curl_dyn_len(&sshp->readdir)); - if(!result) { - /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_IN, - Curl_dyn_ptr(&sshp->readdir), - Curl_dyn_len(&sshp->readdir)); - data->req.bytecount += Curl_dyn_len(&sshp->readdir); - } if(result) { Curl_dyn_free(&sshp->readdir); state(data, SSH_STOP); diff --git a/lib/vssh/ssh.h b/lib/vssh/ssh.h index 1e1b1379c..ca0533aa5 100644 --- a/lib/vssh/ssh.h +++ b/lib/vssh/ssh.h @@ -267,6 +267,7 @@ void Curl_ssh_attach(struct Curl_easy *data, /* for non-SSH builds */ #define Curl_ssh_cleanup() #define Curl_ssh_attach(x,y) +#define Curl_ssh_init() 0 #endif #endif /* HEADER_CURL_SSH_H */ diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 39cee5076..4da7e9dea 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -343,9 +343,6 @@ static CURLcode wssh_setup_connection(struct Curl_easy *data, return CURLE_OK; } -static Curl_recv wscp_recv, wsftp_recv; -static Curl_send wscp_send, wsftp_send; - static int userauth(byte authtype, WS_UserAuthData* authdata, void *ctx) diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c index 934149c1b..a6566f4d9 100644 --- a/lib/vtls/bearssl.c +++ b/lib/vtls/bearssl.c @@ -582,17 +582,12 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, const char * const ssl_cafile = /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ (ca_info_blob ? NULL : conn_config->CAfile); - const char *hostname = connssl->hostname; + const char *hostname = connssl->peer.hostname; const bool verifypeer = conn_config->verifypeer; const bool verifyhost = conn_config->verifyhost; CURLcode ret; unsigned version_min, version_max; int session_set = 0; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif DEBUGASSERT(backend); CURL_TRC_CF(data, cf, "connect_step1"); @@ -706,11 +701,7 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); } - if((1 == Curl_inet_pton(AF_INET, hostname, &addr)) -#ifdef ENABLE_IPV6 - || (1 == Curl_inet_pton(AF_INET6, hostname, &addr)) -#endif - ) { + if(connssl->peer.is_ip_address) { if(verifyhost) { failf(data, "BearSSL: " "host verification of IP address is not supported"); @@ -719,12 +710,11 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, hostname = NULL; } else { - char *snihost = Curl_ssl_snihost(data, hostname, NULL); - if(!snihost) { + if(!connssl->peer.sni) { failf(data, "Failed to set SNI"); return CURLE_SSL_CONNECT_ERROR; } - hostname = snihost; + hostname = connssl->peer.sni; CURL_TRC_CF(data, cf, "connect_step1, SNI set"); } @@ -749,26 +739,26 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, return CURLE_OK; } -static int bearssl_get_select_socks(struct Curl_cfilter *cf, - struct Curl_easy *data, - curl_socket_t *socks) +static void bearssl_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) { - struct ssl_connect_data *connssl = cf->ctx; - curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); - - if(sock == CURL_SOCKET_BAD) - return GETSOCK_BLANK; - else { - struct bearssl_ssl_backend_data *backend = - (struct bearssl_ssl_backend_data *)connssl->backend; - unsigned state = br_ssl_engine_current_state(&backend->ctx.eng); - if(state & BR_SSL_SENDREC) { - socks[0] = sock; - return GETSOCK_WRITESOCK(0); + if(!cf->connected) { + curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); + if(sock != CURL_SOCKET_BAD) { + struct ssl_connect_data *connssl = cf->ctx; + struct bearssl_ssl_backend_data *backend = + (struct bearssl_ssl_backend_data *)connssl->backend; + unsigned state = br_ssl_engine_current_state(&backend->ctx.eng); + + if(state & BR_SSL_SENDREC) { + Curl_pollset_set_out_only(data, ps, sock); + } + else { + Curl_pollset_set_in_only(data, ps, sock); + } } } - socks[0] = sock; - return GETSOCK_READSOCK(0); } static CURLcode bearssl_run_until(struct Curl_cfilter *cf, @@ -1210,7 +1200,7 @@ const struct Curl_ssl Curl_ssl_bearssl = { Curl_none_cert_status_request, /* cert_status_request */ bearssl_connect, /* connect */ bearssl_connect_nonblocking, /* connect_nonblocking */ - bearssl_get_select_socks, /* getsock */ + bearssl_adjust_pollset, /* adjust_pollset */ bearssl_get_internals, /* get_internals */ bearssl_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index c538a966e..4e337f5dd 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -402,18 +402,13 @@ set_ssl_version_min_max(struct Curl_easy *data, CURLcode gtls_client_init(struct Curl_easy *data, struct ssl_primary_config *config, struct ssl_config_data *ssl_config, - const char *hostname, + struct ssl_peer *peer, struct gtls_instance *gtls, long *pverifyresult) { unsigned int init_flags; int rc; bool sni = TRUE; /* default is SNI enabled */ -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif const char *prioritylist; const char *err = NULL; const char *tls13support; @@ -460,50 +455,60 @@ CURLcode gtls_client_init(struct Curl_easy *data, } #endif - if(config->CAfile) { - /* set the trusted CA cert bundle file */ - gnutls_certificate_set_verify_flags(gtls->cred, - GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); + if(config->verifypeer) { + bool imported_native_ca = false; - rc = gnutls_certificate_set_x509_trust_file(gtls->cred, - config->CAfile, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)", - config->CAfile, gnutls_strerror(rc)); - if(config->verifypeer) { - *pverifyresult = rc; - return CURLE_SSL_CACERT_BADFILE; + if(ssl_config->native_ca_store) { + rc = gnutls_certificate_set_x509_system_trust(gtls->cred); + if(rc < 0) + infof(data, "error reading native ca store (%s), continuing anyway", + gnutls_strerror(rc)); + else { + infof(data, "found %d certificates in native ca store", rc); + if(rc > 0) + imported_native_ca = true; } } - else - infof(data, "found %d certificates in %s", rc, config->CAfile); - } - if(config->CApath) { - /* set the trusted CA cert directory */ - rc = gnutls_certificate_set_x509_trust_dir(gtls->cred, - config->CApath, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)", - config->CApath, gnutls_strerror(rc)); - if(config->verifypeer) { - *pverifyresult = rc; - return CURLE_SSL_CACERT_BADFILE; + if(config->CAfile) { + /* set the trusted CA cert bundle file */ + gnutls_certificate_set_verify_flags(gtls->cred, + GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); + + rc = gnutls_certificate_set_x509_trust_file(gtls->cred, + config->CAfile, + GNUTLS_X509_FMT_PEM); + if(rc < 0) { + infof(data, "error reading ca cert file %s (%s)%s", + config->CAfile, gnutls_strerror(rc), + (imported_native_ca ? ", continuing anyway" : "")); + if(!imported_native_ca) { + *pverifyresult = rc; + return CURLE_SSL_CACERT_BADFILE; + } } + else + infof(data, "found %d certificates in %s", rc, config->CAfile); } - else - infof(data, "found %d certificates in %s", rc, config->CApath); - } -#ifdef CURL_CA_FALLBACK - /* use system ca certificate store as fallback */ - if(config->verifypeer && !(config->CAfile || config->CApath)) { - /* this ignores errors on purpose */ - gnutls_certificate_set_x509_system_trust(gtls->cred); + if(config->CApath) { + /* set the trusted CA cert directory */ + rc = gnutls_certificate_set_x509_trust_dir(gtls->cred, + config->CApath, + GNUTLS_X509_FMT_PEM); + if(rc < 0) { + infof(data, "error reading ca cert file %s (%s)%s", + config->CApath, gnutls_strerror(rc), + (imported_native_ca ? ", continuing anyway" : "")); + if(!imported_native_ca) { + *pverifyresult = rc; + return CURLE_SSL_CACERT_BADFILE; + } + } + else + infof(data, "found %d certificates in %s", rc, config->CApath); + } } -#endif if(config->CRLfile) { /* set the CRL list file */ @@ -537,15 +542,9 @@ CURLcode gtls_client_init(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } - if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && -#ifdef ENABLE_IPV6 - (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && -#endif - sni) { - size_t snilen; - char *snihost = Curl_ssl_snihost(data, hostname, &snilen); - if(!snihost || gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS, - snihost, snilen) < 0) { + if(sni && peer->sni) { + if(gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS, + peer->sni, strlen(peer->sni)) < 0) { failf(data, "Failed to set SNI"); return CURLE_SSL_CONNECT_ERROR; } @@ -699,7 +698,7 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_OK; result = gtls_client_init(data, conn_config, ssl_config, - connssl->hostname, + &connssl->peer, &backend->gtls, pverifyresult); if(result) return result; @@ -811,8 +810,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, gnutls_session_t session, struct ssl_primary_config *config, struct ssl_config_data *ssl_config, - const char *hostname, - const char *dispname, + struct ssl_peer *peer, const char *pinned_key) { unsigned int cert_list_size; @@ -1068,7 +1066,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, in RFC2818 (HTTPS), which takes into account wildcards, and the subject alternative name PKIX extension. Returns non zero on success, and zero on failure. */ - rc = gnutls_x509_crt_check_hostname(x509_cert, hostname); + rc = gnutls_x509_crt_check_hostname(x509_cert, peer->hostname); #if GNUTLS_VERSION_NUMBER < 0x030306 /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP addresses. */ @@ -1081,10 +1079,10 @@ Curl_gtls_verifyserver(struct Curl_easy *data, unsigned char addrbuf[sizeof(struct use_addr)]; size_t addrlen = 0; - if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0) + if(Curl_inet_pton(AF_INET, peer->hostname, addrbuf) > 0) addrlen = 4; #ifdef ENABLE_IPV6 - else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0) + else if(Curl_inet_pton(AF_INET6, peer->hostname, addrbuf) > 0) addrlen = 16; #endif @@ -1114,13 +1112,13 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(!rc) { if(config->verifyhost) { failf(data, "SSL: certificate subject name (%s) does not match " - "target host name '%s'", certname, dispname); + "target host name '%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, dispname); + certname, peer->dispname); } else infof(data, " common name: %s (matched)", certname); @@ -1253,8 +1251,7 @@ static CURLcode gtls_verifyserver(struct Curl_cfilter *cf, CURLcode result; result = Curl_gtls_verifyserver(data, session, conn_config, ssl_config, - connssl->hostname, connssl->dispname, - pinned_key); + &connssl->peer, pinned_key); if(result) goto out; @@ -1662,7 +1659,7 @@ const struct Curl_ssl Curl_ssl_gnutls = { gtls_cert_status_request, /* cert_status_request */ gtls_connect, /* connect */ gtls_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_get_select_socks, /* getsock */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ gtls_get_internals, /* get_internals */ gtls_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h index ac141e1c6..1a81c01e9 100644 --- a/lib/vtls/gtls.h +++ b/lib/vtls/gtls.h @@ -43,6 +43,7 @@ struct Curl_easy; struct Curl_cfilter; struct ssl_primary_config; struct ssl_config_data; +struct ssl_peer; struct gtls_instance { gnutls_session_t session; @@ -56,7 +57,7 @@ CURLcode gtls_client_init(struct Curl_easy *data, struct ssl_primary_config *config, struct ssl_config_data *ssl_config, - const char *hostname, + struct ssl_peer *peer, struct gtls_instance *gtls, long *pverifyresult); @@ -65,8 +66,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, gnutls_session_t session, struct ssl_primary_config *config, struct ssl_config_data *ssl_config, - const char *hostname, - const char *dispname, + struct ssl_peer *peer, const char *pinned_key); extern const struct Curl_ssl Curl_ssl_gnutls; diff --git a/lib/vtls/keylog.c b/lib/vtls/keylog.c index d37bb183e..fbcb25cfb 100644 --- a/lib/vtls/keylog.c +++ b/lib/vtls/keylog.c @@ -23,6 +23,11 @@ ***************************************************************************/ #include "curl_setup.h" +#if defined(USE_OPENSSL) || \ + defined(USE_WOLFSSL) || \ + (defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || \ + defined(USE_QUICHE) + #include "keylog.h" #include @@ -55,7 +60,7 @@ Curl_tls_keylog_open(void) if(keylog_file_name) { keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); if(keylog_file_fp) { -#ifdef WIN32 +#ifdef _WIN32 if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) #else if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) @@ -157,3 +162,5 @@ Curl_tls_keylog_write(const char *label, fputs(line, keylog_file_fp); return true; } + +#endif /* TLS or QUIC backend */ diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 2f994d741..38f7de7f7 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -322,7 +322,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) char * const ssl_cert = ssl_config->primary.clientcert; const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; const char * const ssl_crlfile = ssl_config->primary.CRLfile; - const char *hostname = connssl->hostname; + const char *hostname = connssl->peer.hostname; int ret = -1; char errorbuf[128]; @@ -639,9 +639,9 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) mbedtls_ssl_conf_own_cert(&backend->config, &backend->clicert, &backend->pk); } - { - char *snihost = Curl_ssl_snihost(data, hostname, NULL); - if(!snihost || mbedtls_ssl_set_hostname(&backend->ssl, snihost)) { + + if(connssl->peer.sni) { + if(mbedtls_ssl_set_hostname(&backend->ssl, connssl->peer.sni)) { /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and the name to set in the SNI extension. So even if curl connects to a host specified as an IP address, this function must be used. */ @@ -1274,7 +1274,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = { Curl_none_cert_status_request, /* cert_status_request */ mbedtls_connect, /* connect */ mbedtls_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_get_select_socks, /* getsock */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ mbedtls_get_internals, /* get_internals */ mbedtls_close, /* close_one */ mbedtls_close_all, /* close_all */ diff --git a/lib/vtls/mbedtls_threadlock.c b/lib/vtls/mbedtls_threadlock.c index bcb7106a6..22b1b221e 100644 --- a/lib/vtls/mbedtls_threadlock.c +++ b/lib/vtls/mbedtls_threadlock.c @@ -51,7 +51,7 @@ int Curl_mbedtlsthreadlock_thread_setup(void) { int i; - mutex_buf = calloc(NUMT * sizeof(MBEDTLS_MUTEX_T), 1); + mutex_buf = calloc(1, NUMT * sizeof(MBEDTLS_MUTEX_T)); if(!mutex_buf) return 0; /* error, no number of threads defined */ diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 9f9c8d136..8c8f43e83 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -79,6 +79,8 @@ #include #include #include +#include +#include #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) #include @@ -96,6 +98,9 @@ #include "curl_memory.h" #include "memdebug.h" +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif /* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS renegotiations when built with BoringSSL. Renegotiating is non-compliant @@ -173,8 +178,6 @@ #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) #define HAVE_EVP_PKEY_GET_PARAMS 1 -#else -#define SSL_get1_peer_certificate SSL_get_peer_certificate #endif #ifdef HAVE_EVP_PKEY_GET_PARAMS @@ -235,7 +238,11 @@ #elif defined(OPENSSL_IS_AWSLC) #define OSSL_PACKAGE "AWS-LC" #else -#define OSSL_PACKAGE "OpenSSL" +# if defined(USE_NGTCP2) && defined(USE_NGHTTP3) +# define OSSL_PACKAGE "quictls" +# else +# define OSSL_PACKAGE "OpenSSL" +#endif #endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) @@ -538,9 +545,9 @@ CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) #else RSA_get0_key(rsa, &n, &e, NULL); #endif /* HAVE_EVP_PKEY_GET_PARAMS */ - BIO_printf(mem, "%d", BN_num_bits(n)); + BIO_printf(mem, "%d", n ? BN_num_bits(n) : 0); #else - BIO_printf(mem, "%d", BN_num_bits(rsa->n)); + BIO_printf(mem, "%d", rsa->n ? BN_num_bits(rsa->n) : 0); #endif /* HAVE_OPAQUE_RSA_DSA_DH */ push_certinfo("RSA Public Key", i); print_pubkey_BN(rsa, n, i); @@ -2098,22 +2105,6 @@ static bool subj_alt_hostcheck(struct Curl_easy *data, return FALSE; } -static CURLcode -ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - X509 *server_cert, const char *hostname, - const char *dispname); - -CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - X509 *server_cert) -{ - const char *hostname, *dispname; - int port; - - (void)conn; - Curl_conn_get_host(data, FIRSTSOCKET, &hostname, &dispname, &port); - return ossl_verifyhost(data, conn, server_cert, hostname, dispname); -} - /* Quote from RFC2818 section 3.1 "Server Identity" If a subjectAltName extension of type dNSName is present, that MUST @@ -2136,10 +2127,8 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, This function is now used from ngtcp2 (QUIC) as well. */ -static CURLcode -ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - X509 *server_cert, const char *hostname, - const char *dispname) +CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, + struct ssl_peer *peer, X509 *server_cert) { bool matched = FALSE; int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */ @@ -2156,25 +2145,21 @@ ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, size_t hostlen; (void)conn; - hostlen = strlen(hostname); - -#ifndef ENABLE_IPV6 - /* Silence compiler warnings for unused params */ - (void) conn; -#endif - + hostlen = strlen(peer->hostname); + if(peer->is_ip_address) { #ifdef ENABLE_IPV6 - if(conn->bits.ipv6_ip && - Curl_inet_pton(AF_INET6, hostname, &addr)) { - target = GEN_IPADD; - addrlen = sizeof(struct in6_addr); - } - else -#endif - if(Curl_inet_pton(AF_INET, hostname, &addr)) { + if(conn->bits.ipv6_ip && + Curl_inet_pton(AF_INET6, peer->hostname, &addr)) { target = GEN_IPADD; - addrlen = sizeof(struct in_addr); + addrlen = sizeof(struct in6_addr); } + else +#endif + if(Curl_inet_pton(AF_INET, peer->hostname, &addr)) { + target = GEN_IPADD; + addrlen = sizeof(struct in_addr); + } + } /* get a "list" of alternative names */ altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); @@ -2224,9 +2209,9 @@ ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, if((altlen == strlen(altptr)) && /* if this isn't true, there was an embedded zero in the name string and we cannot match it. */ - subj_alt_hostcheck(data, - altptr, - altlen, hostname, hostlen, dispname)) { + subj_alt_hostcheck(data, altptr, altlen, + peer->hostname, hostlen, + peer->dispname)) { dnsmatched = TRUE; } break; @@ -2238,7 +2223,7 @@ ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, ipmatched = TRUE; infof(data, " subjectAltName: host \"%s\" matched cert's IP address!", - dispname); + peer->dispname); } break; } @@ -2254,9 +2239,9 @@ ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, /* an alternative name matched */ ; else if(dNSName || iPAddress) { - infof(data, " subjectAltName does not match %s", dispname); + infof(data, " subjectAltName does not match %s", peer->dispname); failf(data, "SSL: no alternative certificate subject name matches " - "target host name '%s'", dispname); + "target host name '%s'", peer->dispname); result = CURLE_PEER_FAILED_VERIFICATION; } else { @@ -2320,9 +2305,9 @@ ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, result = CURLE_PEER_FAILED_VERIFICATION; } else if(!Curl_cert_hostcheck((const char *)peer_CN, - peerlen, hostname, hostlen)) { + peerlen, peer->hostname, hostlen)) { failf(data, "SSL: certificate subject name '%s' does not match " - "target host name '%s'", peer_CN, dispname); + "target host name '%s'", peer_CN, peer->dispname); result = CURLE_PEER_FAILED_VERIFICATION; } else { @@ -2731,12 +2716,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type, #ifdef USE_OPENSSL /* ====================================================== */ -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -# define use_sni(x) sni = (x) -#else -# define use_sni(x) Curl_nop_stmt -#endif - /* Check for OpenSSL 1.0.2 which has ALPN support. */ #undef HAS_ALPN #if OPENSSL_VERSION_NUMBER >= 0x10002000L \ @@ -3032,6 +3011,151 @@ static CURLcode load_cacert_from_memory(X509_STORE *store, return (count > 0) ? CURLE_OK : CURLE_SSL_CACERT_BADFILE; } +#if defined(USE_WIN32_CRYPTO) +static CURLcode import_windows_cert_store(struct Curl_easy *data, + const char *name, + X509_STORE *store, + bool *imported) +{ + CURLcode result = CURLE_OK; + HCERTSTORE hStore; + + *imported = false; + + hStore = CertOpenSystemStoreA(0, name); + if(hStore) { + PCCERT_CONTEXT pContext = NULL; + /* The array of enhanced key usage OIDs will vary per certificate and + is declared outside of the loop so that rather than malloc/free each + iteration we can grow it with realloc, when necessary. */ + CERT_ENHKEY_USAGE *enhkey_usage = NULL; + DWORD enhkey_usage_size = 0; + + /* This loop makes a best effort to import all valid certificates from + the MS root store. If a certificate cannot be imported it is + skipped. 'result' is used to store only hard-fail conditions (such + as out of memory) that cause an early break. */ + result = CURLE_OK; + for(;;) { + X509 *x509; + FILETIME now; + BYTE key_usage[2]; + DWORD req_size; + const unsigned char *encoded_cert; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + char cert_name[256]; +#endif + + pContext = CertEnumCertificatesInStore(hStore, pContext); + if(!pContext) + break; + +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, + NULL, cert_name, sizeof(cert_name))) { + strcpy(cert_name, "Unknown"); + } + infof(data, "SSL: Checking cert \"%s\"", cert_name); +#endif + encoded_cert = (const unsigned char *)pContext->pbCertEncoded; + if(!encoded_cert) + continue; + + GetSystemTimeAsFileTime(&now); + if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 || + CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0) + continue; + + /* If key usage exists check for signing attribute */ + if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType, + pContext->pCertInfo, + key_usage, sizeof(key_usage))) { + if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE)) + continue; + } + else if(GetLastError()) + continue; + + /* If enhanced key usage exists check for server auth attribute. + * + * Note "In a Microsoft environment, a certificate might also have + * EKU extended properties that specify valid uses for the + * certificate." The call below checks both, and behavior varies + * depending on what is found. For more details see + * CertGetEnhancedKeyUsage doc. + */ + if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) { + if(req_size && req_size > enhkey_usage_size) { + void *tmp = realloc(enhkey_usage, req_size); + + if(!tmp) { + failf(data, "SSL: Out of memory allocating for OID list"); + result = CURLE_OUT_OF_MEMORY; + break; + } + + enhkey_usage = (CERT_ENHKEY_USAGE *)tmp; + enhkey_usage_size = req_size; + } + + if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) { + if(!enhkey_usage->cUsageIdentifier) { + /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate + is good for all uses. If it returns zero, the certificate + has no valid uses." */ + if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND) + continue; + } + else { + DWORD i; + bool found = false; + + for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) { + if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */, + enhkey_usage->rgpszUsageIdentifier[i])) { + found = true; + break; + } + } + + if(!found) + continue; + } + } + else + continue; + } + else + continue; + + x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); + if(!x509) + continue; + + /* Try to import the certificate. This may fail for legitimate + reasons such as duplicate certificate, which is allowed by MS but + not OpenSSL. */ + if(X509_STORE_add_cert(store, x509) == 1) { +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + infof(data, "SSL: Imported cert \"%s\"", cert_name); +#endif + *imported = true; + } + X509_free(x509); + } + + free(enhkey_usage); + CertFreeCertificateContext(pContext); + CertCloseStore(hStore, 0); + + if(result) + return result; + } + + return result; +} +#endif + static CURLcode populate_x509_store(struct Curl_cfilter *cf, struct Curl_easy *data, X509_STORE *store) @@ -3061,140 +3185,25 @@ static CURLcode populate_x509_store(struct Curl_cfilter *cf, https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037 https://datatracker.ietf.org/doc/html/rfc5280 */ if(ssl_config->native_ca_store) { - HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT")); - - if(hStore) { - PCCERT_CONTEXT pContext = NULL; - /* The array of enhanced key usage OIDs will vary per certificate and - is declared outside of the loop so that rather than malloc/free each - iteration we can grow it with realloc, when necessary. */ - CERT_ENHKEY_USAGE *enhkey_usage = NULL; - DWORD enhkey_usage_size = 0; - - /* This loop makes a best effort to import all valid certificates from - the MS root store. If a certificate cannot be imported it is - skipped. 'result' is used to store only hard-fail conditions (such - as out of memory) that cause an early break. */ - result = CURLE_OK; - for(;;) { - X509 *x509; - FILETIME now; - BYTE key_usage[2]; - DWORD req_size; - const unsigned char *encoded_cert; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - char cert_name[256]; -#endif - - pContext = CertEnumCertificatesInStore(hStore, pContext); - if(!pContext) - break; - -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, - NULL, cert_name, sizeof(cert_name))) { - strcpy(cert_name, "Unknown"); - } - infof(data, "SSL: Checking cert \"%s\"", cert_name); -#endif - encoded_cert = (const unsigned char *)pContext->pbCertEncoded; - if(!encoded_cert) - continue; - - GetSystemTimeAsFileTime(&now); - if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 || - CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0) - continue; - - /* If key usage exists check for signing attribute */ - if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType, - pContext->pCertInfo, - key_usage, sizeof(key_usage))) { - if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE)) - continue; - } - else if(GetLastError()) - continue; - - /* If enhanced key usage exists check for server auth attribute. - * - * Note "In a Microsoft environment, a certificate might also have - * EKU extended properties that specify valid uses for the - * certificate." The call below checks both, and behavior varies - * depending on what is found. For more details see - * CertGetEnhancedKeyUsage doc. - */ - if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) { - if(req_size && req_size > enhkey_usage_size) { - void *tmp = realloc(enhkey_usage, req_size); - - if(!tmp) { - failf(data, "SSL: Out of memory allocating for OID list"); - result = CURLE_OUT_OF_MEMORY; - break; - } - - enhkey_usage = (CERT_ENHKEY_USAGE *)tmp; - enhkey_usage_size = req_size; - } - - if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) { - if(!enhkey_usage->cUsageIdentifier) { - /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate - is good for all uses. If it returns zero, the certificate - has no valid uses." */ - if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND) - continue; - } - else { - DWORD i; - bool found = false; - - for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) { - if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */, - enhkey_usage->rgpszUsageIdentifier[i])) { - found = true; - break; - } - } - - if(!found) - continue; - } - } - else - continue; - } - else - continue; - - x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); - if(!x509) - continue; - - /* Try to import the certificate. This may fail for legitimate - reasons such as duplicate certificate, which is allowed by MS but - not OpenSSL. */ - if(X509_STORE_add_cert(store, x509) == 1) { -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - infof(data, "SSL: Imported cert \"%s\"", cert_name); -#endif - imported_native_ca = true; - } - X509_free(x509); - } - - free(enhkey_usage); - CertFreeCertificateContext(pContext); - CertCloseStore(hStore, 0); - + const char *storeNames[] = { + "ROOT", /* Trusted Root Certification Authorities */ + "CA" /* Intermediate Certification Authorities */ + }; + size_t i; + for(i = 0; i < ARRAYSIZE(storeNames); ++i) { + bool imported = false; + result = import_windows_cert_store(data, storeNames[i], store, + &imported); if(result) return result; + if(imported) { + infof(data, "successfully imported Windows %s store", storeNames[i]); + imported_native_ca = true; + } + else + infof(data, "error importing Windows %s store, continuing anyway", + storeNames[i]); } - if(imported_native_ca) - infof(data, "successfully imported Windows CA store"); - else - infof(data, "error importing Windows CA store, continuing anyway"); } #endif if(ca_info_blob) { @@ -3210,7 +3219,7 @@ static CURLcode populate_x509_store(struct Curl_cfilter *cf, } if(ssl_cafile || ssl_capath) { -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ if(ssl_cafile && !X509_STORE_load_file(store, ssl_cafile)) { if(!imported_native_ca && !imported_ca_info_blob) { @@ -3339,6 +3348,7 @@ static X509_STORE *get_cached_x509_store(struct Curl_cfilter *cf, struct Curl_multi *multi = data->multi_easy ? data->multi_easy : data->multi; X509_STORE *store = NULL; + DEBUGASSERT(multi); if(multi && multi->ssl_backend_data && multi->ssl_backend_data->store && @@ -3358,6 +3368,7 @@ static void set_cached_x509_store(struct Curl_cfilter *cf, struct Curl_multi *multi = data->multi_easy ? data->multi_easy : data->multi; struct multi_ssl_backend_data *mbackend; + DEBUGASSERT(multi); if(!multi) return; @@ -3449,17 +3460,6 @@ static CURLcode ossl_connect_step1(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); BIO *bio; - -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - bool sni; - const char *hostname = connssl->hostname; - -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif -#endif const long int ssl_version = conn_config->version; char * const ssl_cert = ssl_config->primary.clientcert; const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; @@ -3494,7 +3494,6 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, #else req_method = SSLv23_client_method(); #endif - use_sni(TRUE); break; case CURL_SSLVERSION_SSLv2: failf(data, "No SSLv2 support"); @@ -3787,13 +3786,8 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, backend->server_cert = 0x0; #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && -#ifdef ENABLE_IPV6 - (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && -#endif - sni) { - char *snihost = Curl_ssl_snihost(data, hostname, NULL); - if(!snihost || !SSL_set_tlsext_host_name(backend->handle, snihost)) { + if(connssl->peer.sni) { + if(!SSL_set_tlsext_host_name(backend->handle, connssl->peer.sni)) { failf(data, "Failed set SNI"); return CURLE_SSL_CONNECT_ERROR; } @@ -3802,6 +3796,7 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, SSL_set_app_data(backend->handle, cf); + connssl->reused_session = FALSE; if(ssl_config->primary.sessionid) { Curl_ssl_sessionid_lock(data); if(!Curl_ssl_getsessionid(cf, data, &ssl_sessionid, NULL)) { @@ -3815,6 +3810,7 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, } /* Informational message */ infof(data, "SSL reusing session ID"); + connssl->reused_session = TRUE; } Curl_ssl_sessionid_unlock(data); } @@ -3975,7 +3971,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, Curl_strerror(sockerr, extramsg, sizeof(extramsg)); failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%d ", extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), - connssl->hostname, connssl->port); + connssl->peer.hostname, connssl->port); return result; } @@ -3986,13 +3982,28 @@ 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're not waiting for anything else. */ connssl->connecting_state = ssl_connect_3; +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + SSL_get_peer_signature_type_nid(backend->handle, &psigtype_nid); +#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) + negotiated_group_name = SSL_get0_group_name(backend->handle); +#else + negotiated_group_name = + OBJ_nid2sn(SSL_get_negotiated_group(backend->handle) & 0x0000FFFF); +#endif +#endif + /* Informational message */ - infof(data, "SSL connection using %s / %s", + infof(data, "SSL connection using %s / %s / %s / %s", SSL_get_version(backend->handle), - SSL_get_cipher(backend->handle)); + SSL_get_cipher(backend->handle), + negotiated_group_name? negotiated_group_name : "[blank]", + OBJ_nid2sn(psigtype_nid)); #ifdef HAS_ALPN /* Sets data and len to negotiated protocol, len is 0 if no protocol was @@ -4069,6 +4080,75 @@ static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert, return result; } +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x3060000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) && \ + !defined(OPENSSL_IS_AWSLC) && \ + !defined(CURL_DISABLE_VERBOSE_STRINGS) +static void infof_certstack(struct Curl_easy *data, const SSL *ssl) +{ + STACK_OF(X509) *certstack; + long verify_result; + int num_cert_levels; + int cert_level; + + verify_result = SSL_get_verify_result(ssl); + if(verify_result != X509_V_OK) + certstack = SSL_get_peer_cert_chain(ssl); + else + certstack = SSL_get0_verified_chain(ssl); + num_cert_levels = sk_X509_num(certstack); + + for(cert_level = 0; cert_level < num_cert_levels; cert_level++) { + char cert_algorithm[80] = ""; + char group_name_final[80] = ""; + const X509_ALGOR *palg_cert = NULL; + const ASN1_OBJECT *paobj_cert = NULL; + X509 *current_cert; + EVP_PKEY *current_pkey; + int key_bits; + int key_sec_bits; + int get_group_name; + const char *type_name; + + current_cert = sk_X509_value(certstack, cert_level); + + X509_get0_signature(NULL, &palg_cert, current_cert); + X509_ALGOR_get0(&paobj_cert, NULL, NULL, palg_cert); + OBJ_obj2txt(cert_algorithm, sizeof(cert_algorithm), paobj_cert, 0); + + current_pkey = X509_get0_pubkey(current_cert); + key_bits = EVP_PKEY_bits(current_pkey); +#if (OPENSSL_VERSION_NUMBER < 0x30000000L) +#define EVP_PKEY_get_security_bits EVP_PKEY_security_bits +#endif + key_sec_bits = EVP_PKEY_get_security_bits(current_pkey); +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) + { + char group_name[80] = ""; + get_group_name = EVP_PKEY_get_group_name(current_pkey, group_name, + sizeof(group_name), NULL); + msnprintf(group_name_final, sizeof(group_name_final), "/%s", group_name); + } + type_name = EVP_PKEY_get0_type_name(current_pkey); +#else + get_group_name = 0; + type_name = NULL; +#endif + + infof(data, + " Certificate level %d: " + "Public key type %s%s (%d/%d Bits/secBits), signed using %s", + cert_level, type_name ? type_name : "?", + get_group_name == 0 ? "" : group_name_final, + key_bits, key_sec_bits, cert_algorithm); + } +} +#else +#define infof_certstack(data, ssl) +#endif + /* * Get the server cert, verify it and show it, etc., only call failf() if the * 'strict' argument is TRUE as otherwise all this is for informational @@ -4147,8 +4227,8 @@ static CURLcode servercert(struct Curl_cfilter *cf, BIO_free(mem); if(conn_config->verifyhost) { - result = ossl_verifyhost(data, conn, backend->server_cert, - connssl->hostname, connssl->dispname); + result = Curl_ossl_verifyhost(data, conn, &connssl->peer, + backend->server_cert); if(result) { X509_free(backend->server_cert); backend->server_cert = NULL; @@ -4258,9 +4338,12 @@ static CURLcode servercert(struct Curl_cfilter *cf, infof(data, " SSL certificate verify ok."); } + infof_certstack(data, backend->handle); + #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ !defined(OPENSSL_NO_OCSP) - if(conn_config->verifystatus) { + if(conn_config->verifystatus && !connssl->reused_session) { + /* don't do this after Session ID reuse */ result = verifystatus(cf, data); if(result) { X509_free(backend->server_cert); @@ -4522,22 +4605,9 @@ static ssize_t ossl_send(struct Curl_cfilter *cf, case SSL_ERROR_SSL: { /* A failure in the SSL library occurred, usually a protocol error. The OpenSSL error queue contains more information on the error. */ - struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next); - struct ssl_connect_data *connssl_next = cf_ssl_next? - cf_ssl_next->ctx : NULL; sslerror = ERR_get_error(); - if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL && - ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET && - connssl->state == ssl_connection_complete && - (connssl_next && connssl_next->state == ssl_connection_complete) - ) { - char ver[120]; - (void)ossl_version(ver, sizeof(ver)); - failf(data, "Error: %s does not support double SSL tunneling.", ver); - } - else - failf(data, "SSL_write() error: %s", - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); + failf(data, "SSL_write() error: %s", + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); *curlcode = CURLE_SEND_ERROR; rc = -1; goto out; @@ -4842,7 +4912,7 @@ const struct Curl_ssl Curl_ssl_openssl = { ossl_cert_status_request, /* cert_status_request */ ossl_connect, /* connect */ ossl_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_get_select_socks,/* getsock */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ ossl_get_internals, /* get_internals */ ossl_close, /* close_one */ ossl_close_all, /* close_all */ diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h index 950faab88..e802363a4 100644 --- a/lib/vtls/openssl.h +++ b/lib/vtls/openssl.h @@ -31,24 +31,21 @@ * This header should only be needed to get included by vtls.c, openssl.c * and ngtcp2.c */ +#include #include #include "urldata.h" -/* - * In an effort to avoid using 'X509 *' here, we instead use the struct - * x509_st version of the type so that we can forward-declare it here without - * having to include . Including that header causes name - * conflicts when libcurl is built with both Schannel and OpenSSL support. - */ -struct x509_st; +#if (OPENSSL_VERSION_NUMBER < 0x30000000L) +#define SSL_get1_peer_certificate SSL_get_peer_certificate +#endif + CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn, - struct x509_st *server_cert); + struct ssl_peer *peer, X509 *server_cert); extern const struct Curl_ssl Curl_ssl_openssl; -struct ssl_ctx_st; CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data, - struct ssl_ctx_st *ctx, char *cert_file, + 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, @@ -65,5 +62,9 @@ CURLcode Curl_ssl_setup_x509_store(struct Curl_cfilter *cf, struct Curl_easy *data, SSL_CTX *ssl_ctx); +CURLcode Curl_ossl_ctx_configure(struct Curl_cfilter *cf, + struct Curl_easy *data, + SSL_CTX *ssl_ctx); + #endif /* USE_OPENSSL */ #endif /* HEADER_CURL_SSLUSE_H */ diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index a3e9d964c..8751fd981 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -39,6 +39,7 @@ #include "select.h" #include "strerror.h" #include "multiif.h" +#include "connect.h" /* for the connect timeout */ struct rustls_ssl_backend_data { @@ -75,14 +76,6 @@ cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data) return backend->data_pending; } -static CURLcode -cr_connect(struct Curl_cfilter *cf UNUSED_PARAM, - struct Curl_easy *data UNUSED_PARAM) -{ - infof(data, "rustls_connect: unimplemented"); - return CURLE_SSL_CONNECT_ERROR; -} - struct io_ctx { struct Curl_cfilter *cf; struct Curl_easy *data; @@ -386,7 +379,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ (ca_info_blob ? NULL : conn_config->CAfile); const bool verifypeer = conn_config->verifypeer; - const char *hostname = connssl->hostname; + const char *hostname = connssl->peer.hostname; char errorbuf[256]; size_t errorlen; int result; @@ -458,12 +451,11 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, backend->config = rustls_client_config_builder_build(config_builder); DEBUGASSERT(rconn == NULL); { - char *snihost = Curl_ssl_snihost(data, hostname, NULL); - if(!snihost) { - failf(data, "rustls: failed to get SNI"); - return CURLE_SSL_CONNECT_ERROR; - } - result = rustls_client_connection_new(backend->config, snihost, &rconn); + /* rustls claims to manage ip address hostnames as well here. So, + * if we have an SNI, we use it, otherwise we pass the hostname */ + char *server = connssl->peer.sni? + connssl->peer.sni : connssl->peer.hostname; + result = rustls_client_connection_new(backend->config, server, &rconn); } if(result != RUSTLS_RESULT_OK) { rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen); @@ -486,9 +478,20 @@ cr_set_negotiated_alpn(struct Curl_cfilter *cf, struct Curl_easy *data, Curl_alpn_set_negotiated(cf, data, protocol, len); } +/* Given an established network connection, do a TLS handshake. + * + * If `blocking` is true, this function will block until the handshake is + * complete. Otherwise it will return as soon as I/O would block. + * + * For the non-blocking I/O case, this function will set `*done` to true + * once the handshake is complete. This function never reads the value of + * `*done*`. + */ static CURLcode -cr_connect_nonblocking(struct Curl_cfilter *cf, - struct Curl_easy *data, bool *done) +cr_connect_common(struct Curl_cfilter *cf, + struct Curl_easy *data, + bool blocking, + bool *done) { struct ssl_connect_data *const connssl = cf->ctx; curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); @@ -502,6 +505,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf, bool wants_write; curl_socket_t writefd; curl_socket_t readfd; + timediff_t timeout_ms; + timediff_t socket_check_timeout; DEBUGASSERT(backend); @@ -539,12 +544,29 @@ cr_connect_nonblocking(struct Curl_cfilter *cf, writefd = wants_write?sockfd:CURL_SOCKET_BAD; readfd = wants_read?sockfd:CURL_SOCKET_BAD; - what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, 0); + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "rustls: operation timed out before socket check"); + return CURLE_OPERATION_TIMEDOUT; + } + + socket_check_timeout = blocking?timeout_ms:0; + + what = Curl_socket_check( + readfd, CURL_SOCKET_BAD, writefd, socket_check_timeout); if(what < 0) { /* fatal error */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); return CURLE_SSL_CONNECT_ERROR; } + if(blocking && 0 == what) { + failf(data, "rustls connection timeout after %d ms", + socket_check_timeout); + return CURLE_OPERATION_TIMEDOUT; + } if(0 == what) { infof(data, "Curl_socket_check: %s would block", wants_read&&wants_write ? "writing and reading" : @@ -589,32 +611,43 @@ cr_connect_nonblocking(struct Curl_cfilter *cf, DEBUGASSERT(false); } -/* returns a bitmap of flags for this connection's first socket indicating - whether we want to read or write */ -static int -cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) +static CURLcode +cr_connect_nonblocking(struct Curl_cfilter *cf, + struct Curl_easy *data, bool *done) { - struct ssl_connect_data *const connssl = cf->ctx; - curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); - struct rustls_ssl_backend_data *const backend = - (struct rustls_ssl_backend_data *)connssl->backend; - struct rustls_connection *rconn = NULL; + return cr_connect_common(cf, data, false, done); +} - (void)data; - DEBUGASSERT(backend); - rconn = backend->conn; +static CURLcode +cr_connect_blocking(struct Curl_cfilter *cf UNUSED_PARAM, + struct Curl_easy *data UNUSED_PARAM) +{ + bool done; /* unused */ + return cr_connect_common(cf, data, true, &done); +} - if(rustls_connection_wants_write(rconn)) { - socks[0] = sockfd; - return GETSOCK_WRITESOCK(0); - } - if(rustls_connection_wants_read(rconn)) { - socks[0] = sockfd; - return GETSOCK_READSOCK(0); +static void cr_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) +{ + if(!cf->connected) { + curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); + 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; + + (void)data; + DEBUGASSERT(backend); + rconn = backend->conn; + + if(rustls_connection_wants_write(rconn)) { + Curl_pollset_add_out(data, ps, sock); + } + if(rustls_connection_wants_read(rconn)) { + Curl_pollset_add_in(data, ps, sock); + } } - - return GETSOCK_BLANK; } static void * @@ -675,9 +708,9 @@ const struct Curl_ssl Curl_ssl_rustls = { cr_data_pending, /* data_pending */ Curl_none_random, /* random */ Curl_none_cert_status_request, /* cert_status_request */ - cr_connect, /* connect */ + cr_connect_blocking, /* connect */ cr_connect_nonblocking, /* connect_nonblocking */ - cr_get_select_socks, /* get_select_socks */ + cr_adjust_pollset, /* adjust_pollset */ cr_get_internals, /* get_internals */ cr_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index 410a5c4ec..ae7f2956d 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -1063,17 +1063,12 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) #endif SECURITY_STATUS sspi_status = SEC_E_OK; struct Curl_schannel_cred *old_cred = NULL; - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif CURLcode result; - const char *hostname = connssl->hostname; DEBUGASSERT(backend); DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %d (step 1/3)", - hostname, connssl->port)); + connssl->peer.hostname, connssl->port)); if(curlx_verify_windows_version(5, 1, 0, PLATFORM_WINNT, VERSION_LESS_THAN_EQUAL)) { @@ -1154,22 +1149,14 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) /* A hostname associated with the credential is needed by InitializeSecurityContext for SNI and other reasons. */ - snihost = Curl_ssl_snihost(data, hostname, NULL); - if(!snihost) { - failf(data, "Failed to set SNI"); - return CURLE_SSL_CONNECT_ERROR; - } + snihost = connssl->peer.sni? connssl->peer.sni : connssl->peer.hostname; backend->cred->sni_hostname = curlx_convert_UTF8_to_tchar(snihost); if(!backend->cred->sni_hostname) return CURLE_OUT_OF_MEMORY; } /* Warn if SNI is disabled due to use of an IP address */ - if(Curl_inet_pton(AF_INET, hostname, &addr) -#ifdef ENABLE_IPV6 - || Curl_inet_pton(AF_INET6, hostname, &addr6) -#endif - ) { + if(connssl->peer.is_ip_address) { infof(data, "schannel: using IP address, SNI is not supported by OS."); } @@ -1346,7 +1333,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %d (step 2/3)", - connssl->hostname, connssl->port)); + connssl->peer.hostname, connssl->port)); if(!backend->cred || !backend->ctxt) return CURLE_SSL_CONNECT_ERROR; @@ -1700,7 +1687,7 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %d (step 3/3)", - connssl->hostname, connssl->port)); + connssl->peer.hostname, connssl->port)); if(!backend->cred) return CURLE_SSL_CONNECT_ERROR; @@ -2498,7 +2485,7 @@ static int schannel_shutdown(struct Curl_cfilter *cf, if(backend->ctxt) { infof(data, "schannel: shutting down SSL/TLS connection with %s port %d", - connssl->hostname, connssl->port); + connssl->peer.hostname, connssl->port); } if(backend->cred && backend->ctxt) { @@ -2754,6 +2741,151 @@ static void *schannel_get_internals(struct ssl_connect_data *connssl, return &backend->ctxt->ctxt_handle; } +HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf, + const struct Curl_easy *data) +{ + struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); + struct Curl_multi *multi = data->multi_easy ? data->multi_easy : data->multi; + const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; + struct schannel_multi_ssl_backend_data *mbackend; + const struct ssl_general_config *cfg = &data->set.general_ssl; + timediff_t timeout_ms; + timediff_t elapsed_ms; + struct curltime now; + unsigned char info_blob_digest[CURL_SHA256_DIGEST_LENGTH]; + + DEBUGASSERT(multi); + + if(!multi || !multi->ssl_backend_data) { + return NULL; + } + + mbackend = (struct schannel_multi_ssl_backend_data *)multi->ssl_backend_data; + if(!mbackend->cert_store) { + return NULL; + } + + /* zero ca_cache_timeout completely disables caching */ + if(!cfg->ca_cache_timeout) { + return NULL; + } + + /* check for cache timeout by using the cached_x509_store_expired timediff + calculation pattern from openssl.c. + negative timeout means retain forever. */ + timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; + if(timeout_ms >= 0) { + now = Curl_now(); + elapsed_ms = Curl_timediff(now, mbackend->time); + if(elapsed_ms >= timeout_ms) { + return NULL; + } + } + + if(ca_info_blob) { + if(!mbackend->CAinfo_blob_digest) { + return NULL; + } + if(mbackend->CAinfo_blob_size != ca_info_blob->len) { + return NULL; + } + schannel_sha256sum((const unsigned char *)ca_info_blob->data, + ca_info_blob->len, + info_blob_digest, + CURL_SHA256_DIGEST_LENGTH); + if(memcmp(mbackend->CAinfo_blob_digest, + info_blob_digest, + CURL_SHA256_DIGEST_LENGTH)) { + return NULL; + } + } + else { + if(!conn_config->CAfile || !mbackend->CAfile || + strcmp(mbackend->CAfile, conn_config->CAfile)) { + return NULL; + } + } + + return mbackend->cert_store; +} + +bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, + const struct Curl_easy *data, + HCERTSTORE cert_store) +{ + struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); + struct Curl_multi *multi = data->multi_easy ? data->multi_easy : data->multi; + const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; + struct schannel_multi_ssl_backend_data *mbackend; + unsigned char *CAinfo_blob_digest = NULL; + size_t CAinfo_blob_size = 0; + char *CAfile = NULL; + + DEBUGASSERT(multi); + + if(!multi) { + return false; + } + + if(!multi->ssl_backend_data) { + multi->ssl_backend_data = + calloc(1, sizeof(struct schannel_multi_ssl_backend_data)); + if(!multi->ssl_backend_data) { + return false; + } + } + + mbackend = (struct schannel_multi_ssl_backend_data *)multi->ssl_backend_data; + + + if(ca_info_blob) { + CAinfo_blob_digest = malloc(CURL_SHA256_DIGEST_LENGTH); + if(!CAinfo_blob_digest) { + return false; + } + schannel_sha256sum((const unsigned char *)ca_info_blob->data, + ca_info_blob->len, + CAinfo_blob_digest, + CURL_SHA256_DIGEST_LENGTH); + CAinfo_blob_size = ca_info_blob->len; + } + else { + if(conn_config->CAfile) { + CAfile = strdup(conn_config->CAfile); + if(!CAfile) { + return false; + } + } + } + + /* free old cache data */ + if(mbackend->cert_store) { + CertCloseStore(mbackend->cert_store, 0); + } + free(mbackend->CAinfo_blob_digest); + free(mbackend->CAfile); + + mbackend->time = Curl_now(); + mbackend->cert_store = cert_store; + mbackend->CAinfo_blob_digest = CAinfo_blob_digest; + mbackend->CAinfo_blob_size = CAinfo_blob_size; + mbackend->CAfile = CAfile; + return true; +} + +static void schannel_free_multi_ssl_backend_data( + struct multi_ssl_backend_data *msbd) +{ + struct schannel_multi_ssl_backend_data *mbackend = + (struct schannel_multi_ssl_backend_data*)msbd; + if(mbackend->cert_store) { + CertCloseStore(mbackend->cert_store, 0); + } + free(mbackend->CAinfo_blob_digest); + free(mbackend->CAfile); + free(mbackend); +} + const struct Curl_ssl Curl_ssl_schannel = { { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ @@ -2777,7 +2909,7 @@ const struct Curl_ssl Curl_ssl_schannel = { Curl_none_cert_status_request, /* cert_status_request */ schannel_connect, /* connect */ schannel_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_get_select_socks, /* getsock */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ schannel_get_internals, /* get_internals */ schannel_close, /* close_one */ Curl_none_close_all, /* close_all */ @@ -2789,7 +2921,7 @@ const struct Curl_ssl Curl_ssl_schannel = { schannel_sha256sum, /* sha256sum */ NULL, /* associate_connection */ NULL, /* disassociate_connection */ - NULL, /* free_multi_ssl_backend_data */ + schannel_free_multi_ssl_backend_data, /* free_multi_ssl_backend_data */ schannel_recv, /* recv decrypted data */ schannel_send, /* send data to encrypt */ }; diff --git a/lib/vtls/schannel_int.h b/lib/vtls/schannel_int.h index a128e04f6..fe7450d45 100644 --- a/lib/vtls/schannel_int.h +++ b/lib/vtls/schannel_int.h @@ -149,5 +149,22 @@ struct schannel_ssl_backend_data { #endif }; +struct schannel_multi_ssl_backend_data { + unsigned char *CAinfo_blob_digest; /* CA info blob digest */ + size_t CAinfo_blob_size; /* CA info blob size */ + char *CAfile; /* CAfile path used to generate + certificate store */ + HCERTSTORE cert_store; /* cached certificate store or + NULL if none */ + struct curltime time; /* when the cached store was created */ +}; + +HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf, + const struct Curl_easy *data); + +bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf, + const struct Curl_easy *data, + HCERTSTORE cert_store); + #endif /* USE_SCHANNEL */ #endif /* HEADER_CURL_SCHANNEL_INT_H */ diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index a5d5c98bb..e7c8bc66b 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -470,7 +470,7 @@ CURLcode Curl_verify_host(struct Curl_cfilter *cf, CERT_CONTEXT *pCertContextServer = NULL; TCHAR *cert_hostname_buff = NULL; size_t cert_hostname_buff_index = 0; - const char *conn_hostname = connssl->hostname; + const char *conn_hostname = connssl->peer.hostname; size_t hostlen = strlen(conn_hostname); DWORD len = 0; DWORD actual_len = 0; @@ -600,6 +600,7 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, const CERT_CHAIN_CONTEXT *pChainContext = NULL; HCERTCHAINENGINE cert_chain_engine = NULL; HCERTSTORE trust_store = NULL; + HCERTSTORE own_trust_store = NULL; DEBUGASSERT(BACKEND); @@ -630,31 +631,46 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, result = CURLE_SSL_CACERT_BADFILE; } else { - /* Open the certificate store */ - trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY, - 0, - (HCRYPTPROV)NULL, - CERT_STORE_CREATE_NEW_FLAG, - NULL); - if(!trust_store) { - char buffer[STRERROR_LEN]; - failf(data, "schannel: failed to create certificate store: %s", - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; + /* try cache */ + trust_store = Curl_schannel_get_cached_cert_store(cf, data); + + if(trust_store) { + infof(data, "schannel: reusing certificate store from cache"); } else { - const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; - if(ca_info_blob) { - result = add_certs_data_to_store(trust_store, - (const char *)ca_info_blob->data, - ca_info_blob->len, - "(memory blob)", - data); + /* Open the certificate store */ + trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY, + 0, + (HCRYPTPROV)NULL, + CERT_STORE_CREATE_NEW_FLAG, + NULL); + if(!trust_store) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: failed to create certificate store: %s", + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; } else { - result = add_certs_file_to_store(trust_store, - conn_config->CAfile, - data); + const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; + own_trust_store = trust_store; + + if(ca_info_blob) { + result = add_certs_data_to_store(trust_store, + (const char *)ca_info_blob->data, + ca_info_blob->len, + "(memory blob)", + data); + } + else { + result = add_certs_file_to_store(trust_store, + conn_config->CAfile, + data); + } + if(result == CURLE_OK) { + if(Curl_schannel_set_cached_cert_store(cf, data, trust_store)) { + own_trust_store = NULL; + } + } } } } @@ -754,8 +770,8 @@ CURLcode Curl_verify_certificate(struct Curl_cfilter *cf, CertFreeCertificateChainEngine(cert_chain_engine); } - if(trust_store) { - CertCloseStore(trust_store, 0); + if(own_trust_store) { + CertCloseStore(own_trust_store, 0); } if(pChainContext) diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c index 3378f7619..0a22ff60b 100644 --- a/lib/vtls/sectransp.c +++ b/lib/vtls/sectransp.c @@ -46,8 +46,10 @@ #endif /* __clang__ */ #ifdef __GNUC__ +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Waddress" #pragma GCC diagnostic ignored "-Wundef" +#pragma GCC diagnostic ignored "-Wunreachable-code" #endif #include @@ -1013,7 +1015,7 @@ static CURLcode CopyCertSubject(struct Curl_easy *data, } else { size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1; - cbuf = calloc(cbuf_size, 1); + cbuf = calloc(1, cbuf_size); if(cbuf) { if(!CFStringGetCString(c, cbuf, cbuf_size, kCFStringEncodingUTF8)) { @@ -1651,11 +1653,6 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, const bool verifypeer = conn_config->verifypeer; char * const ssl_cert = ssl_config->primary.clientcert; const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif /* ENABLE_IPV6 */ char *ciphers; OSStatus err = noErr; #if CURL_BUILD_MAC @@ -2003,13 +2000,9 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, * Both hostname check and SNI require SSLSetPeerDomainName(). * Also: the verifyhost setting influences SNI usage */ if(conn_config->verifyhost) { - size_t snilen; - char *snihost = Curl_ssl_snihost(data, connssl->hostname, &snilen); - if(!snihost) { - failf(data, "Failed to set SNI"); - return CURLE_SSL_CONNECT_ERROR; - } - err = SSLSetPeerDomainName(backend->ssl_ctx, snihost, snilen); + char *server = connssl->peer.sni? + connssl->peer.sni : connssl->peer.hostname; + err = SSLSetPeerDomainName(backend->ssl_ctx, server, strlen(server)); if(err != noErr) { failf(data, "SSL: SSLSetPeerDomainName() failed: OSStatus %d", @@ -2017,11 +2010,7 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, return CURLE_SSL_CONNECT_ERROR; } - if((Curl_inet_pton(AF_INET, connssl->hostname, &addr)) - #ifdef ENABLE_IPV6 - || (Curl_inet_pton(AF_INET6, connssl->hostname, &addr)) - #endif - ) { + if(connssl->peer.is_ip_address) { infof(data, "WARNING: using IP address, SNI is being disabled by " "the OS."); } @@ -2079,7 +2068,7 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, ssl_sessionid = aprintf("%s:%d:%d:%s:%d", ssl_cafile ? ssl_cafile : "(blob memory)", - verifypeer, conn_config->verifyhost, connssl->hostname, + verifypeer, conn_config->verifyhost, connssl->peer.hostname, connssl->port); ssl_sessionid_len = strlen(ssl_sessionid); @@ -2665,7 +2654,7 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf, host name: */ case errSSLHostNameMismatch: failf(data, "SSL certificate peer verification failed, the " - "certificate did not match \"%s\"\n", connssl->dispname); + "certificate did not match \"%s\"\n", connssl->peer.dispname); return CURLE_PEER_FAILED_VERIFICATION; /* Problem with SSL / TLS negotiation */ @@ -2757,7 +2746,7 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf, default: /* May also return codes listed in Security Framework Result Codes */ failf(data, "Unknown SSL protocol error in connection to %s:%d", - connssl->hostname, err); + connssl->peer.hostname, err); break; } return CURLE_SSL_CONNECT_ERROR; @@ -3415,7 +3404,6 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf, } *curlcode = CURLE_AGAIN; return -1L; - break; /* errSSLClosedGraceful - server gracefully shut down the SSL session errSSLClosedNoNotify - server hung up on us instead of sending a @@ -3425,7 +3413,6 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf, case errSSLClosedNoNotify: *curlcode = CURLE_OK; return 0; - break; /* The below is errSSLPeerAuthCompleted; it's not defined in Leopard's headers */ @@ -3445,7 +3432,6 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf, failf(data, "SSLRead() return error %d", err); *curlcode = CURLE_RECV_ERROR; return -1L; - break; } } return (ssize_t)processed; @@ -3483,7 +3469,7 @@ const struct Curl_ssl Curl_ssl_sectransp = { Curl_none_cert_status_request, /* cert_status_request */ sectransp_connect, /* connect */ sectransp_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_get_select_socks, /* getsock */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ sectransp_get_internals, /* get_internals */ sectransp_close, /* close_one */ Curl_none_close_all, /* close_all */ @@ -3500,6 +3486,10 @@ const struct Curl_ssl Curl_ssl_sectransp = { sectransp_send, /* send data to encrypt */ }; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #ifdef __clang__ #pragma clang diagnostic pop #endif diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index 494b660a9..34eda3e5a 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -67,6 +67,7 @@ #include "warnless.h" #include "curl_base64.h" #include "curl_printf.h" +#include "inet_pton.h" #include "strdup.h" /* The last #include files should be: */ @@ -131,9 +132,6 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second) } #ifdef USE_SSL -static const struct alpn_spec ALPN_SPEC_H10 = { - { ALPN_HTTP_1_0 }, 1 -}; static const struct alpn_spec ALPN_SPEC_H11 = { { ALPN_HTTP_1_1 }, 1 }; @@ -147,51 +145,83 @@ static const struct alpn_spec *alpn_get_spec(int httpwant, bool use_alpn) { if(!use_alpn) return NULL; - if(httpwant == CURL_HTTP_VERSION_1_0) - return &ALPN_SPEC_H10; #ifdef USE_HTTP2 if(httpwant >= CURL_HTTP_VERSION_2) return &ALPN_SPEC_H2_H11; +#else + (void)httpwant; #endif + /* Use the ALPN protocol "http/1.1" for HTTP/1.x. + Avoid "http/1.0" because some servers don't support it. */ return &ALPN_SPEC_H11; } #endif /* USE_SSL */ -bool -Curl_ssl_config_matches(struct ssl_primary_config *data, - struct ssl_primary_config *needle) -{ - if((data->version == needle->version) && - (data->version_max == needle->version_max) && - (data->ssl_options == needle->ssl_options) && - (data->verifypeer == needle->verifypeer) && - (data->verifyhost == needle->verifyhost) && - (data->verifystatus == needle->verifystatus) && - blobcmp(data->cert_blob, needle->cert_blob) && - blobcmp(data->ca_info_blob, needle->ca_info_blob) && - blobcmp(data->issuercert_blob, needle->issuercert_blob) && - Curl_safecmp(data->CApath, needle->CApath) && - Curl_safecmp(data->CAfile, needle->CAfile) && - Curl_safecmp(data->issuercert, needle->issuercert) && - Curl_safecmp(data->clientcert, needle->clientcert) && +void Curl_ssl_easy_config_init(struct Curl_easy *data) +{ + /* + * libcurl 7.10 introduced SSL verification *by default*! This needs to be + * switched off unless wanted. + */ + data->set.ssl.primary.verifypeer = TRUE; + data->set.ssl.primary.verifyhost = TRUE; + data->set.ssl.primary.sessionid = TRUE; /* session ID caching by default */ +#ifndef CURL_DISABLE_PROXY + data->set.proxy_ssl = data->set.ssl; +#endif +} + +static bool +match_ssl_primary_config(struct Curl_easy *data, + struct ssl_primary_config *c1, + struct ssl_primary_config *c2) +{ + (void)data; + if((c1->version == c2->version) && + (c1->version_max == c2->version_max) && + (c1->ssl_options == c2->ssl_options) && + (c1->verifypeer == c2->verifypeer) && + (c1->verifyhost == c2->verifyhost) && + (c1->verifystatus == c2->verifystatus) && + blobcmp(c1->cert_blob, c2->cert_blob) && + blobcmp(c1->ca_info_blob, c2->ca_info_blob) && + blobcmp(c1->issuercert_blob, c2->issuercert_blob) && + Curl_safecmp(c1->CApath, c2->CApath) && + Curl_safecmp(c1->CAfile, c2->CAfile) && + Curl_safecmp(c1->issuercert, c2->issuercert) && + Curl_safecmp(c1->clientcert, c2->clientcert) && #ifdef USE_TLS_SRP - !Curl_timestrcmp(data->username, needle->username) && - !Curl_timestrcmp(data->password, needle->password) && + !Curl_timestrcmp(c1->username, c2->username) && + !Curl_timestrcmp(c1->password, c2->password) && #endif - strcasecompare(data->cipher_list, needle->cipher_list) && - strcasecompare(data->cipher_list13, needle->cipher_list13) && - strcasecompare(data->curves, needle->curves) && - strcasecompare(data->CRLfile, needle->CRLfile) && - strcasecompare(data->pinned_key, needle->pinned_key)) + strcasecompare(c1->cipher_list, c2->cipher_list) && + strcasecompare(c1->cipher_list13, c2->cipher_list13) && + strcasecompare(c1->curves, c2->curves) && + strcasecompare(c1->CRLfile, c2->CRLfile) && + strcasecompare(c1->pinned_key, c2->pinned_key)) return TRUE; return FALSE; } -bool -Curl_clone_primary_ssl_config(struct ssl_primary_config *source, - struct ssl_primary_config *dest) +bool Curl_ssl_conn_config_match(struct Curl_easy *data, + struct connectdata *candidate, + bool proxy) +{ +#ifndef CURL_DISABLE_PROXY + if(proxy) + return match_ssl_primary_config(data, &data->set.proxy_ssl.primary, + &candidate->proxy_ssl_config); +#else + (void)proxy; +#endif + return match_ssl_primary_config(data, &data->set.ssl.primary, + &candidate->ssl_config); +} + +static bool clone_ssl_primary_config(struct ssl_primary_config *source, + struct ssl_primary_config *dest) { dest->version = source->version; dest->version_max = source->version_max; @@ -221,7 +251,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, return TRUE; } -void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) +static void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) { Curl_safefree(sslc->CApath); Curl_safefree(sslc->CAfile); @@ -241,6 +271,111 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) #endif } +CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data) +{ + data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; + data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; + data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; + data->set.ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST]; + data->set.ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST]; + data->set.ssl.primary.pinned_key = + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT]; + data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; + data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES]; +#ifdef USE_TLS_SRP + data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; + data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; +#endif + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; + data->set.ssl.key = data->set.str[STRING_KEY]; + data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE]; + data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD]; + data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; + data->set.ssl.key_blob = data->set.blobs[BLOB_KEY]; + +#ifndef CURL_DISABLE_PROXY + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; + data->set.proxy_ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; + data->set.proxy_ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; + data->set.proxy_ssl.primary.pinned_key = + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; + data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; + data->set.proxy_ssl.primary.ca_info_blob = + data->set.blobs[BLOB_CAINFO_PROXY]; + data->set.proxy_ssl.primary.issuercert = + data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.proxy_ssl.primary.issuercert_blob = + data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; + data->set.proxy_ssl.primary.CRLfile = + data->set.str[STRING_SSL_CRLFILE_PROXY]; + data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; + data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; + data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; + data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; + data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; + data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; +#ifdef USE_TLS_SRP + data->set.proxy_ssl.primary.username = + data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; + data->set.proxy_ssl.primary.password = + data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; +#endif +#endif /* CURL_DISABLE_PROXY */ + + return CURLE_OK; +} + +CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, + struct connectdata *conn) +{ + /* Clone "primary" SSL configurations from the esay handle to + * the connection. They are used for connection cache matching and + * probably outlive the easy handle */ + if(!clone_ssl_primary_config(&data->set.ssl.primary, &conn->ssl_config)) + return CURLE_OUT_OF_MEMORY; +#ifndef CURL_DISABLE_PROXY + if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary, + &conn->proxy_ssl_config)) + return CURLE_OUT_OF_MEMORY; +#endif + return CURLE_OK; +} + +void Curl_ssl_conn_config_cleanup(struct connectdata *conn) +{ + Curl_free_primary_ssl_config(&conn->ssl_config); +#ifndef CURL_DISABLE_PROXY + Curl_free_primary_ssl_config(&conn->proxy_ssl_config); +#endif +} + +void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy) +{ + /* May be called on an easy that has no connection yet */ + if(data->conn) { + struct ssl_primary_config *src, *dest; +#ifndef CURL_DISABLE_PROXY + src = for_proxy? &data->set.proxy_ssl.primary : &data->set.ssl.primary; + dest = for_proxy? &data->conn->proxy_ssl_config : &data->conn->ssl_config; +#else + (void)for_proxy; + src = &data->set.ssl.primary; + dest = &data->conn->ssl_config; +#endif + dest->verifyhost = src->verifyhost; + dest->verifypeer = src->verifypeer; + dest->verifystatus = src->verifystatus; + } +} + #ifdef USE_SSL static int multissl_setup(const struct Curl_ssl *backend); #endif @@ -432,7 +567,7 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf, if(!check->sessionid) /* not session ID means blank entry */ continue; - if(strcasecompare(connssl->hostname, check->name) && + if(strcasecompare(connssl->peer.hostname, check->name) && ((!cf->conn->bits.conn_to_host && !check->conn_to_host) || (cf->conn->bits.conn_to_host && check->conn_to_host && strcasecompare(cf->conn->conn_to_host.name, check->conn_to_host))) && @@ -441,7 +576,7 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf, cf->conn->conn_to_port == check->conn_to_port)) && (connssl->port == check->remote_port) && strcasecompare(cf->conn->handler->scheme, check->scheme) && - Curl_ssl_config_matches(conn_config, &check->ssl_config)) { + match_ssl_primary_config(data, conn_config, &check->ssl_config)) { /* yes, we have a session ID! */ (*general_age)++; /* increase general age */ check->age = *general_age; /* set this as used in this age */ @@ -456,7 +591,8 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf, DEBUGF(infof(data, "%s Session ID in cache for %s %s://%s:%d", no_match? "Didn't find": "Found", Curl_ssl_cf_is_proxy(cf) ? "proxy" : "host", - cf->conn->handler->scheme, connssl->hostname, connssl->port)); + cf->conn->handler->scheme, connssl->peer.hostname, + connssl->port)); return no_match; } @@ -532,7 +668,7 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf, (void)ssl_config; DEBUGASSERT(ssl_config->primary.sessionid); - clone_host = strdup(connssl->hostname); + clone_host = strdup(connssl->peer.hostname); if(!clone_host) return CURLE_OUT_OF_MEMORY; /* bail out */ @@ -590,7 +726,7 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf, store->remote_port = connssl->port; store->scheme = cf->conn->handler->scheme; - if(!Curl_clone_primary_ssl_config(conn_config, &store->ssl_config)) { + if(!clone_ssl_primary_config(conn_config, &store->ssl_config)) { Curl_free_primary_ssl_config(&store->ssl_config); store->sessionid = NULL; /* let caller free sessionid */ free(clone_host); @@ -629,22 +765,21 @@ void Curl_ssl_close_all(struct Curl_easy *data) Curl_ssl->close_all(data); } -int Curl_ssl_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) +void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, + struct easy_pollset *ps) { - struct ssl_connect_data *connssl = cf->ctx; - curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); - - if(sock == CURL_SOCKET_BAD) - return GETSOCK_BLANK; - - if(connssl->connecting_state == ssl_connect_2_writing) { - /* we are only interested in writing */ - socks[0] = sock; - return GETSOCK_WRITESOCK(0); + if(!cf->connected) { + struct ssl_connect_data *connssl = cf->ctx; + curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); + if(sock != CURL_SOCKET_BAD) { + if(connssl->connecting_state == ssl_connect_2_writing) { + Curl_pollset_set_out_only(data, ps, sock); + } + else { + Curl_pollset_set_in_only(data, ps, sock); + } + } } - socks[0] = sock; - return GETSOCK_READSOCK(0); } /* Selects an SSL crypto engine @@ -785,32 +920,6 @@ CURLcode Curl_ssl_random(struct Curl_easy *data, return Curl_ssl->random(data, entropy, length); } -/* - * Curl_ssl_snihost() converts the input host name to a suitable SNI name put - * in data->state.buffer. Returns a pointer to the name (or NULL if a problem) - * and stores the new length in 'olen'. - * - * SNI fields must not have any trailing dot and while RFC 6066 section 3 says - * the SNI field is case insensitive, browsers always send the data lowercase - * and subsequently there are numerous servers out there that don't work - * unless the name is lowercased. - */ - -char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen) -{ - size_t len = strlen(host); - if(len && (host[len-1] == '.')) - len--; - if(len >= data->set.buffer_size) - return NULL; - - Curl_strntolower(data->state.buffer, host, len); - data->state.buffer[len] = 0; - if(olen) - *olen = len; - return data->state.buffer; -} - /* * Public key pem to der conversion */ @@ -1156,13 +1265,13 @@ static CURLcode multissl_connect_nonblocking(struct Curl_cfilter *cf, return Curl_ssl->connect_nonblocking(cf, data, done); } -static int multissl_get_select_socks(struct Curl_cfilter *cf, +static void multissl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { if(multissl_setup(NULL)) - return 0; - return Curl_ssl->get_select_socks(cf, data, socks); + return; + Curl_ssl->adjust_pollset(cf, data, ps); } static void *multissl_get_internals(struct ssl_connect_data *connssl, @@ -1214,7 +1323,7 @@ static const struct Curl_ssl Curl_ssl_multi = { Curl_none_cert_status_request, /* cert_status_request */ multissl_connect, /* connect */ multissl_connect_nonblocking, /* connect_nonblocking */ - multissl_get_select_socks, /* getsock */ + multissl_adjust_pollset, /* adjust_pollset */ multissl_get_internals, /* get_internals */ multissl_close, /* close_one */ Curl_none_close_all, /* close_all */ @@ -1409,12 +1518,14 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, #ifdef USE_SSL -static void free_hostname(struct ssl_connect_data *connssl) +void Curl_ssl_peer_cleanup(struct ssl_peer *peer) { - if(connssl->dispname != connssl->hostname) - free(connssl->dispname); - free(connssl->hostname); - connssl->hostname = connssl->dispname = NULL; + if(peer->dispname != peer->hostname) + free(peer->dispname); + free(peer->sni); + free(peer->hostname); + peer->hostname = peer->sni = peer->dispname = NULL; + peer->is_ip_address = FALSE; } static void cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) @@ -1423,12 +1534,26 @@ static void cf_close(struct Curl_cfilter *cf, struct Curl_easy *data) if(connssl) { Curl_ssl->close(cf, data); connssl->state = ssl_connection_none; - free_hostname(connssl); + Curl_ssl_peer_cleanup(&connssl->peer); } cf->connected = FALSE; } -static CURLcode reinit_hostname(struct Curl_cfilter *cf) +static int is_ip_address(const char *hostname) +{ +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif + return (hostname && hostname[0] && (Curl_inet_pton(AF_INET, hostname, &addr) +#ifdef ENABLE_IPV6 + || Curl_inet_pton(AF_INET6, hostname, &addr) +#endif + )); +} + +CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, struct Curl_cfilter *cf) { struct ssl_connect_data *connssl = cf->ctx; const char *ehostname, *edispname; @@ -1454,23 +1579,43 @@ static CURLcode reinit_hostname(struct Curl_cfilter *cf) } /* change if ehostname changed */ - if(ehostname && (!connssl->hostname - || strcmp(ehostname, connssl->hostname))) { - free_hostname(connssl); - connssl->hostname = strdup(ehostname); - if(!connssl->hostname) { - free_hostname(connssl); + if(ehostname && (!peer->hostname + || strcmp(ehostname, peer->hostname))) { + Curl_ssl_peer_cleanup(peer); + peer->hostname = strdup(ehostname); + if(!peer->hostname) { + Curl_ssl_peer_cleanup(peer); return CURLE_OUT_OF_MEMORY; } if(!edispname || !strcmp(ehostname, edispname)) - connssl->dispname = connssl->hostname; + peer->dispname = peer->hostname; else { - connssl->dispname = strdup(edispname); - if(!connssl->dispname) { - free_hostname(connssl); + peer->dispname = strdup(edispname); + if(!peer->dispname) { + Curl_ssl_peer_cleanup(peer); return CURLE_OUT_OF_MEMORY; } } + + peer->sni = NULL; + peer->is_ip_address = is_ip_address(peer->hostname)? TRUE : FALSE; + if(peer->hostname[0] && !peer->is_ip_address) { + /* not an IP address, normalize according to RCC 6066 ch. 3, + * max len of SNI is 2^16-1, no trailing dot */ + size_t len = strlen(peer->hostname); + if(len && (peer->hostname[len-1] == '.')) + len--; + if(len < USHRT_MAX) { + peer->sni = calloc(1, len + 1); + if(!peer->sni) { + Curl_ssl_peer_cleanup(peer); + return CURLE_OUT_OF_MEMORY; + } + Curl_strntolower(peer->sni, peer->hostname, len); + peer->sni[len] = 0; + } + } + } connssl->port = eport; return CURLE_OK; @@ -1525,7 +1670,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf, goto out; *done = FALSE; - result = reinit_hostname(cf); + result = Curl_ssl_peer_init(&connssl->peer, cf); if(result) goto out; @@ -1599,22 +1744,17 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf, return nread; } -static int ssl_cf_get_select_socks(struct Curl_cfilter *cf, +static void ssl_cf_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks) + struct easy_pollset *ps) { struct cf_call_data save; - int fds = GETSOCK_BLANK; - if(!cf->next->connected) { - fds = cf->next->cft->get_select_socks(cf->next, data, socks); - } - else if(!cf->connected) { + if(!cf->connected) { CF_DATA_SAVE(save, cf, data); - fds = Curl_ssl->get_select_socks(cf, data, socks); + Curl_ssl->adjust_pollset(cf, data, ps); CF_DATA_RESTORE(cf, save); } - return fds; } static CURLcode ssl_cf_cntrl(struct Curl_cfilter *cf, @@ -1705,7 +1845,7 @@ struct Curl_cftype Curl_cft_ssl = { ssl_cf_connect, ssl_cf_close, Curl_cf_def_get_host, - ssl_cf_get_select_socks, + ssl_cf_adjust_pollset, ssl_cf_data_pending, ssl_cf_send, ssl_cf_recv, @@ -1723,7 +1863,7 @@ struct Curl_cftype Curl_cft_ssl_proxy = { ssl_cf_connect, ssl_cf_close, Curl_cf_def_get_host, - ssl_cf_get_select_socks, + ssl_cf_adjust_pollset, ssl_cf_data_pending, ssl_cf_send, ssl_cf_recv, @@ -1837,6 +1977,16 @@ bool Curl_ssl_supports(struct Curl_easy *data, int option) return (Curl_ssl->supports & option)? TRUE : FALSE; } +static struct Curl_cfilter *get_ssl_filter(struct Curl_cfilter *cf) +{ + for(; cf; cf = cf->next) { + if(cf->cft == &Curl_cft_ssl || cf->cft == &Curl_cft_ssl_proxy) + return cf; + } + return NULL; +} + + void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, CURLINFO info, int n) { @@ -1844,8 +1994,8 @@ void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, (void)n; if(data->conn) { struct Curl_cfilter *cf; - /* get first filter in chain, if any is present */ - cf = Curl_ssl_cf_get_ssl(data->conn->cfilter[sockindex]); + /* get first SSL filter in chain, if any is present */ + cf = get_ssl_filter(data->conn->cfilter[sockindex]); if(cf) { struct cf_call_data save; CF_DATA_SAVE(save, cf, data); @@ -1875,23 +2025,6 @@ CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data, return result; } -static struct Curl_cfilter *get_ssl_cf_engaged(struct connectdata *conn, - int sockindex) -{ - struct Curl_cfilter *cf, *lowest_ssl_cf = NULL; - - for(cf = conn->cfilter[sockindex]; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_ssl || cf->cft == &Curl_cft_ssl_proxy) { - lowest_ssl_cf = cf; - if(cf->connected || (cf->next && cf->next->connected)) { - /* connected or about to start */ - return cf; - } - } - } - return lowest_ssl_cf; -} - bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf) { return (cf->cft == &Curl_cft_ssl_proxy); @@ -1908,17 +2041,6 @@ Curl_ssl_cf_get_config(struct Curl_cfilter *cf, struct Curl_easy *data) #endif } -struct ssl_config_data * -Curl_ssl_get_config(struct Curl_easy *data, int sockindex) -{ - struct Curl_cfilter *cf; - - (void)data; - DEBUGASSERT(data->conn); - cf = get_ssl_cf_engaged(data->conn, sockindex); - return cf? Curl_ssl_cf_get_config(cf, data) : &data->set.ssl; -} - struct ssl_primary_config * Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf) { @@ -1930,15 +2052,6 @@ Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf) #endif } -struct Curl_cfilter *Curl_ssl_cf_get_ssl(struct Curl_cfilter *cf) -{ - for(; cf; cf = cf->next) { - if(cf->cft == &Curl_cft_ssl || cf->cft == &Curl_cft_ssl_proxy) - return cf; - } - return NULL; -} - CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf, const struct alpn_spec *spec) { @@ -2005,10 +2118,6 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, !memcmp(ALPN_HTTP_1_1, proto, ALPN_HTTP_1_1_LENGTH)) { *palpn = CURL_HTTP_VERSION_1_1; } - else if(proto_len == ALPN_HTTP_1_0_LENGTH && - !memcmp(ALPN_HTTP_1_0, proto, ALPN_HTTP_1_0_LENGTH)) { - *palpn = CURL_HTTP_VERSION_1_0; - } #ifdef USE_HTTP2 else if(proto_len == ALPN_H2_LENGTH && !memcmp(ALPN_H2, proto, ALPN_H2_LENGTH)) { diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h index 8ad1cf6de..f1856bd33 100644 --- a/lib/vtls/vtls.h +++ b/lib/vtls/vtls.h @@ -65,15 +65,54 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ #endif -char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen); -bool Curl_ssl_config_matches(struct ssl_primary_config *data, - struct ssl_primary_config *needle); -bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, - struct ssl_primary_config *dest); -void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc); - curl_sslbackend Curl_ssl_backend(void); +/** + * Init ssl config for a new easy handle. + */ +void Curl_ssl_easy_config_init(struct Curl_easy *data); + +/** + * Init the `data->set.ssl` and `data->set.proxy_ssl` for + * connection matching use. + */ +CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data); + +/** + * Init SSL configs (main + proxy) for a new connection from the easy handle. + */ +CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, + struct connectdata *conn); + +/** + * Free allocated resources in SSL configs (main + proxy) for + * the given connection. + */ +void Curl_ssl_conn_config_cleanup(struct connectdata *conn); + +/** + * Return TRUE iff SSL configuration from `conn` is functionally the + * same as the one on `candidate`. + * @param proxy match the proxy SSL config or the main one + */ +bool Curl_ssl_conn_config_match(struct Curl_easy *data, + struct connectdata *candidate, + bool proxy); + +/* Update certain connection SSL config flags after they have + * been changed on the easy handle. Will work for `verifypeer`, + * `verifyhost` and `verifystatus`. */ +void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy); + +/** + * Init SSL peer information for filter. Can be called repeatedly. + */ +CURLcode Curl_ssl_peer_init(struct ssl_peer *peer, struct Curl_cfilter *cf); +/** + * Free all allocated data and reset peer information. + */ +void Curl_ssl_peer_cleanup(struct ssl_peer *peer); + #ifdef USE_SSL int Curl_ssl_init(void); void Curl_ssl_cleanup(void); @@ -159,18 +198,6 @@ CURLcode Curl_cf_ssl_proxy_insert_after(struct Curl_cfilter *cf_at, struct Curl_easy *data); #endif /* !CURL_DISABLE_PROXY */ -/** - * Get the SSL configuration that is used on the connection. - * This returns NULL if no SSL is configured. - * Otherwise it returns the config of the first (highest) one that is - * either connected, in handshake or about to start - * (e.g. all filters below it are connected). If SSL filters are present, - * but neither can start operating, return the config of the lowest one - * that will first come into effect when connecting. - */ -struct ssl_config_data *Curl_ssl_get_config(struct Curl_easy *data, - int sockindex); - /** * True iff the underlying SSL implementation supports the option. * Option is one of the defined SSLSUPP_* values. @@ -188,6 +215,18 @@ bool Curl_ssl_supports(struct Curl_easy *data, int ssl_option); 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`. + */ +struct ssl_config_data *Curl_ssl_cf_get_config(struct Curl_cfilter *cf, + struct Curl_easy *data); + +/** + * Get the primary config relevant for the filter from its connection. + */ +struct ssl_primary_config * + Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf); + extern struct Curl_cftype Curl_cft_ssl; extern struct Curl_cftype Curl_cft_ssl_proxy; @@ -209,8 +248,9 @@ extern struct Curl_cftype Curl_cft_ssl_proxy; #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_get_config(a,b) NULL #define Curl_ssl_cfilter_remove(a,b) CURLE_OK +#define Curl_ssl_cf_get_config(a,b) NULL +#define Curl_ssl_cf_get_primary_config(a) NULL #endif #endif /* HEADER_CURL_VTLS_H */ diff --git a/lib/vtls/vtls_int.h b/lib/vtls/vtls_int.h index a6e4544a8..af7ae552e 100644 --- a/lib/vtls/vtls_int.h +++ b/lib/vtls/vtls_int.h @@ -32,8 +32,6 @@ /* see https://www.iana.org/assignments/tls-extensiontype-values/ */ #define ALPN_HTTP_1_1_LENGTH 8 #define ALPN_HTTP_1_1 "http/1.1" -#define ALPN_HTTP_1_0_LENGTH 8 -#define ALPN_HTTP_1_0 "http/1.0" #define ALPN_H2_LENGTH 2 #define ALPN_H2 "h2" #define ALPN_H3_LENGTH 2 @@ -70,14 +68,14 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, struct ssl_connect_data { ssl_connection_state state; ssl_connect_state connecting_state; - char *hostname; /* hostname for verification */ - char *dispname; /* display version of hostname */ + struct ssl_peer peer; const struct alpn_spec *alpn; /* ALPN to use or NULL for none */ void *backend; /* vtls backend specific props */ struct cf_call_data call_data; /* data handle used in current call */ struct curltime handshake_done; /* time when handshake finished */ int port; /* remote port at origin */ BIT(use_alpn); /* if ALPN shall be used in handshake */ + BIT(reused_session); /* session-ID was reused for this */ }; @@ -118,14 +116,11 @@ struct Curl_ssl { struct Curl_easy *data, bool *done); - /* If the SSL backend wants to read or write on this connection during a - handshake, set socks[0] to the connection's FIRSTSOCKET, and return - a bitmap indicating read or write with GETSOCK_WRITESOCK(0) or - GETSOCK_READSOCK(0). Otherwise return GETSOCK_BLANK. - Mandatory. */ - int (*get_select_socks)(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks); - + /* During handshake, 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); 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); @@ -169,25 +164,8 @@ CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine); CURLcode Curl_none_set_engine_default(struct Curl_easy *data); struct curl_slist *Curl_none_engines_list(struct Curl_easy *data); bool Curl_none_false_start(void); -int Curl_ssl_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data, - curl_socket_t *socks); - -/** - * Get the ssl_config_data in `data` that is relevant for cfilter `cf`. - */ -struct ssl_config_data *Curl_ssl_cf_get_config(struct Curl_cfilter *cf, - struct Curl_easy *data); - -/** - * Get the primary config relevant for the filter from its connection. - */ -struct ssl_primary_config * - Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf); - -/** - * Get the first SSL filter in the chain starting with `cf`, or NULL. - */ -struct Curl_cfilter *Curl_ssl_cf_get_ssl(struct Curl_cfilter *cf); +void 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/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index b1384a644..5890bb609 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -480,6 +480,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_SSL_CONNECT_ERROR; } #endif + default: break; } @@ -513,7 +514,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) } } -#ifndef NO_FILESYSTEM +#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SYS_CA_CERTS) /* load native CA certificates */ if(ssl_config->native_ca_store) { if(wolfSSL_CTX_load_system_CA_certs(backend->ctx) != WOLFSSL_SUCCESS) { @@ -608,24 +609,12 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) SSL_VERIFY_NONE, NULL); #ifdef HAVE_SNI - if(sni) { - struct in_addr addr4; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - size_t hostname_len = strlen(connssl->hostname); - - if((hostname_len < USHRT_MAX) && - !Curl_inet_pton(AF_INET, connssl->hostname, &addr4) -#ifdef ENABLE_IPV6 - && !Curl_inet_pton(AF_INET6, connssl->hostname, &addr6) -#endif - ) { - size_t snilen; - char *snihost = Curl_ssl_snihost(data, connssl->hostname, &snilen); - if(!snihost || - wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, snihost, - (unsigned short)snilen) != 1) { + if(sni && connssl->peer.sni) { + size_t sni_len = strlen(connssl->peer.sni); + if((sni_len < USHRT_MAX)) { + if(wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, + connssl->peer.sni, + (unsigned short)sni_len) != 1) { failf(data, "Failed to set SNI"); return CURLE_SSL_CONNECT_ERROR; } @@ -763,9 +752,9 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) /* Enable RFC2818 checks */ if(conn_config->verifyhost) { - char *snihost = Curl_ssl_snihost(data, connssl->hostname, NULL); - if(!snihost || - (wolfSSL_check_domain_name(backend->handle, snihost) == SSL_FAILURE)) + char *snihost = connssl->peer.sni? + connssl->peer.sni : connssl->peer.hostname; + if(wolfSSL_check_domain_name(backend->handle, snihost) == SSL_FAILURE) return CURLE_SSL_CONNECT_ERROR; } @@ -813,7 +802,7 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) else if(DOMAIN_NAME_MISMATCH == detail) { #if 1 failf(data, " subject alt name(s) or common name do not match \"%s\"", - connssl->dispname); + connssl->peer.dispname); return CURLE_PEER_FAILED_VERIFICATION; #else /* When the wolfssl_check_domain_name() is used and you desire to @@ -1398,7 +1387,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = { Curl_none_cert_status_request, /* cert_status_request */ wolfssl_connect, /* connect */ wolfssl_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_get_select_socks, /* getsock */ + Curl_ssl_adjust_pollset, /* adjust_pollset */ wolfssl_get_internals, /* get_internals */ wolfssl_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c index c3fd3a30b..8b1eed63f 100644 --- a/lib/vtls/x509asn1.c +++ b/lib/vtls/x509asn1.c @@ -1317,16 +1317,16 @@ CURLcode Curl_verifyhost(struct Curl_cfilter *cf, if(Curl_parseX509(&cert, beg, end)) return CURLE_PEER_FAILED_VERIFICATION; - hostlen = strlen(connssl->hostname); + hostlen = strlen(connssl->peer.hostname); /* Get the server IP address. */ #ifdef ENABLE_IPV6 if(cf->conn->bits.ipv6_ip && - Curl_inet_pton(AF_INET6, connssl->hostname, &addr)) + Curl_inet_pton(AF_INET6, connssl->peer.hostname, &addr)) addrlen = sizeof(struct in6_addr); else #endif - if(Curl_inet_pton(AF_INET, connssl->hostname, &addr)) + if(Curl_inet_pton(AF_INET, connssl->peer.hostname, &addr)) addrlen = sizeof(struct in_addr); /* Process extensions. */ @@ -1361,7 +1361,7 @@ CURLcode Curl_verifyhost(struct Curl_cfilter *cf, name.beg, name.end); if(len > 0 && (size_t)len == strlen(dnsname)) matched = Curl_cert_hostcheck(dnsname, (size_t)len, - connssl->hostname, hostlen); + connssl->peer.hostname, hostlen); else matched = 0; free(dnsname); @@ -1421,7 +1421,7 @@ CURLcode Curl_verifyhost(struct Curl_cfilter *cf, if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */ failf(data, "SSL: illegal cert name field"); else if(Curl_cert_hostcheck((const char *) dnsname, - len, connssl->hostname, hostlen)) { + len, connssl->peer.hostname, hostlen)) { infof(data, " common name: %s (matched)", dnsname); free(dnsname); return CURLE_OK; diff --git a/lib/warnless.c b/lib/warnless.c index 7e077f8d8..c80937b84 100644 --- a/lib/warnless.c +++ b/lib/warnless.c @@ -37,7 +37,7 @@ #include "warnless.h" -#ifdef WIN32 +#ifdef _WIN32 #undef read #undef write #endif @@ -367,7 +367,7 @@ curl_socket_t curlx_sitosk(int i) #endif /* USE_WINSOCK */ -#if defined(WIN32) +#if defined(_WIN32) ssize_t curlx_read(int fd, void *buf, size_t count) { @@ -379,8 +379,8 @@ ssize_t curlx_write(int fd, const void *buf, size_t count) return (ssize_t)write(fd, buf, curlx_uztoui(count)); } -/* Ensure that warnless.h continues to have an effect in "unity" builds. */ -#undef HEADER_CURL_WARNLESS_H - -#endif /* WIN32 */ +#endif /* _WIN32 */ +/* Ensure that warnless.h redefinitions continue to have an effect + in "unity" builds. */ +#undef HEADER_CURL_WARNLESS_H_REDEFS diff --git a/lib/warnless.h b/lib/warnless.h index 2a5301628..e5a02c8d9 100644 --- a/lib/warnless.h +++ b/lib/warnless.h @@ -69,18 +69,13 @@ curl_socket_t curlx_sitosk(int i); #endif /* USE_WINSOCK */ -#if defined(WIN32) +#if defined(_WIN32) ssize_t curlx_read(int fd, void *buf, size_t count); ssize_t curlx_write(int fd, const void *buf, size_t count); -#undef read -#define read(fd, buf, count) curlx_read(fd, buf, count) -#undef write -#define write(fd, buf, count) curlx_write(fd, buf, count) - -#endif /* WIN32 */ +#endif /* _WIN32 */ #if defined(__INTEL_COMPILER) && defined(__unix__) @@ -97,3 +92,15 @@ unsigned short curlx_ntohs(unsigned short usnum); #endif /* __INTEL_COMPILER && __unix__ */ #endif /* HEADER_CURL_WARNLESS_H */ + +#ifndef HEADER_CURL_WARNLESS_H_REDEFS +#define HEADER_CURL_WARNLESS_H_REDEFS + +#if defined(_WIN32) +#undef read +#define read(fd, buf, count) curlx_read(fd, buf, count) +#undef write +#define write(fd, buf, count) curlx_write(fd, buf, count) +#endif + +#endif /* HEADER_CURL_WARNLESS_H_REDEFS */ diff --git a/lib/ws.c b/lib/ws.c index 3c1964b86..adde531f5 100644 --- a/lib/ws.c +++ b/lib/ws.c @@ -274,8 +274,8 @@ static CURLcode ws_dec_pass_payload(struct ws_decoder *dec, dec->payload_offset += (curl_off_t)nwritten; remain = dec->payload_len - dec->payload_offset; /* infof(data, "WS-DEC: passed %zd bytes payload, %" - CURL_FORMAT_CURL_OFF_T " remain", - nwritten, remain); */ + CURL_FORMAT_CURL_OFF_T " remain", + nwritten, remain); */ } return remain? CURLE_AGAIN : CURLE_OK; @@ -925,8 +925,8 @@ CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer, *metap = &ws->frame; *nread = ws->frame.len; /* infof(data, "curl_ws_recv(len=%zu) -> %zu bytes (frame at %" - CURL_FORMAT_CURL_OFF_T ", %" CURL_FORMAT_CURL_OFF_T " left)", - buflen, *nread, ws->frame.offset, ws->frame.bytesleft); */ + CURL_FORMAT_CURL_OFF_T ", %" CURL_FORMAT_CURL_OFF_T " left)", + buflen, *nread, ws->frame.offset, ws->frame.bytesleft); */ return CURLE_OK; } diff --git a/m4/curl-amissl.m4 b/m4/curl-amissl.m4 index 95208f0c2..48067e720 100644 --- a/m4/curl-amissl.m4 +++ b/m4/curl-amissl.m4 @@ -33,7 +33,7 @@ if test "$HAVE_PROTO_BSDSOCKET_H" = "1"; then #include ]],[[ #if defined(AMISSL_CURRENT_VERSION) && defined(AMISSL_V3xx) && \ - defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) && \ + (OPENSSL_VERSION_NUMBER >= 0x30000000L) && \ defined(PROTO_AMISSL_H) return 0; #else diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4 index caa2b14cb..35ba19866 100644 --- a/m4/curl-compilers.m4 +++ b/m4/curl-compilers.m4 @@ -48,7 +48,6 @@ AC_DEFUN([CURL_CHECK_COMPILER], [ CURL_CHECK_COMPILER_INTEL_C CURL_CHECK_COMPILER_CLANG CURL_CHECK_COMPILER_GNU_C - CURL_CHECK_COMPILER_LCC CURL_CHECK_COMPILER_SGI_MIPSPRO_C CURL_CHECK_COMPILER_SGI_MIPS_C CURL_CHECK_COMPILER_SUNPRO_C @@ -92,19 +91,40 @@ AC_DEFUN([CURL_CHECK_COMPILER_CLANG], [ AC_MSG_RESULT([no]) compiler_id="CLANG" fi + AC_MSG_CHECKING([compiler version]) fullclangver=`$CC -v 2>&1 | grep version` + if echo $fullclangver | grep 'Apple' >/dev/null; then + appleclang=1 + else + appleclang=0 + fi clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*)/\1/'` if test -z "$clangver"; then - if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then - dnl Starting with XCode 7 / clang 3.7, Apple clang won't tell its upstream version - clangver="3.7" - else - clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` - fi + clangver=`echo $fullclangver | "$SED" 's/.*version \(@<:@0-9@:>@*\.@<:@0-9@:>@*\).*/\1/'` + oldapple=0 + else + oldapple=1 fi clangvhi=`echo $clangver | cut -d . -f1` clangvlo=`echo $clangver | cut -d . -f2` compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` + if test "$appleclang" = '1' && test "$oldapple" = '0'; then + dnl Starting with Xcode 7 / clang 3.7, Apple clang won't tell its upstream version + if test "$compiler_num" -ge '1300'; then compiler_num='1200' + elif test "$compiler_num" -ge '1205'; then compiler_num='1101' + elif test "$compiler_num" -ge '1204'; then compiler_num='1000' + elif test "$compiler_num" -ge '1107'; then compiler_num='900' + elif test "$compiler_num" -ge '1103'; then compiler_num='800' + elif test "$compiler_num" -ge '1003'; then compiler_num='700' + elif test "$compiler_num" -ge '1001'; then compiler_num='600' + elif test "$compiler_num" -ge '904'; then compiler_num='500' + elif test "$compiler_num" -ge '902'; then compiler_num='400' + elif test "$compiler_num" -ge '803'; then compiler_num='309' + elif test "$compiler_num" -ge '703'; then compiler_num='308' + else compiler_num='307' + fi + fi + AC_MSG_RESULT([clang '$compiler_num' (raw: '$fullclangver' / '$clangver')]) flags_dbg_yes="-g" flags_opt_all="-O -O0 -O1 -O2 -Os -O3 -O4" flags_opt_yes="-O2" @@ -159,10 +179,17 @@ AC_DEFUN([CURL_CHECK_COMPILER_GNU_C], [ test "$compiler_id" = "unknown"; then AC_MSG_RESULT([yes]) compiler_id="GNU_C" - gccver=`$CC -dumpversion` + AC_MSG_CHECKING([compiler version]) + # strip '-suffix' parts, e.g. Ubuntu Windows cross-gcc returns '10-win32' + gccver=`$CC -dumpversion | sed -E 's/-.+$//'` gccvhi=`echo $gccver | cut -d . -f1` - gccvlo=`echo $gccver | cut -d . -f2` + if echo $gccver | grep -F '.' >/dev/null; then + gccvlo=`echo $gccver | cut -d . -f2` + else + gccvlo="0" + fi compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null` + AC_MSG_RESULT([gcc '$compiler_num' (raw: '$gccver')]) flags_dbg_yes="-g" flags_opt_all="-O -O0 -O1 -O2 -O3 -Os -Og -Ofast" flags_opt_yes="-O2" @@ -232,7 +259,9 @@ AC_DEFUN([CURL_CHECK_COMPILER_INTEL_C], [ CURL_CHECK_DEF([__INTEL_COMPILER], [], [silent]) if test "$curl_cv_have_def___INTEL_COMPILER" = "yes"; then AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([compiler version]) compiler_num="$curl_cv_def___INTEL_COMPILER" + AC_MSG_RESULT([Intel C '$compiler_num']) CURL_CHECK_DEF([__unix__], [], [silent]) if test "$curl_cv_have_def___unix__" = "yes"; then compiler_id="INTEL_UNIX_C" @@ -253,26 +282,6 @@ AC_DEFUN([CURL_CHECK_COMPILER_INTEL_C], [ ]) -dnl CURL_CHECK_COMPILER_LCC -dnl ------------------------------------------------- -dnl Verify if compiler being used is LCC. - -AC_DEFUN([CURL_CHECK_COMPILER_LCC], [ - AC_MSG_CHECKING([if compiler is LCC]) - CURL_CHECK_DEF([__LCC__], [], [silent]) - if test "$curl_cv_have_def___LCC__" = "yes"; then - AC_MSG_RESULT([yes]) - compiler_id="LCC" - flags_dbg_yes="-g" - flags_opt_all="" - flags_opt_yes="" - flags_opt_off="" - else - AC_MSG_RESULT([no]) - fi -]) - - dnl CURL_CHECK_COMPILER_SGI_MIPS_C dnl ------------------------------------------------- dnl Verify if compiler being used is SGI MIPS C. @@ -580,12 +589,6 @@ AC_DEFUN([CURL_SET_COMPILER_BASIC_OPTS], [ tmp_CFLAGS="$tmp_CFLAGS" ;; # - LCC) - # - dnl Disallow run-time dereferencing of null pointers - tmp_CFLAGS="$tmp_CFLAGS -n" - ;; - # SGI_MIPS_C) # dnl Placeholder @@ -787,7 +790,8 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-prototypes]) tmp_CFLAGS="$tmp_CFLAGS -Wno-long-long" CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [float-equal]) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [no-multichar sign-compare]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sign-compare]) + tmp_CFLAGS="$tmp_CFLAGS -Wno-multichar" CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [undef]) tmp_CFLAGS="$tmp_CFLAGS -Wno-format-nonliteral" CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [endif-labels strict-prototypes]) @@ -801,29 +805,46 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused]) fi # + dnl Only clang 2.7 or later + if test "$compiler_num" -ge "207"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [address]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [attributes]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [bad-function-cast]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [conversion]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [div-by-zero format-security]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [empty-body]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-field-initializers]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-noreturn]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [old-style-definition]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [redundant-decls]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [switch-enum]) # Not used because this basically disallows default case + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [type-limits]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-macros]) # Not practical + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unreachable-code unused-parameter]) + fi + # dnl Only clang 2.8 or later if test "$compiler_num" -ge "208"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [ignored-qualifiers]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [vla]) fi # dnl Only clang 2.9 or later if test "$compiler_num" -ge "209"; then + tmp_CFLAGS="$tmp_CFLAGS -Wno-sign-conversion" CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [shift-sign-overflow]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [padded]) # Not used because we cannot change public structs fi # - dnl Only clang 3.0 or later (possibly earlier) + dnl Only clang 3.0 or later if test "$compiler_num" -ge "300"; then - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [bad-function-cast]) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [conversion]) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [empty-body]) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [ignored-qualifiers]) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [type-limits]) - CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [no-sign-conversion]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [language-extension-token]) fi # dnl Only clang 3.2 or later if test "$compiler_num" -ge "302"; then CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [enum-conversion]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [sometimes-uninitialized]) case $host_os in cygwin* | mingw*) dnl skip missing-variable-declarations warnings for cygwin and @@ -837,9 +858,16 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ # dnl Only clang 3.4 or later if test "$compiler_num" -ge "304"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [header-guard]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-const-variable]) fi # + dnl Only clang 3.5 or later + if test "$compiler_num" -ge "305"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [pragmas]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unreachable-code-break]) + fi + # dnl Only clang 3.6 or later if test "$compiler_num" -ge "306"; then CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [double-promotion]) @@ -877,7 +905,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ GNU_C) # if test "$want_warnings" = "yes"; then - tmp_CFLAGS="$tmp_CFLAGS -std=gnu89" # dnl Do not enable -pedantic when cross-compiling with a gcc older dnl than 3.0, to avoid warnings from third party system headers. @@ -958,6 +985,26 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ tmp_CFLAGS="$tmp_CFLAGS -Wstrict-aliasing=3" fi # + dnl Only gcc 4.1 or later + if test "$compiler_num" -ge "401"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [attributes]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [div-by-zero format-security]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-field-initializers]) + case $host in + *-*-msys*) + ;; + *) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-noreturn]) # Seen to clash with libtool-generated stub code + ;; + esac + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unreachable-code unused-parameter]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [padded]) # Not used because we cannot change public structs + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [pragmas]) + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [redundant-decls]) + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [switch-enum]) # Not used because this basically disallows default case + # CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [unused-macros]) # Not practical + fi + # dnl Only gcc 4.2 or later if test "$compiler_num" -ge "402"; then CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [cast-align]) @@ -965,6 +1012,7 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ # dnl Only gcc 4.3 or later if test "$compiler_num" -ge "403"; then + CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [address]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [type-limits old-style-declaration]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [missing-parameter-type empty-body]) CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [clobbered ignored-qualifiers]) @@ -1105,17 +1153,6 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [ tmp_CFLAGS="$tmp_CFLAGS" ;; # - LCC) - # - if test "$want_warnings" = "yes"; then - dnl Highest warning level is double -A, next is single -A. - dnl Due to the big number of warnings these trigger on third - dnl party header files it is impractical for us to use any of - dnl them here. If you want them simply define it in CPPFLAGS. - tmp_CFLAGS="$tmp_CFLAGS" - fi - ;; - # SGI_MIPS_C) # if test "$want_warnings" = "yes"; then diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4 index 7fefa3967..28f4b8b9a 100644 --- a/m4/curl-functions.m4 +++ b/m4/curl-functions.m4 @@ -108,35 +108,6 @@ curl_includes_ifaddrs="\ ]) -dnl CURL_INCLUDES_INTTYPES -dnl ------------------------------------------------- -dnl Set up variable with list of headers that must be -dnl included when inttypes.h is to be included. - -AC_DEFUN([CURL_INCLUDES_INTTYPES], [ -curl_includes_inttypes="\ -/* includes start */ -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -/* includes end */" - case $host_os in - irix*) - ac_cv_header_stdint_h="no" - ;; - esac - AC_CHECK_HEADERS( - sys/types.h stdint.h inttypes.h, - [], [], [$curl_includes_inttypes]) -]) - - dnl CURL_INCLUDES_LIBGEN dnl ------------------------------------------------- dnl Set up variable with list of headers that must be @@ -447,10 +418,10 @@ curl_includes_winsock2="\ # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # endif +# include #endif /* includes end */" CURL_CHECK_HEADER_WINDOWS @@ -470,13 +441,13 @@ curl_includes_ws2tcpip="\ # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif -# include # ifdef HAVE_WINSOCK2_H # include # ifdef HAVE_WS2TCPIP_H # include # endif # endif +# include #endif /* includes end */" CURL_CHECK_HEADER_WINDOWS diff --git a/m4/curl-openssl.m4 b/m4/curl-openssl.m4 index a4811d2a3..608653c5c 100644 --- a/m4/curl-openssl.m4 +++ b/m4/curl-openssl.m4 @@ -312,7 +312,7 @@ if test "x$OPT_OPENSSL" != xno; then AC_LANG_PROGRAM([[ #include ]],[[ - #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) + #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) return 0; #else #error older than 3 diff --git a/projects/Windows/VC14.20/.gitignore b/projects/Windows/VC14.20/.gitignore new file mode 100644 index 000000000..11504d2c1 --- /dev/null +++ b/projects/Windows/VC14.20/.gitignore @@ -0,0 +1,9 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +/*.opendb +/*.opensdf +/*.sdf +/*.vc.db +/.vs diff --git a/projects/Windows/VC14.20/curl-all.sln b/projects/Windows/VC14.20/curl-all.sln new file mode 100644 index 000000000..992310090 --- /dev/null +++ b/projects/Windows/VC14.20/curl-all.sln @@ -0,0 +1,298 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curl", "src\curl.vcxproj", "{5228E9CE-A216-422F-A5E6-58E95E2DD71D}" + ProjectSection(ProjectDependencies) = postProject + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} = {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "lib\libcurl.vcxproj", "{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + DLL Debug - DLL OpenSSL|Win32 = DLL Debug - DLL OpenSSL|Win32 + DLL Debug - DLL OpenSSL|x64 = DLL Debug - DLL OpenSSL|x64 + DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + DLL Debug - DLL Windows SSPI|Win32 = DLL Debug - DLL Windows SSPI|Win32 + DLL Debug - DLL Windows SSPI|x64 = DLL Debug - DLL Windows SSPI|x64 + DLL Debug - DLL wolfSSL|Win32 = DLL Debug - DLL wolfSSL|Win32 + DLL Debug - DLL wolfSSL|x64 = DLL Debug - DLL wolfSSL|x64 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Debug|x64 = DLL Debug|x64 + DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + DLL Release - DLL OpenSSL - DLL LibSSH2|x64 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + DLL Release - DLL OpenSSL|Win32 = DLL Release - DLL OpenSSL|Win32 + DLL Release - DLL OpenSSL|x64 = DLL Release - DLL OpenSSL|x64 + DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + DLL Release - DLL Windows SSPI - DLL WinIDN|x64 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + DLL Release - DLL Windows SSPI|Win32 = DLL Release - DLL Windows SSPI|Win32 + DLL Release - DLL Windows SSPI|x64 = DLL Release - DLL Windows SSPI|x64 + DLL Release - DLL wolfSSL|Win32 = DLL Release - DLL wolfSSL|Win32 + DLL Release - DLL wolfSSL|x64 = DLL Release - DLL wolfSSL|x64 + DLL Release|Win32 = DLL Release|Win32 + DLL Release|x64 = DLL Release|x64 + LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + LIB Debug - DLL OpenSSL|Win32 = LIB Debug - DLL OpenSSL|Win32 + LIB Debug - DLL OpenSSL|x64 = LIB Debug - DLL OpenSSL|x64 + LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + LIB Debug - DLL Windows SSPI|Win32 = LIB Debug - DLL Windows SSPI|Win32 + LIB Debug - DLL Windows SSPI|x64 = LIB Debug - DLL Windows SSPI|x64 + LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + LIB Debug - LIB OpenSSL|Win32 = LIB Debug - LIB OpenSSL|Win32 + LIB Debug - LIB OpenSSL|x64 = LIB Debug - LIB OpenSSL|x64 + LIB Debug - LIB wolfSSL|Win32 = LIB Debug - LIB wolfSSL|Win32 + LIB Debug - LIB wolfSSL|x64 = LIB Debug - LIB wolfSSL|x64 + LIB Debug|Win32 = LIB Debug|Win32 + LIB Debug|x64 = LIB Debug|x64 + LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + LIB Release - DLL OpenSSL - DLL LibSSH2|x64 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + LIB Release - DLL OpenSSL|Win32 = LIB Release - DLL OpenSSL|Win32 + LIB Release - DLL OpenSSL|x64 = LIB Release - DLL OpenSSL|x64 + LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + LIB Release - DLL Windows SSPI - DLL WinIDN|x64 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + LIB Release - DLL Windows SSPI|Win32 = LIB Release - DLL Windows SSPI|Win32 + LIB Release - DLL Windows SSPI|x64 = LIB Release - DLL Windows SSPI|x64 + LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + LIB Release - LIB OpenSSL - LIB LibSSH2|x64 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + LIB Release - LIB OpenSSL|Win32 = LIB Release - LIB OpenSSL|Win32 + LIB Release - LIB OpenSSL|x64 = LIB Release - LIB OpenSSL|x64 + LIB Release - LIB wolfSSL|Win32 = LIB Release - LIB wolfSSL|Win32 + LIB Release - LIB wolfSSL|x64 = LIB Release - LIB wolfSSL|x64 + LIB Release|Win32 = LIB Release|Win32 + LIB Release|x64 = LIB Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|Win32.ActiveCfg = DLL Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|Win32.Build.0 = DLL Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|x64.ActiveCfg = DLL Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|x64.Build.0 = DLL Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|Win32.Build.0 = DLL Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|x64.ActiveCfg = DLL Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|x64.Build.0 = DLL Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|Win32.ActiveCfg = DLL Debug - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|Win32.Build.0 = DLL Debug - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|x64.ActiveCfg = DLL Debug - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|x64.Build.0 = DLL Debug - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|Win32.ActiveCfg = DLL Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|Win32.Build.0 = DLL Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|x64.ActiveCfg = DLL Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|x64.Build.0 = DLL Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|Win32.ActiveCfg = DLL Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|Win32.Build.0 = DLL Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|x64.ActiveCfg = DLL Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|x64.Build.0 = DLL Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|Win32.ActiveCfg = DLL Release - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|Win32.Build.0 = DLL Release - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|x64.ActiveCfg = DLL Release - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|x64.Build.0 = DLL Release - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|x64.Build.0 = DLL Release|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|Win32.ActiveCfg = LIB Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|Win32.Build.0 = LIB Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|x64.ActiveCfg = LIB Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|x64.Build.0 = LIB Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|Win32.Build.0 = LIB Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|x64.ActiveCfg = LIB Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|x64.Build.0 = LIB Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|Win32.ActiveCfg = LIB Debug - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|Win32.Build.0 = LIB Debug - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|x64.ActiveCfg = LIB Debug - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|x64.Build.0 = LIB Debug - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|Win32.ActiveCfg = LIB Debug - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|Win32.Build.0 = LIB Debug - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|x64.ActiveCfg = LIB Debug - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|x64.Build.0 = LIB Debug - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|Win32.ActiveCfg = LIB Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|Win32.Build.0 = LIB Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|x64.ActiveCfg = LIB Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|x64.Build.0 = LIB Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|Win32.ActiveCfg = LIB Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|Win32.Build.0 = LIB Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|x64.ActiveCfg = LIB Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|x64.Build.0 = LIB Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|Win32.ActiveCfg = LIB Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|Win32.Build.0 = LIB Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|x64.ActiveCfg = LIB Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|x64.Build.0 = LIB Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|Win32.ActiveCfg = LIB Release - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|Win32.Build.0 = LIB Release - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|x64.ActiveCfg = LIB Release - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|x64.Build.0 = LIB Release - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|Win32.ActiveCfg = LIB Release - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|Win32.Build.0 = LIB Release - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|x64.ActiveCfg = LIB Release - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|x64.Build.0 = LIB Release - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|Win32.ActiveCfg = LIB Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|Win32.Build.0 = LIB Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|x64.ActiveCfg = LIB Release|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|x64.Build.0 = LIB Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|Win32.ActiveCfg = DLL Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|Win32.Build.0 = DLL Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|x64.ActiveCfg = DLL Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|x64.Build.0 = DLL Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|Win32.Build.0 = DLL Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|x64.ActiveCfg = DLL Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|x64.Build.0 = DLL Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|Win32.ActiveCfg = DLL Debug - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|Win32.Build.0 = DLL Debug - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|x64.ActiveCfg = DLL Debug - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|x64.Build.0 = DLL Debug - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|Win32.ActiveCfg = DLL Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|Win32.Build.0 = DLL Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|x64.ActiveCfg = DLL Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|x64.Build.0 = DLL Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|Win32.ActiveCfg = DLL Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|Win32.Build.0 = DLL Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|x64.ActiveCfg = DLL Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|x64.Build.0 = DLL Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|Win32.ActiveCfg = DLL Release - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|Win32.Build.0 = DLL Release - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|x64.ActiveCfg = DLL Release - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|x64.Build.0 = DLL Release - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|x64.Build.0 = DLL Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|Win32.ActiveCfg = LIB Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|Win32.Build.0 = LIB Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|x64.ActiveCfg = LIB Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|x64.Build.0 = LIB Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|Win32.Build.0 = LIB Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|x64.ActiveCfg = LIB Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|x64.Build.0 = LIB Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|Win32.ActiveCfg = LIB Debug - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|Win32.Build.0 = LIB Debug - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|x64.ActiveCfg = LIB Debug - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|x64.Build.0 = LIB Debug - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|Win32.ActiveCfg = LIB Debug - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|Win32.Build.0 = LIB Debug - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|x64.ActiveCfg = LIB Debug - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|x64.Build.0 = LIB Debug - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|Win32.ActiveCfg = LIB Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|Win32.Build.0 = LIB Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|x64.ActiveCfg = LIB Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|x64.Build.0 = LIB Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|Win32.ActiveCfg = LIB Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|Win32.Build.0 = LIB Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|x64.ActiveCfg = LIB Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|x64.Build.0 = LIB Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|Win32.ActiveCfg = LIB Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|Win32.Build.0 = LIB Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|x64.ActiveCfg = LIB Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|x64.Build.0 = LIB Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|Win32.ActiveCfg = LIB Release - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|Win32.Build.0 = LIB Release - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|x64.ActiveCfg = LIB Release - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|x64.Build.0 = LIB Release - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|Win32.ActiveCfg = LIB Release - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|Win32.Build.0 = LIB Release - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|x64.ActiveCfg = LIB Release - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|x64.Build.0 = LIB Release - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|Win32.ActiveCfg = LIB Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|Win32.Build.0 = LIB Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|x64.ActiveCfg = LIB Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|x64.Build.0 = LIB Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/Windows/VC14.20/lib/.gitignore b/projects/Windows/VC14.20/lib/.gitignore new file mode 100644 index 000000000..5baee8342 --- /dev/null +++ b/projects/Windows/VC14.20/lib/.gitignore @@ -0,0 +1,10 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +/*.opensdf +/*.sdf +/*.user +/*.vc.db +/*.vcxproj +/.vs diff --git a/projects/Windows/VC14.20/lib/libcurl.sln b/projects/Windows/VC14.20/lib/libcurl.sln new file mode 100644 index 000000000..e34b5eb5d --- /dev/null +++ b/projects/Windows/VC14.20/lib/libcurl.sln @@ -0,0 +1,181 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 17 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "libcurl.vcxproj", "{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + DLL Debug - DLL OpenSSL|Win32 = DLL Debug - DLL OpenSSL|Win32 + DLL Debug - DLL OpenSSL|x64 = DLL Debug - DLL OpenSSL|x64 + DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + DLL Debug - DLL Windows SSPI|Win32 = DLL Debug - DLL Windows SSPI|Win32 + DLL Debug - DLL Windows SSPI|x64 = DLL Debug - DLL Windows SSPI|x64 + DLL Debug - DLL wolfSSL|Win32 = DLL Debug - DLL wolfSSL|Win32 + DLL Debug - DLL wolfSSL|x64 = DLL Debug - DLL wolfSSL|x64 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Debug|x64 = DLL Debug|x64 + DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + DLL Release - DLL OpenSSL - DLL LibSSH2|x64 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + DLL Release - DLL OpenSSL|Win32 = DLL Release - DLL OpenSSL|Win32 + DLL Release - DLL OpenSSL|x64 = DLL Release - DLL OpenSSL|x64 + DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + DLL Release - DLL Windows SSPI - DLL WinIDN|x64 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + DLL Release - DLL Windows SSPI|Win32 = DLL Release - DLL Windows SSPI|Win32 + DLL Release - DLL Windows SSPI|x64 = DLL Release - DLL Windows SSPI|x64 + DLL Release - DLL wolfSSL|Win32 = DLL Release - DLL wolfSSL|Win32 + DLL Release - DLL wolfSSL|x64 = DLL Release - DLL wolfSSL|x64 + DLL Release|Win32 = DLL Release|Win32 + DLL Release|x64 = DLL Release|x64 + LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + LIB Debug - DLL OpenSSL|Win32 = LIB Debug - DLL OpenSSL|Win32 + LIB Debug - DLL OpenSSL|x64 = LIB Debug - DLL OpenSSL|x64 + LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + LIB Debug - DLL Windows SSPI|Win32 = LIB Debug - DLL Windows SSPI|Win32 + LIB Debug - DLL Windows SSPI|x64 = LIB Debug - DLL Windows SSPI|x64 + LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + LIB Debug - LIB OpenSSL|Win32 = LIB Debug - LIB OpenSSL|Win32 + LIB Debug - LIB OpenSSL|x64 = LIB Debug - LIB OpenSSL|x64 + LIB Debug - LIB wolfSSL|Win32 = LIB Debug - LIB wolfSSL|Win32 + LIB Debug - LIB wolfSSL|x64 = LIB Debug - LIB wolfSSL|x64 + LIB Debug|Win32 = LIB Debug|Win32 + LIB Debug|x64 = LIB Debug|x64 + LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + LIB Release - DLL OpenSSL - DLL LibSSH2|x64 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + LIB Release - DLL OpenSSL|Win32 = LIB Release - DLL OpenSSL|Win32 + LIB Release - DLL OpenSSL|x64 = LIB Release - DLL OpenSSL|x64 + LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + LIB Release - DLL Windows SSPI - DLL WinIDN|x64 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + LIB Release - DLL Windows SSPI|Win32 = LIB Release - DLL Windows SSPI|Win32 + LIB Release - DLL Windows SSPI|x64 = LIB Release - DLL Windows SSPI|x64 + LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + LIB Release - LIB OpenSSL - LIB LibSSH2|x64 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + LIB Release - LIB OpenSSL|Win32 = LIB Release - LIB OpenSSL|Win32 + LIB Release - LIB OpenSSL|x64 = LIB Release - LIB OpenSSL|x64 + LIB Release - LIB wolfSSL|Win32 = LIB Release - LIB wolfSSL|Win32 + LIB Release - LIB wolfSSL|x64 = LIB Release - LIB wolfSSL|x64 + LIB Release|Win32 = LIB Release|Win32 + LIB Release|x64 = LIB Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|Win32.ActiveCfg = DLL Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|Win32.Build.0 = DLL Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|x64.ActiveCfg = DLL Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL OpenSSL|x64.Build.0 = DLL Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|Win32.Build.0 = DLL Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|x64.ActiveCfg = DLL Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL Windows SSPI|x64.Build.0 = DLL Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|Win32.ActiveCfg = DLL Debug - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|Win32.Build.0 = DLL Debug - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|x64.ActiveCfg = DLL Debug - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug - DLL wolfSSL|x64.Build.0 = DLL Debug - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|Win32.ActiveCfg = DLL Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|Win32.Build.0 = DLL Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|x64.ActiveCfg = DLL Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL OpenSSL|x64.Build.0 = DLL Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|Win32.ActiveCfg = DLL Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|Win32.Build.0 = DLL Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|x64.ActiveCfg = DLL Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL Windows SSPI|x64.Build.0 = DLL Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|Win32.ActiveCfg = DLL Release - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|Win32.Build.0 = DLL Release - DLL wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|x64.ActiveCfg = DLL Release - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release - DLL wolfSSL|x64.Build.0 = DLL Release - DLL wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.DLL Release|x64.Build.0 = DLL Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|Win32.ActiveCfg = LIB Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|Win32.Build.0 = LIB Debug - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|x64.ActiveCfg = LIB Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL OpenSSL|x64.Build.0 = LIB Debug - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|Win32.Build.0 = LIB Debug - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|x64.ActiveCfg = LIB Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - DLL Windows SSPI|x64.Build.0 = LIB Debug - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|Win32.ActiveCfg = LIB Debug - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|Win32.Build.0 = LIB Debug - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|x64.ActiveCfg = LIB Debug - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB OpenSSL|x64.Build.0 = LIB Debug - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|Win32.ActiveCfg = LIB Debug - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|Win32.Build.0 = LIB Debug - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|x64.ActiveCfg = LIB Debug - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug - LIB wolfSSL|x64.Build.0 = LIB Debug - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|Win32.ActiveCfg = LIB Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|Win32.Build.0 = LIB Debug|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|x64.ActiveCfg = LIB Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Debug|x64.Build.0 = LIB Debug|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|Win32.ActiveCfg = LIB Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|Win32.Build.0 = LIB Release - DLL OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|x64.ActiveCfg = LIB Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL OpenSSL|x64.Build.0 = LIB Release - DLL OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|Win32.ActiveCfg = LIB Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|Win32.Build.0 = LIB Release - DLL Windows SSPI|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|x64.ActiveCfg = LIB Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - DLL Windows SSPI|x64.Build.0 = LIB Release - DLL Windows SSPI|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|Win32.ActiveCfg = LIB Release - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|Win32.Build.0 = LIB Release - LIB OpenSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|x64.ActiveCfg = LIB Release - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB OpenSSL|x64.Build.0 = LIB Release - LIB OpenSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|Win32.ActiveCfg = LIB Release - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|Win32.Build.0 = LIB Release - LIB wolfSSL|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|x64.ActiveCfg = LIB Release - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release - LIB wolfSSL|x64.Build.0 = LIB Release - LIB wolfSSL|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|Win32.ActiveCfg = LIB Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|Win32.Build.0 = LIB Release|Win32 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|x64.ActiveCfg = LIB Release|x64 + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}.LIB Release|x64.Build.0 = LIB Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/Windows/VC14.20/lib/libcurl.tmpl b/projects/Windows/VC14.20/lib/libcurl.tmpl new file mode 100644 index 000000000..ff88b4220 --- /dev/null +++ b/projects/Windows/VC14.20/lib/libcurl.tmpl @@ -0,0 +1,2381 @@ + + + + + DLL Debug - DLL wolfSSL + Win32 + + + DLL Debug - DLL wolfSSL + x64 + + + DLL Debug - DLL OpenSSL - DLL LibSSH2 + Win32 + + + DLL Debug - DLL OpenSSL - DLL LibSSH2 + x64 + + + DLL Debug - DLL OpenSSL + Win32 + + + DLL Debug - DLL OpenSSL + x64 + + + DLL Debug - DLL Windows SSPI - DLL WinIDN + Win32 + + + DLL Debug - DLL Windows SSPI - DLL WinIDN + x64 + + + DLL Debug - DLL Windows SSPI + Win32 + + + DLL Debug - DLL Windows SSPI + x64 + + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release - DLL wolfSSL + Win32 + + + DLL Release - DLL wolfSSL + x64 + + + DLL Release - DLL OpenSSL - DLL LibSSH2 + Win32 + + + DLL Release - DLL OpenSSL - DLL LibSSH2 + x64 + + + DLL Release - DLL OpenSSL + Win32 + + + DLL Release - DLL OpenSSL + x64 + + + DLL Release - DLL Windows SSPI - DLL WinIDN + Win32 + + + DLL Release - DLL Windows SSPI - DLL WinIDN + x64 + + + DLL Release - DLL Windows SSPI + Win32 + + + DLL Release - DLL Windows SSPI + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + + + LIB Debug - DLL OpenSSL - DLL LibSSH2 + Win32 + + + LIB Debug - DLL OpenSSL - DLL LibSSH2 + x64 + + + LIB Debug - DLL OpenSSL + Win32 + + + LIB Debug - DLL OpenSSL + x64 + + + LIB Debug - DLL Windows SSPI - DLL WinIDN + Win32 + + + LIB Debug - DLL Windows SSPI - DLL WinIDN + x64 + + + LIB Debug - DLL Windows SSPI + Win32 + + + LIB Debug - DLL Windows SSPI + x64 + + + LIB Debug - LIB wolfSSL + Win32 + + + LIB Debug - LIB wolfSSL + x64 + + + LIB Debug - LIB OpenSSL - LIB LibSSH2 + Win32 + + + LIB Debug - LIB OpenSSL - LIB LibSSH2 + x64 + + + LIB Debug - LIB OpenSSL + Win32 + + + LIB Debug - LIB OpenSSL + x64 + + + LIB Debug + Win32 + + + LIB Debug + x64 + + + LIB Release - DLL OpenSSL - DLL LibSSH2 + Win32 + + + LIB Release - DLL OpenSSL - DLL LibSSH2 + x64 + + + LIB Release - DLL OpenSSL + Win32 + + + LIB Release - DLL OpenSSL + x64 + + + LIB Release - DLL Windows SSPI - DLL WinIDN + Win32 + + + LIB Release - DLL Windows SSPI - DLL WinIDN + x64 + + + LIB Release - DLL Windows SSPI + Win32 + + + LIB Release - DLL Windows SSPI + x64 + + + LIB Release - LIB wolfSSL + Win32 + + + LIB Release - LIB wolfSSL + x64 + + + LIB Release - LIB OpenSSL - LIB LibSSH2 + Win32 + + + LIB Release - LIB OpenSSL - LIB LibSSH2 + x64 + + + LIB Release - LIB OpenSSL + Win32 + + + LIB Release - LIB OpenSSL + x64 + + + LIB Release + Win32 + + + LIB Release + x64 + + + + {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} + libcurl + + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + StaticLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)lib\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)lib\ + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + + + + _DEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_WOLFSSL;USE_IPV6;WOLFSSL_DLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + 4214 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\wolfssl\build\Win32\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_WOLFSSL;USE_IPV6;WOLFSSL_DLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + 4214 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\wolfssl\build\Win64\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_WOLFSSL;USE_IPV6;WOLFSSL_DLL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + 4214 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\wolfssl\build\Win32\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + $(TargetDir)$(TargetName).lib + MachineX86 + true + $(TargetDir)$(TargetName).pdb + + + + + NDEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_WOLFSSL;USE_IPV6;WOLFSSL_DLL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + 4214 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\wolfssl\build\Win64\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + MachineX64 + true + $(TargetDir)$(TargetName).pdb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_WOLFSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + 4214 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_WOLFSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + 4214 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_WOLFSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + 4214 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\wolfssl;..\..\..\..\..\wolfssl\wolfssl;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_WOLFSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + 4214 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + %(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;libssh2d.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Debug;..\..\..\..\..\libssh2\build\Win32\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;libssh2d.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Debug;..\..\..\..\..\libssh2\build\Win64\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + Win32 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;libssh2.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Release;..\..\..\..\..\libssh2\build\Win32\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + $(IntDir)$(TargetFileName).intermediate.manifest + $(TargetDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + X64 + $(OutDir)$(ProjectName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcrypto.lib;libssl.lib;libssh2.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Release;..\..\..\..\..\libssh2\build\Win64\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + MachineX64 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Debug\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\LIB Debug\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\LIB Debug\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\LIB Debug\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\LIB Debug\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + _DEBUG;BUILDING_LIBCURL;DEBUGBUILD;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\DLL Release\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_WINDOWS_SSPI;USE_SCHANNEL;USE_WIN32_IDN;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\LIB Release\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\LIB Release\include;..\..\..\..\..\openssl\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win32\VC14.20\LIB Release\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX86 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;..\..\..\..\..\openssl\include\..\build\Win64\VC14.20\LIB Release\include;..\..\..\..\..\openssl\include;..\..\..\..\..\libssh2\include;%(AdditionalIncludeDirectories) + NDEBUG;BUILDING_LIBCURL;CURL_STATICLIB;USE_OPENSSL;USE_LIBSSH2;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(TargetName)$(TargetExt) + MachineX64 + + + +CURL_LIB_C_FILES +CURL_LIB_VAUTH_C_FILES +CURL_LIB_VQUIC_C_FILES +CURL_LIB_VSSH_C_FILES +CURL_LIB_VTLS_C_FILES + + +CURL_LIB_H_FILES +CURL_LIB_VAUTH_H_FILES +CURL_LIB_VQUIC_H_FILES +CURL_LIB_VSSH_H_FILES +CURL_LIB_VTLS_H_FILES + + +CURL_LIB_RC_FILES + + + + + \ No newline at end of file diff --git a/projects/Windows/VC14.20/lib/libcurl.vcxproj.filters b/projects/Windows/VC14.20/lib/libcurl.vcxproj.filters new file mode 100644 index 000000000..4d6341d74 --- /dev/null +++ b/projects/Windows/VC14.20/lib/libcurl.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + \ No newline at end of file diff --git a/projects/Windows/VC14.20/src/.gitignore b/projects/Windows/VC14.20/src/.gitignore new file mode 100644 index 000000000..5baee8342 --- /dev/null +++ b/projects/Windows/VC14.20/src/.gitignore @@ -0,0 +1,10 @@ +# Copyright (C) Daniel Stenberg, , et al. +# +# SPDX-License-Identifier: curl + +/*.opensdf +/*.sdf +/*.user +/*.vc.db +/*.vcxproj +/.vs diff --git a/projects/Windows/VC14.20/src/curl.sln b/projects/Windows/VC14.20/src/curl.sln new file mode 100644 index 000000000..5cfa4ce24 --- /dev/null +++ b/projects/Windows/VC14.20/src/curl.sln @@ -0,0 +1,181 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 16 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curl", "curl.vcxproj", "{5228E9CE-A216-422F-A5E6-58E95E2DD71D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + DLL Debug - DLL OpenSSL|Win32 = DLL Debug - DLL OpenSSL|Win32 + DLL Debug - DLL OpenSSL|x64 = DLL Debug - DLL OpenSSL|x64 + DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + DLL Debug - DLL Windows SSPI|Win32 = DLL Debug - DLL Windows SSPI|Win32 + DLL Debug - DLL Windows SSPI|x64 = DLL Debug - DLL Windows SSPI|x64 + DLL Debug - DLL wolfSSL|Win32 = DLL Debug - DLL wolfSSL|Win32 + DLL Debug - DLL wolfSSL|x64 = DLL Debug - DLL wolfSSL|x64 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Debug|x64 = DLL Debug|x64 + DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + DLL Release - DLL OpenSSL - DLL LibSSH2|x64 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + DLL Release - DLL OpenSSL|Win32 = DLL Release - DLL OpenSSL|Win32 + DLL Release - DLL OpenSSL|x64 = DLL Release - DLL OpenSSL|x64 + DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + DLL Release - DLL Windows SSPI - DLL WinIDN|x64 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + DLL Release - DLL Windows SSPI|Win32 = DLL Release - DLL Windows SSPI|Win32 + DLL Release - DLL Windows SSPI|x64 = DLL Release - DLL Windows SSPI|x64 + DLL Release - DLL wolfSSL|Win32 = DLL Release - DLL wolfSSL|Win32 + DLL Release - DLL wolfSSL|x64 = DLL Release - DLL wolfSSL|x64 + DLL Release|Win32 = DLL Release|Win32 + DLL Release|x64 = DLL Release|x64 + LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + LIB Debug - DLL OpenSSL|Win32 = LIB Debug - DLL OpenSSL|Win32 + LIB Debug - DLL OpenSSL|x64 = LIB Debug - DLL OpenSSL|x64 + LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + LIB Debug - DLL Windows SSPI|Win32 = LIB Debug - DLL Windows SSPI|Win32 + LIB Debug - DLL Windows SSPI|x64 = LIB Debug - DLL Windows SSPI|x64 + LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + LIB Debug - LIB OpenSSL|Win32 = LIB Debug - LIB OpenSSL|Win32 + LIB Debug - LIB OpenSSL|x64 = LIB Debug - LIB OpenSSL|x64 + LIB Debug - LIB wolfSSL|Win32 = LIB Debug - LIB wolfSSL|Win32 + LIB Debug - LIB wolfSSL|x64 = LIB Debug - LIB wolfSSL|x64 + LIB Debug|Win32 = LIB Debug|Win32 + LIB Debug|x64 = LIB Debug|x64 + LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + LIB Release - DLL OpenSSL - DLL LibSSH2|x64 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + LIB Release - DLL OpenSSL|Win32 = LIB Release - DLL OpenSSL|Win32 + LIB Release - DLL OpenSSL|x64 = LIB Release - DLL OpenSSL|x64 + LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + LIB Release - DLL Windows SSPI - DLL WinIDN|x64 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + LIB Release - DLL Windows SSPI|Win32 = LIB Release - DLL Windows SSPI|Win32 + LIB Release - DLL Windows SSPI|x64 = LIB Release - DLL Windows SSPI|x64 + LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + LIB Release - LIB OpenSSL - LIB LibSSH2|x64 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + LIB Release - LIB OpenSSL|Win32 = LIB Release - LIB OpenSSL|Win32 + LIB Release - LIB OpenSSL|x64 = LIB Release - LIB OpenSSL|x64 + LIB Release - LIB wolfSSL|Win32 = LIB Release - LIB wolfSSL|Win32 + LIB Release - LIB wolfSSL|x64 = LIB Release - LIB wolfSSL|x64 + LIB Release|Win32 = LIB Release|Win32 + LIB Release|x64 = LIB Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|Win32.ActiveCfg = DLL Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|Win32.Build.0 = DLL Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|x64.ActiveCfg = DLL Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL OpenSSL|x64.Build.0 = DLL Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|Win32.ActiveCfg = DLL Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|Win32.Build.0 = DLL Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|x64.ActiveCfg = DLL Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL Windows SSPI|x64.Build.0 = DLL Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|Win32.ActiveCfg = DLL Debug - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|Win32.Build.0 = DLL Debug - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|x64.ActiveCfg = DLL Debug - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug - DLL wolfSSL|x64.Build.0 = DLL Debug - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = DLL Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|Win32.ActiveCfg = DLL Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|Win32.Build.0 = DLL Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|x64.ActiveCfg = DLL Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL OpenSSL|x64.Build.0 = DLL Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = DLL Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|Win32.ActiveCfg = DLL Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|Win32.Build.0 = DLL Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|x64.ActiveCfg = DLL Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL Windows SSPI|x64.Build.0 = DLL Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|Win32.ActiveCfg = DLL Release - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|Win32.Build.0 = DLL Release - DLL wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|x64.ActiveCfg = DLL Release - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release - DLL wolfSSL|x64.Build.0 = DLL Release - DLL wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.DLL Release|x64.Build.0 = DLL Release|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Debug - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|Win32.ActiveCfg = LIB Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|Win32.Build.0 = LIB Debug - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|x64.ActiveCfg = LIB Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL OpenSSL|x64.Build.0 = LIB Debug - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Debug - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|Win32.ActiveCfg = LIB Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|Win32.Build.0 = LIB Debug - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|x64.ActiveCfg = LIB Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - DLL Windows SSPI|x64.Build.0 = LIB Debug - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Debug - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|Win32.ActiveCfg = LIB Debug - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|Win32.Build.0 = LIB Debug - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|x64.ActiveCfg = LIB Debug - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB OpenSSL|x64.Build.0 = LIB Debug - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|Win32.ActiveCfg = LIB Debug - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|Win32.Build.0 = LIB Debug - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|x64.ActiveCfg = LIB Debug - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug - LIB wolfSSL|x64.Build.0 = LIB Debug - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|Win32.ActiveCfg = LIB Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|Win32.Build.0 = LIB Debug|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|x64.ActiveCfg = LIB Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Debug|x64.Build.0 = LIB Debug|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|Win32.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.ActiveCfg = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL - DLL LibSSH2|x64.Build.0 = LIB Release - DLL OpenSSL - DLL LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|Win32.ActiveCfg = LIB Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|Win32.Build.0 = LIB Release - DLL OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|x64.ActiveCfg = LIB Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL OpenSSL|x64.Build.0 = LIB Release - DLL OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|Win32.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.ActiveCfg = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI - DLL WinIDN|x64.Build.0 = LIB Release - DLL Windows SSPI - DLL WinIDN|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|Win32.ActiveCfg = LIB Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|Win32.Build.0 = LIB Release - DLL Windows SSPI|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|x64.ActiveCfg = LIB Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - DLL Windows SSPI|x64.Build.0 = LIB Release - DLL Windows SSPI|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|Win32.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.ActiveCfg = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL - LIB LibSSH2|x64.Build.0 = LIB Release - LIB OpenSSL - LIB LibSSH2|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|Win32.ActiveCfg = LIB Release - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|Win32.Build.0 = LIB Release - LIB OpenSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|x64.ActiveCfg = LIB Release - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB OpenSSL|x64.Build.0 = LIB Release - LIB OpenSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|Win32.ActiveCfg = LIB Release - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|Win32.Build.0 = LIB Release - LIB wolfSSL|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|x64.ActiveCfg = LIB Release - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release - LIB wolfSSL|x64.Build.0 = LIB Release - LIB wolfSSL|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|Win32.ActiveCfg = LIB Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|Win32.Build.0 = LIB Release|Win32 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|x64.ActiveCfg = LIB Release|x64 + {5228E9CE-A216-422F-A5E6-58E95E2DD71D}.LIB Release|x64.Build.0 = LIB Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/Windows/VC14.20/src/curl.tmpl b/projects/Windows/VC14.20/src/curl.tmpl new file mode 100644 index 000000000..85c71768b --- /dev/null +++ b/projects/Windows/VC14.20/src/curl.tmpl @@ -0,0 +1,2671 @@ + + + + + DLL Debug - DLL wolfSSL + Win32 + + + DLL Debug - DLL wolfSSL + x64 + + + DLL Debug - DLL OpenSSL - DLL LibSSH2 + Win32 + + + DLL Debug - DLL OpenSSL - DLL LibSSH2 + x64 + + + DLL Debug - DLL OpenSSL + Win32 + + + DLL Debug - DLL OpenSSL + x64 + + + DLL Debug - DLL Windows SSPI - DLL WinIDN + Win32 + + + DLL Debug - DLL Windows SSPI - DLL WinIDN + x64 + + + DLL Debug - DLL Windows SSPI + Win32 + + + DLL Debug - DLL Windows SSPI + x64 + + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release - DLL wolfSSL + Win32 + + + DLL Release - DLL wolfSSL + x64 + + + DLL Release - DLL OpenSSL - DLL LibSSH2 + Win32 + + + DLL Release - DLL OpenSSL - DLL LibSSH2 + x64 + + + DLL Release - DLL OpenSSL + Win32 + + + DLL Release - DLL OpenSSL + x64 + + + DLL Release - DLL Windows SSPI - DLL WinIDN + Win32 + + + DLL Release - DLL Windows SSPI - DLL WinIDN + x64 + + + DLL Release - DLL Windows SSPI + Win32 + + + DLL Release - DLL Windows SSPI + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + + + LIB Debug - DLL OpenSSL - DLL LibSSH2 + Win32 + + + LIB Debug - DLL OpenSSL - DLL LibSSH2 + x64 + + + LIB Debug - DLL OpenSSL + Win32 + + + LIB Debug - DLL OpenSSL + x64 + + + LIB Debug - DLL Windows SSPI - DLL WinIDN + Win32 + + + LIB Debug - DLL Windows SSPI - DLL WinIDN + x64 + + + LIB Debug - DLL Windows SSPI + Win32 + + + LIB Debug - DLL Windows SSPI + x64 + + + LIB Debug - LIB wolfSSL + Win32 + + + LIB Debug - LIB wolfSSL + x64 + + + LIB Debug - LIB OpenSSL - LIB LibSSH2 + Win32 + + + LIB Debug - LIB OpenSSL - LIB LibSSH2 + x64 + + + LIB Debug - LIB OpenSSL + Win32 + + + LIB Debug - LIB OpenSSL + x64 + + + LIB Debug + Win32 + + + LIB Debug + x64 + + + LIB Release - DLL OpenSSL - DLL LibSSH2 + Win32 + + + LIB Release - DLL OpenSSL - DLL LibSSH2 + x64 + + + LIB Release - DLL OpenSSL + Win32 + + + LIB Release - DLL OpenSSL + x64 + + + LIB Release - DLL Windows SSPI - DLL WinIDN + Win32 + + + LIB Release - DLL Windows SSPI - DLL WinIDN + x64 + + + LIB Release - DLL Windows SSPI + Win32 + + + LIB Release - DLL Windows SSPI + x64 + + + LIB Release - LIB wolfSSL + Win32 + + + LIB Release - LIB wolfSSL + x64 + + + LIB Release - LIB OpenSSL - LIB LibSSH2 + Win32 + + + LIB Release - LIB OpenSSL - LIB LibSSH2 + x64 + + + LIB Release - LIB OpenSSL + Win32 + + + LIB Release - LIB OpenSSL + x64 + + + LIB Release + Win32 + + + LIB Release + x64 + + + + {5228E9CE-A216-422F-A5E6-58E95E2DD71D} + curl + + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win32\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + ..\..\..\..\build\Win64\VC14.20\$(Configuration)\ + $(OutDir)src\ + $(OutDir)src\ + false + false + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName)d + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + $(ProjectName) + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + true + $(TargetDir)$(TargetName).pdb + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + true + $(TargetDir)$(TargetName).pdb + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\wolfssl\build\Win32\VC14.20\LIB Release;%(AdditionalLibraryDirectories) + Console + MachineX86 + true + $(TargetDir)$(TargetName).pdb + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\wolfssl\build\Win64\VC14.20\LIB Release;%(AdditionalLibraryDirectories) + Console + MachineX64 + true + $(TargetDir)$(TargetName).pdb + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\wolfssl\build\Win32\VC14.20\LIB Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;wolfssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\wolfssl\build\Win64\VC14.20\LIB Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\LIB Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\LIB Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\LIB Release;%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\LIB Release;%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;libssh2d.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\LIB Debug;..\..\..\..\..\libssh2\build\Win32\VC14.20\LIB Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;libssh2d.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\LIB Debug;..\..\..\..\..\libssh2\build\Win64\VC14.20\LIB Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;libssh2.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\LIB Release;..\..\..\..\..\libssh2\build\Win32\VC14.20\LIB Release;%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;libssh2.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\LIB Release;..\..\..\..\..\libssh2\build\Win64\VC14.20\LIB Release;%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;libssh2d.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Debug;..\..\..\..\..\libssh2\build\Win32\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurld.lib;libcrypto.lib;libssl.lib;libssh2d.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Debug;..\..\..\..\..\libssh2\build\Win64\VC14.20\DLL Debug;%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libcrypto.lib;libssl.lib;libssh2.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win32\VC14.20\DLL Release;..\..\..\..\..\libssh2\build\Win32\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + crypt32.lib;ws2_32.lib;wldap32.lib;libcurl.lib;libssh2.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);..\..\..\..\..\openssl\build\Win64\VC14.20\DLL Release;..\..\..\..\..\libssh2\build\Win64\VC14.20\DLL Release;%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + Disabled + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + _DEBUG;_CONSOLE;DEBUGBUILD;CURL_STATICLIB;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;libcurld.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + true + $(TargetDir)$(TargetName).pdb + Console + MachineX64 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win32\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX86 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + + + X64 + $(TargetDir)$(TargetName).tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\..\include;..\..\..\..\lib;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Level4 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + ..\..\..\..\include;%(AdditionalIncludeDirectories) + + + ws2_32.lib;wldap32.lib;crypt32.lib;normaliz.lib;libcurl.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + ..\..\..\..\build\Win64\VC14.20\$(Configuration);%(AdditionalLibraryDirectories) + Console + MachineX64 + + + +CURL_SRC_X_C_FILES +CURL_SRC_C_FILES + + +CURL_SRC_X_H_FILES +CURL_SRC_H_FILES + + +CURL_SRC_RC_FILES + + + + + \ No newline at end of file diff --git a/projects/Windows/VC14.20/src/curl.vcxproj.filters b/projects/Windows/VC14.20/src/curl.vcxproj.filters new file mode 100644 index 000000000..4d6341d74 --- /dev/null +++ b/projects/Windows/VC14.20/src/curl.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + \ No newline at end of file diff --git a/projects/Windows/VC14.30/src/curl.sln b/projects/Windows/VC14.30/src/curl.sln index 16d22965f..ce5aa2c6f 100644 --- a/projects/Windows/VC14.30/src/curl.sln +++ b/projects/Windows/VC14.30/src/curl.sln @@ -1,5 +1,5 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 +# Visual Studio 17 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curl", "curl.vcxproj", "{5228E9CE-A216-422F-A5E6-58E95E2DD71D}" EndProject Global diff --git a/projects/generate.bat b/projects/generate.bat index 45dd9e5dc..83e638757 100644 --- a/projects/generate.bat +++ b/projects/generate.bat @@ -56,6 +56,8 @@ rem *************************************************************************** set VERSION=VC14 ) else if /i "%~1" == "vc14.10" ( set VERSION=VC14.10 + ) else if /i "%~1" == "vc14.20" ( + set VERSION=VC14.20 ) else if /i "%~1" == "vc14.30" ( set VERSION=VC14.30 ) else if /i "%~1" == "-clean" ( @@ -88,6 +90,7 @@ rem *************************************************************************** if "%VERSION%" == "VC12" goto vc12 if "%VERSION%" == "VC14" goto vc14 if "%VERSION%" == "VC14.10" goto vc14.10 + if "%VERSION%" == "VC14.20" goto vc14.20 if "%VERSION%" == "VC14.30" goto vc14.30 :vc10 @@ -165,6 +168,21 @@ rem *************************************************************************** if not "%VERSION%" == "ALL" goto success +:vc14.20 + echo. + + if "%MODE%" == "GENERATE" ( + echo Generating VC14.20 project files + call :generate vcxproj Windows\VC14.20\src\curl.tmpl Windows\VC14.20\src\curl.vcxproj + call :generate vcxproj Windows\VC14.20\lib\libcurl.tmpl Windows\VC14.20\lib\libcurl.vcxproj + ) else ( + echo Removing VC14.20 project files + call :clean Windows\VC14.20\src\curl.vcxproj + call :clean Windows\VC14.20\lib\libcurl.vcxproj + ) + + if not "%VERSION%" == "ALL" goto success + :vc14.30 echo. @@ -182,7 +200,7 @@ rem *************************************************************************** rem Main generate function. rem -rem %1 - Project Type (vcxproj for VC10, VC11, VC12, VC14, VC14.10 and VC14.30) +rem %1 - Project Type (vcxproj for VC10, VC11, VC12, VC14, VC14.10, VC14.20 and VC14.30) rem %2 - Input template file rem %3 - Output project file rem @@ -263,7 +281,7 @@ rem rem Generates a single file xml element. rem -rem %1 - Project Type (vcxproj for VC10, VC11, VC12, VC14, VC14.10 and VC14.30) +rem %1 - Project Type (vcxproj for VC10, VC11, VC12, VC14, VC14.10, VC14.20 and VC14.30) rem %2 - Directory (src, lib, lib\vauth, lib\vquic, lib\vssh, lib\vtls) rem %3 - Source filename rem %4 - Output project file @@ -359,6 +377,7 @@ rem echo vc12 - Use Visual Studio 2013 echo vc14 - Use Visual Studio 2015 echo vc14.10 - Use Visual Studio 2017 + echo vc14.20 - Use Visual Studio 2019 echo vc14.30 - Use Visual Studio 2022 echo. echo -clean - Removes the project files diff --git a/scripts/Makefile.am b/scripts/Makefile.am index fcb78eabf..9d69cff9c 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -23,7 +23,7 @@ ########################################################################### EXTRA_DIST = updatemanpages.pl coverage.sh completion.pl firefox-db2pem.sh \ - checksrc.pl mk-ca-bundle.pl + checksrc.pl mk-ca-bundle.pl schemetable.c ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@ FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@ diff --git a/scripts/checksrc.pl b/scripts/checksrc.pl index b85b56b43..76f466081 100644 --- a/scripts/checksrc.pl +++ b/scripts/checksrc.pl @@ -59,6 +59,7 @@ 'ASTERISKSPACE' => 'pointer declared with space after asterisk', 'BADCOMMAND' => 'bad !checksrc! instruction', 'BANNEDFUNC' => 'a banned function was used', + 'BANNEDPREPROC' => 'a banned symbol was used on a preprocessor line', 'BRACEELSE' => '} else on the same line', 'BRACEPOS' => 'wrong position for an open brace', 'BRACEWHILE' => 'A single space between open brace and while', @@ -402,6 +403,13 @@ sub scanfile { checksrc($cmd, $line, $file, $l) } + if($l =~ /^#line (\d+) \"([^\"]*)\"/) { + # a #line instruction + $file = $2; + $line = $1; + next; + } + # check for a copyright statement and save the years if($l =~ /\* +copyright .* (\d\d\d\d|)/i) { my $count = 0; @@ -892,6 +900,18 @@ sub scanfile { "multiple spaces"); } preproc: + if($prep) { + # scan for use of banned symbols on a preprocessor line + if($l =~ /^(^|.*\W) + (WIN32) + (\W|$) + /x) { + checkwarn("BANNEDPREPROC", + $line, length($1), $file, $ol, + "use of $2 is banned from preprocessor lines" . + (($2 eq "WIN32") ? ", use _WIN32 instead" : "")); + } + } $line++; $prevp = $prep; $prevl = $ol if(!$prep); diff --git a/scripts/cmp-config.pl b/scripts/cmp-config.pl index b1717cded..e36fcdd3c 100755 --- a/scripts/cmp-config.pl +++ b/scripts/cmp-config.pl @@ -43,6 +43,7 @@ '#define HAVE_DECL_GETPWUID_R 1' => 1, '#define HAVE_DLFCN_H 1' => 1, '#define HAVE_GETHOSTBYNAME 1' => 1, + '#define HAVE_INTTYPES_H 1' => 1, '#define HAVE_IOCTL 1' => 1, '#define HAVE_LDAP_SSL 1' => 1, '#define HAVE_LIBBROTLIDEC 1' => 1, @@ -57,6 +58,7 @@ '#define HAVE_OPENSSL_X509_H 1' => 1, '#define HAVE_SA_FAMILY_T 1' => 1, '#define HAVE_SETJMP_H 1' => 1, + '#define HAVE_STDINT_H 1' => 1, '#define HAVE_STDIO_H 1' => 1, '#define HAVE_STDLIB_H 1' => 1, '#define HAVE_STRING_H 1' => 1, diff --git a/scripts/schemetable.c b/scripts/schemetable.c new file mode 100644 index 000000000..ae79eaa09 --- /dev/null +++ b/scripts/schemetable.c @@ -0,0 +1,207 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 + +/* + * Use this tool to generate an updated table for the Curl_getn_scheme_handler + * function in url.c. + */ + +struct detail { + const char *n; + const char *ifdef; +}; + +static const struct detail scheme[] = { + {"dict", "#ifndef CURL_DISABLE_DICT" }, + {"file", "#ifndef CURL_DISABLE_FILE" }, + {"ftp", "#ifndef CURL_DISABLE_FTP" }, + {"ftps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)" }, + {"gopher", "#ifndef CURL_DISABLE_GOPHER" }, + {"gophers", "#if defined(USE_SSL) && !defined(CURL_DISABLE_GOPHER)" }, + {"http", "#ifndef CURL_DISABLE_HTTP" }, + {"https", "#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)" }, + {"imap", "#ifndef CURL_DISABLE_IMAP" }, + {"imaps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)" }, + {"ldap", "#ifndef CURL_DISABLE_LDAP" }, + {"ldaps", "#if !defined(CURL_DISABLE_LDAP) && \\\n" + " !defined(CURL_DISABLE_LDAPS) && \\\n" + " ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \\\n" + " (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))" }, + {"mqtt", "#ifndef CURL_DISABLE_MQTT" }, + {"pop3", "#ifndef CURL_DISABLE_POP3" }, + {"pop3s", "#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)" }, + {"rtmp", "#ifdef USE_LIBRTMP" }, + {"rtmpt", "#ifdef USE_LIBRTMP" }, + {"rtmpe", "#ifdef USE_LIBRTMP" }, + {"rtmpte", "#ifdef USE_LIBRTMP" }, + {"rtmps", "#ifdef USE_LIBRTMP" }, + {"rtmpts", "#ifdef USE_LIBRTMP" }, + {"rtsp", "#ifndef CURL_DISABLE_RTSP" }, + {"scp", "#if defined(USE_SSH) && !defined(USE_WOLFSSH)" }, + {"sftp", "#if defined(USE_SSH)" }, + {"smb", "#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \\\n" + " (SIZEOF_CURL_OFF_T > 4)" }, + {"smbs", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMB) && \\\n" + " defined(USE_CURL_NTLM_CORE) && (SIZEOF_CURL_OFF_T > 4)" }, + {"smtp", "#ifndef CURL_DISABLE_SMTP" }, + {"smtps", "#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)" }, + {"telnet", "#ifndef CURL_DISABLE_TELNET" }, + {"tftp", "#ifndef CURL_DISABLE_TFTP" }, + {"ws", "#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)" }, + {"wss", "#if defined(USE_WEBSOCKETS) && \\\n" + " defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)" }, + { NULL, NULL } +}; + +unsigned int calc(const char *s, int add, int shift) +{ + const char *so = s; + unsigned int c = add; + while(*s) { + c <<= shift; + c += *s; + s++; + } + return c; +} + +unsigned int num[100]; +unsigned int ix[100]; + +static void showtable(int try, int init, int shift) +{ + int nulls = 0; + int i; + for(i = 0; scheme[i].n; ++i) + num[i] = calc(scheme[i].n, init, shift); + for(i = 0; scheme[i].n; ++i) + ix[i] = num[i] % try; + printf("/*\n" + " unsigned int c = %d\n" + " while(l) {\n" + " c <<= %d;\n" + " c += Curl_raw_tolower(*s);\n" + " s++;\n" + " l--;\n" + " }\n" + "*/\n", init, shift); + + printf(" static const struct Curl_handler * const protocols[%d] = {", try); + + /* generate table */ + for(i=0; i < try; i++) { + int match = 0; + int j; + for(j=0; scheme[j].n; j++) { + if(ix[j] == i) { + printf("\n"); + printf("%s\n", scheme[j].ifdef); + printf(" &Curl_handler_%s,\n", scheme[j].n); + printf("#else\n NULL,\n"); + printf("#endif"); + match = 1; + nulls = 0; + break; + } + } + if(!match) { + if(!nulls || (nulls>10)) { + printf("\n "); + nulls = 0; + } + printf(" NULL,", nulls); + nulls++; + } + } + printf("\n };\n"); +} + +int main(void) +{ + int i; + int try; + int besttry = 9999; + int bestadd = 0; + int bestshift = 0; + int add; + int shift; + for(shift = 0; shift < 8; shift++) { + for(add = 0; add < 999; add++) { + for(i = 0; scheme[i].n; ++i) { + unsigned int v = calc(scheme[i].n, add, shift); + int j; + int badcombo = 0; + for(j=0; j < i; j++) { + + if(num[j] == v) { + /* + printf("NOPE: %u is a dupe (%s and %s)\n", + v, scheme[i], scheme[j]); + */ + badcombo = 1; + break; + } + } + if(badcombo) + break; + num[i] = v; + } +#if 0 + for(i = 0; scheme[i].n; ++i) { + printf("%u - %s\n", num[i], scheme[i].n); + } +#endif + /* try different remainders to find smallest possible table */ + for(try = 28; try < 199; try++) { + int good = 1; + for(i = 0; scheme[i].n; ++i) { + ix[i] = num[i] % try; + } + /* check for dupes */ + for(i = 0; scheme[i].n && good; ++i) { + int j; + for(j=0; j < i; j++) { + if(ix[j] == ix[i]) { + /* printf("NOPE, try %u causes dupes (%d and %d)\n", try, j, i); */ + good = 0; + break; + } + } + } + if(good) { + if(try < besttry) { + besttry = try; + bestadd = add; + bestshift = shift; + } + break; + } + } + } + } + + showtable(besttry, bestadd, bestshift); +} diff --git a/src/Makefile.am b/src/Makefile.am index ddeb70073..dced53e0f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,6 +61,8 @@ curl_SOURCES += $(CURL_RCFILES) $(CURL_RCFILES): tool_version.h endif +curl_LDFLAGS = $(AM_LDFLAGS) $(CURL_LDFLAGS_BIN) + # This might hold -Werror CFLAGS += @CURL_CFLAG_EXTRAS@ @@ -89,7 +91,7 @@ CLEANFILES = tool_hugehelp.c NROFF=env LC_ALL=C @NROFF@ @MANOPT@ 2>/dev/null # figured out by the configure script EXTRA_DIST = mkhelp.pl \ - Makefile.mk curl.rc Makefile.inc CMakeLists.txt + Makefile.mk curl.rc Makefile.inc CMakeLists.txt .checksrc # Use absolute directory to disable VPATH MANPAGE=$(abs_top_builddir)/docs/curl.1 diff --git a/src/Makefile.inc b/src/Makefile.inc index 253893536..c1d202a06 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -79,6 +79,7 @@ CURL_CFILES = \ tool_help.c \ tool_helpers.c \ tool_hugehelp.c \ + tool_ipfs.c \ tool_libinfo.c \ tool_listhelp.c \ tool_main.c \ @@ -122,6 +123,7 @@ CURL_HFILES = \ tool_help.h \ tool_helpers.h \ tool_hugehelp.h \ + tool_ipfs.h \ tool_libinfo.h \ tool_main.h \ tool_msgs.h \ diff --git a/src/curl.rc b/src/curl.rc index 11d528429..6fcaf353e 100644 --- a/src/curl.rc +++ b/src/curl.rc @@ -53,7 +53,7 @@ BEGIN VALUE "OriginalFilename", "curl.exe\0" VALUE "ProductName", "The curl executable\0" VALUE "ProductVersion", CURL_VERSION "\0" - VALUE "LegalCopyright", "\xa9 " CURL_COPYRIGHT "\0" /* a9: Copyright symbol */ + VALUE "LegalCopyright", "Copyright (C) " CURL_COPYRIGHT "\0" VALUE "License", "https://curl.se/docs/copyright.html\0" END END diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index df44f7aa7..198a8d050 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -41,9 +41,9 @@ static char *parse_filename(const char *ptr, size_t len); -#ifdef WIN32 -#define BOLD -#define BOLDOFF +#ifdef _WIN32 +#define BOLD "\x1b[1m" +#define BOLDOFF "\x1b[22m" #else #define BOLD "\x1b[1m" /* Switch off bold by setting "all attributes off" since the explicit @@ -87,7 +87,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) } #endif -#ifdef WIN32 +#ifdef _WIN32 /* Discard incomplete UTF-8 sequence buffered from body */ if(outs->utf8seq[0]) memset(outs->utf8seq, 0, sizeof(outs->utf8seq)); @@ -150,16 +150,19 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) char *filename; size_t len; - while(*p && (p < end) && !ISALPHA(*p)) + while((p < end) && *p && !ISALPHA(*p)) p++; if(p > end - 9) break; if(memcmp(p, "filename=", 9)) { /* no match, find next parameter */ - while((p < end) && (*p != ';')) + while((p < end) && *p && (*p != ';')) p++; - continue; + if((p < end) && *p) + continue; + else + break; } p += 9; @@ -209,7 +212,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 && hdrcbdata->global->styled_output) + if(hdrcbdata->global->isatty && +#ifdef _WIN32 + tool_term_has_bold && +#endif + hdrcbdata->global->styled_output) value = memchr(ptr, ':', cb); if(value) { size_t namelen = value - ptr; @@ -297,7 +304,7 @@ static char *parse_filename(const char *ptr, size_t len) if(copy != p) memmove(copy, p, strlen(p) + 1); -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) { char *sanitized; SANITIZEcode sc = sanitize_file_name(&sanitized, copy, 0); @@ -306,7 +313,7 @@ static char *parse_filename(const char *ptr, size_t len) return NULL; copy = sanitized; } -#endif /* MSDOS || WIN32 */ +#endif /* _WIN32 || MSDOS */ /* in case we built debug enabled, we allow an environment variable * named CURL_TESTDIR to prefix the given file name to put it into a diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 47ec3ef39..ef47b42da 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -38,6 +38,8 @@ #include "memdebug.h" /* keep this as LAST include */ +#define MAX_BARLENGTH 256 + #ifdef HAVE_TERMIOS_H # include #elif defined(HAVE_TERMIO_H) @@ -78,11 +80,16 @@ static const unsigned int sinus[] = { static void fly(struct ProgressData *bar, bool moved) { - char buf[256]; + char buf[MAX_BARLENGTH + 2]; int pos; int check = bar->width - 2; - msnprintf(buf, sizeof(buf), "%*s\r", bar->width-1, " "); + /* bar->width is range checked when assigned */ + DEBUGASSERT(bar->width <= MAX_BARLENGTH); + memset(buf, ' ', bar->width); + buf[bar->width] = '\r'; + buf[bar->width + 1] = '\0'; + memcpy(&buf[bar->bar], "-=O=-", 5); pos = sinus[bar->tick%200] / (1000000 / check); @@ -114,8 +121,6 @@ static void fly(struct ProgressData *bar, bool moved) ** callback for CURLOPT_XFERINFOFUNCTION */ -#define MAX_BARLENGTH 256 - #if (SIZEOF_CURL_OFF_T < 8) #error "too small curl_off_t" #else @@ -249,7 +254,7 @@ void progressbarinit(struct ProgressData *bar, struct winsize ts; if(!ioctl(STDIN_FILENO, TIOCGWINSZ, &ts)) cols = ts.ws_col; -#elif defined(WIN32) +#elif defined(_WIN32) { HANDLE stderr_hnd = GetStdHandle(STD_ERROR_HANDLE); CONSOLE_SCREEN_BUFFER_INFO console_info; diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c index d70a9b909..8cb5bbe8a 100644 --- a/src/tool_cb_rea.c +++ b/src/tool_cb_rea.c @@ -62,7 +62,7 @@ size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) if(msdelta > config->timeout_ms) /* timeout */ return 0; -#ifndef WIN32 +#ifndef _WIN32 /* this logic waits on read activity on a file descriptor that is not a socket which makes it not work with select() on Windows */ else { diff --git a/src/tool_cb_see.c b/src/tool_cb_see.c index 8351473c8..bce57bb28 100644 --- a/src/tool_cb_see.c +++ b/src/tool_cb_see.c @@ -93,21 +93,6 @@ int tool_seek_cb(void *userdata, curl_off_t offset, int whence) #ifdef USE_TOOL_FTRUNCATE -#ifdef __BORLANDC__ -/* 64-bit lseek-like function unavailable */ -# define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence) -#endif - -#ifdef __POCC__ -# if(__POCC__ < 450) -/* 64-bit lseek-like function unavailable */ -# define _lseeki64(hnd,ofs,whence) _lseek(hnd,ofs,whence) -# else -# undef _lseeki64 -# define _lseeki64(hnd,ofs,whence) _lseek64(hnd,ofs,whence) -# endif -#endif - #ifdef _WIN32_WCE /* 64-bit lseek-like function unavailable */ # undef _lseeki64 diff --git a/src/tool_cb_see.h b/src/tool_cb_see.h index 14bbc4264..b5d7bf985 100644 --- a/src/tool_cb_see.h +++ b/src/tool_cb_see.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -#if defined(WIN32) && !defined(HAVE_FTRUNCATE) +#if defined(_WIN32) && !defined(HAVE_FTRUNCATE) int tool_ftruncate64(int fd, curl_off_t where); @@ -35,7 +35,7 @@ int tool_ftruncate64(int fd, curl_off_t where); #define HAVE_FTRUNCATE 1 #define USE_TOOL_FTRUNCATE 1 -#endif /* WIN32 && ! HAVE_FTRUNCATE */ +#endif /* _WIN32 && ! HAVE_FTRUNCATE */ /* ** callback for CURLOPT_SEEKFUNCTION diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index b7838664e..98063c39c 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -44,7 +44,7 @@ #ifndef O_BINARY #define O_BINARY 0 #endif -#ifdef WIN32 +#ifdef _WIN32 #define OPENMODE S_IREAD | S_IWRITE #else #define OPENMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH @@ -159,7 +159,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) struct OperationConfig *config = per->config; size_t bytes = sz * nmemb; bool is_tty = config->global->isatty; -#ifdef WIN32 +#ifdef _WIN32 CONSOLE_SCREEN_BUFFER_INFO console_info; intptr_t fhnd; #endif @@ -231,13 +231,13 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) } } -#ifdef WIN32 +#ifdef _WIN32 fhnd = _get_osfhandle(fileno(outs->stream)); /* 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; + DWORD wc_len, chars_written; unsigned char *rbuf = (unsigned char *)buffer; DWORD rlen = (DWORD)bytes; @@ -292,7 +292,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) (HANDLE) fhnd, prefix, prefix[1] ? 2 : 1, - NULL, + &chars_written, NULL)) { return CURL_WRITEFUNC_ERROR; } @@ -351,7 +351,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) (HANDLE) fhnd, wc_buf, wc_len, - NULL, + &chars_written, NULL)) { free(wc_buf); return CURL_WRITEFUNC_ERROR; diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c index 16765c3a5..1cadbd0be 100644 --- a/src/tool_dirhie.c +++ b/src/tool_dirhie.c @@ -25,7 +25,7 @@ #include -#ifdef WIN32 +#ifdef _WIN32 # include #endif @@ -38,7 +38,7 @@ #include "memdebug.h" /* keep this as LAST include */ -#if defined(WIN32) || (defined(MSDOS) && !defined(__DJGPP__)) +#if defined(_WIN32) || (defined(MSDOS) && !defined(__DJGPP__)) # define mkdir(x,y) (mkdir)((x)) # ifndef F_OK # define F_OK 0 @@ -88,7 +88,7 @@ static void show_dir_errno(struct GlobalConfig *global, const char *name) * should create all the dir* automagically */ -#if defined(WIN32) || defined(__DJGPP__) +#if defined(_WIN32) || defined(__DJGPP__) /* systems that may use either or when specifying a path */ #define PATH_DELIMITERS "\\/" #else @@ -132,7 +132,7 @@ CURLcode create_dir_hierarchy(const char *outfile, struct GlobalConfig *global) msnprintf(&dirbuildup[dlen], outlen - dlen, "%s%s", DIR_CHAR, tempdir); else { if(outdup == tempdir) { -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) /* Skip creating a drive's current directory. It may seem as though that would harmlessly fail but it could be a corner case if X: did not exist, since we would be creating it diff --git a/src/tool_doswin.c b/src/tool_doswin.c index faa5755e6..db2b8b78a 100644 --- a/src/tool_doswin.c +++ b/src/tool_doswin.c @@ -23,13 +23,13 @@ ***************************************************************************/ #include "tool_setup.h" -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) # include #endif -#ifdef WIN32 +#ifdef _WIN32 # include # include # include "tool_cfgable.h" @@ -42,7 +42,7 @@ #include "curlx.h" #include "memdebug.h" /* keep this as LAST include */ -#ifdef WIN32 +#ifdef _WIN32 # undef PATH_MAX # define PATH_MAX MAX_PATH #endif @@ -55,7 +55,7 @@ # endif #endif -#ifdef WIN32 +#ifdef _WIN32 # define _use_lfn(f) (1) /* long file names always available */ #elif !defined(__DJGPP__) || (__DJGPP__ < 2) /* DJGPP 2.0 has _use_lfn() */ # define _use_lfn(f) (0) /* long file names never available */ @@ -597,7 +597,7 @@ char **__crt0_glob_function(char *arg) #endif /* MSDOS && (__DJGPP__ || __GO32__) */ -#ifdef WIN32 +#ifdef _WIN32 /* * Function to find CACert bundle on a Win32 platform using SearchPath. @@ -714,6 +714,8 @@ static struct TerminalSettings { #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif +bool tool_term_has_bold; + static void restore_terminal(void) { if(InterlockedExchange(&TerminalSettings.valid, (LONG)FALSE)) @@ -733,16 +735,23 @@ static BOOL WINAPI signal_handler(DWORD type) static void init_terminal(void) { TerminalSettings.hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + /* * Enable VT (Virtual Terminal) output. * Note: VT mode flag can be set on any version of Windows, but VT - * processing only performed on Win10 >= Creators Update) + * processing only performed on Win10 >= version 1709 (OS build 16299) + * Creator's Update. Also, ANSI bold on/off supported since then. */ - if((TerminalSettings.hStdOut != INVALID_HANDLE_VALUE) && - GetConsoleMode(TerminalSettings.hStdOut, - &TerminalSettings.dwOutputMode) && - !(TerminalSettings.dwOutputMode & - ENABLE_VIRTUAL_TERMINAL_PROCESSING)) { + if(TerminalSettings.hStdOut == INVALID_HANDLE_VALUE || + !GetConsoleMode(TerminalSettings.hStdOut, + &TerminalSettings.dwOutputMode) || + !curlx_verify_windows_version(10, 0, 16299, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) + return; + + if((TerminalSettings.dwOutputMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)) + tool_term_has_bold = true; + else { /* The signal handler is set before attempting to change the console mode because otherwise a signal would not be caught after the change but before the handler was installed. */ @@ -751,6 +760,7 @@ static void init_terminal(void) if(SetConsoleMode(TerminalSettings.hStdOut, (TerminalSettings.dwOutputMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))) { + tool_term_has_bold = true; atexit(restore_terminal); } else { @@ -781,6 +791,6 @@ CURLcode win32_init(void) return CURLE_OK; } -#endif /* WIN32 */ +#endif /* _WIN32 */ -#endif /* MSDOS || WIN32 */ +#endif /* _WIN32 || MSDOS */ diff --git a/src/tool_doswin.h b/src/tool_doswin.h index 669fdb6ed..e07d89d95 100644 --- a/src/tool_doswin.h +++ b/src/tool_doswin.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) #define SANITIZE_ALLOW_COLONS (1<<0) /* Allow colons */ #define SANITIZE_ALLOW_PATH (1<<1) /* Allow path separators and colons */ @@ -57,7 +57,7 @@ char **__crt0_glob_function(char *arg); #endif /* MSDOS && (__DJGPP__ || __GO32__) */ -#ifdef WIN32 +#ifdef _WIN32 CURLcode FindWin32CACert(struct OperationConfig *config, curl_sslbackend backend, @@ -65,8 +65,8 @@ CURLcode FindWin32CACert(struct OperationConfig *config, struct curl_slist *GetLoadedModulePaths(void); CURLcode win32_init(void); -#endif /* WIN32 */ +#endif /* _WIN32 */ -#endif /* MSDOS || WIN32 */ +#endif /* _WIN32 || MSDOS */ #endif /* HEADER_CURL_TOOL_DOSWIN_H */ diff --git a/src/tool_filetime.c b/src/tool_filetime.c index 9c2e80429..13113886e 100644 --- a/src/tool_filetime.c +++ b/src/tool_filetime.c @@ -41,7 +41,7 @@ int getfiletime(const char *filename, struct GlobalConfig *global, /* Windows stat() may attempt to adjust the unix GMT file time by a daylight saving time offset and since it's GMT that is bad behavior. When we have access to a 64-bit type we can bypass stat and get the times directly. */ -#if defined(WIN32) +#if defined(_WIN32) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); @@ -87,7 +87,7 @@ int getfiletime(const char *filename, struct GlobalConfig *global, return rc; } -#if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || defined(WIN32) +#if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || defined(_WIN32) void setfiletime(curl_off_t filetime, const char *filename, struct GlobalConfig *global) { @@ -95,7 +95,7 @@ void setfiletime(curl_off_t filetime, const char *filename, /* Windows utime() may attempt to adjust the unix GMT file time by a daylight saving time offset and since it's GMT that is bad behavior. When we have access to a 64-bit type we can bypass utime and set the times directly. */ -#if defined(WIN32) +#if defined(_WIN32) HANDLE hfile; TCHAR *tchar_filename = curlx_convert_UTF8_to_tchar((char *)filename); @@ -153,4 +153,4 @@ void setfiletime(curl_off_t filetime, const char *filename, } } #endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ - defined(WIN32) */ + defined(_WIN32) */ diff --git a/src/tool_filetime.h b/src/tool_filetime.h index 908b2d72b..205e5cee2 100644 --- a/src/tool_filetime.h +++ b/src/tool_filetime.h @@ -31,12 +31,12 @@ int getfiletime(const char *filename, struct GlobalConfig *global, curl_off_t *stamp); #if defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ - (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) + (defined(_WIN32) && (SIZEOF_CURL_OFF_T >= 8)) void setfiletime(curl_off_t filetime, const char *filename, struct GlobalConfig *global); #else #define setfiletime(a,b,c) Curl_nop_stmt #endif /* defined(HAVE_UTIME) || defined(HAVE_UTIMES) || \ - (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */ + (defined(_WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */ #endif /* HEADER_CURL_TOOL_FILETIME_H */ diff --git a/src/tool_findfile.c b/src/tool_findfile.c index 201d8f0a8..a1544a563 100644 --- a/src/tool_findfile.c +++ b/src/tool_findfile.c @@ -53,7 +53,7 @@ static const struct finder conf_list[] = { { "CURL_HOME", NULL, FALSE }, { "XDG_CONFIG_HOME", NULL, FALSE }, /* index == 1, used in the code */ { "HOME", NULL, FALSE }, -#ifdef WIN32 +#ifdef _WIN32 { "USERPROFILE", NULL, FALSE }, { "APPDATA", NULL, FALSE }, { "USERPROFILE", "\\Application Data", FALSE}, diff --git a/src/tool_findfile.h b/src/tool_findfile.h index faafd71cb..63d25195f 100644 --- a/src/tool_findfile.h +++ b/src/tool_findfile.h @@ -25,7 +25,7 @@ ***************************************************************************/ #include "tool_setup.h" -#ifdef WIN32 +#ifdef _WIN32 #define CURLRC_DOTSCORE 2 /* look for underscore-prefixed name too */ #else #define CURLRC_DOTSCORE 1 /* regular .curlrc check */ diff --git a/src/tool_getparam.c b/src/tool_getparam.c index d9772a309..5fa1ace10 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -437,7 +437,7 @@ void parse_cert_parameter(const char *cert_parameter, needs to work. In order not to break compatibility, we still use : as separator, but we try to detect when it is used for a file name! On windows. */ -#ifdef WIN32 +#ifdef _WIN32 if((param_place == &cert_parameter[1]) && (cert_parameter[2] == '\\' || cert_parameter[2] == '/') && (ISALPHA(cert_parameter[0])) ) { @@ -1043,6 +1043,12 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ break; } } + + if(denominator > numerator) { + err = PARAM_NUMBER_TOO_LARGE; + break; + } + global->ms_per_transfer = numerator/denominator; } break; diff --git a/src/tool_getpass.c b/src/tool_getpass.c index f5aa98c6a..8ccccdfb8 100644 --- a/src/tool_getpass.c +++ b/src/tool_getpass.c @@ -46,7 +46,7 @@ # include iodef #endif -#ifdef WIN32 +#ifdef _WIN32 # include #endif @@ -94,7 +94,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen) #define DONE #endif /* __VMS */ -#if defined(WIN32) +#if defined(_WIN32) char *getpass_r(const char *prompt, char *buffer, size_t buflen) { @@ -122,7 +122,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen) return buffer; /* we always return success */ } #define DONE -#endif /* WIN32 */ +#endif /* _WIN32 */ #ifndef DONE /* not previously provided */ diff --git a/src/tool_help.c b/src/tool_help.c index 8983a4ca0..c8aea295d 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -73,8 +73,6 @@ static const struct category_descriptors categories[] = { {NULL, NULL, CURLHELP_HIDDEN} }; -extern const struct helptxt helptext[]; - static void print_category(curlhelp_t category) { diff --git a/src/tool_ipfs.c b/src/tool_ipfs.c new file mode 100644 index 000000000..435d1697c --- /dev/null +++ b/src/tool_ipfs.c @@ -0,0 +1,296 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "tool_setup.h" + +#define ENABLE_CURLX_PRINTF +/* use our own printf() functions */ +#include "curlx.h" +#include "dynbuf.h" + +#include "tool_cfgable.h" +#include "tool_msgs.h" +#include "tool_ipfs.h" + +#include "memdebug.h" /* keep this as LAST include */ + +/* ensure input ends in slash */ +static CURLcode ensure_trailing_slash(char **input) +{ + if(*input && **input) { + size_t len = strlen(*input); + if(((*input)[len - 1] != '/')) { + struct curlx_dynbuf dyn; + curlx_dyn_init(&dyn, len + 2); + + if(curlx_dyn_addn(&dyn, *input, len)) { + Curl_safefree(*input); + return CURLE_OUT_OF_MEMORY; + } + + Curl_safefree(*input); + + if(curlx_dyn_addn(&dyn, "/", 1)) + return CURLE_OUT_OF_MEMORY; + + *input = curlx_dyn_ptr(&dyn); + } + } + + return CURLE_OK; +} + +static char *ipfs_gateway(void) +{ + char *ipfs_path = NULL; + char *gateway_composed_file_path = NULL; + FILE *gateway_file = NULL; + char *gateway = curlx_getenv("IPFS_GATEWAY"); + + /* Gateway is found from environment variable. */ + if(gateway) { + if(ensure_trailing_slash(&gateway)) + goto fail; + return gateway; + } + + /* Try to find the gateway in the IPFS data folder. */ + ipfs_path = curlx_getenv("IPFS_PATH"); + + if(!ipfs_path) { + char *home = curlx_getenv("HOME"); + if(home && *home) + ipfs_path = aprintf("%s/.ipfs/", home); + /* fallback to "~/.ipfs", as that's the default location. */ + + Curl_safefree(home); + } + + if(!ipfs_path || ensure_trailing_slash(&ipfs_path)) + goto fail; + + gateway_composed_file_path = aprintf("%sgateway", ipfs_path); + + if(!gateway_composed_file_path) + goto fail; + + gateway_file = fopen(gateway_composed_file_path, FOPEN_READTEXT); + Curl_safefree(gateway_composed_file_path); + + if(gateway_file) { + int c; + struct curlx_dynbuf dyn; + curlx_dyn_init(&dyn, MAX_GATEWAY_URL_LEN); + + /* get the first line of the gateway file, ignore the rest */ + while((c = getc(gateway_file)) != EOF && c != '\n' && c != '\r') { + char c_char = (char)c; + if(curlx_dyn_addn(&dyn, &c_char, 1)) + goto fail; + } + + fclose(gateway_file); + gateway_file = NULL; + + if(curlx_dyn_len(&dyn)) + gateway = curlx_dyn_ptr(&dyn); + + if(gateway) + ensure_trailing_slash(&gateway); + + if(!gateway) + goto fail; + + Curl_safefree(ipfs_path); + + return gateway; + } +fail: + if(gateway_file) + fclose(gateway_file); + Curl_safefree(gateway); + Curl_safefree(ipfs_path); + return NULL; +} + +/* + * Rewrite ipfs:// and ipns:// to a HTTP(S) + * URL that can be handled by an IPFS gateway. + */ +CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url, + struct OperationConfig *config) +{ + CURLcode result = CURLE_URL_MALFORMAT; + CURLUcode getResult; + char *gateway = NULL; + char *gwhost = NULL; + char *gwpath = NULL; + char *gwquery = NULL; + char *gwscheme = NULL; + char *gwport = NULL; + char *inputpath = NULL; + char *cid = NULL; + char *pathbuffer = NULL; + char *cloneurl; + CURLU *gatewayurl = curl_url(); + + if(!gatewayurl) { + result = CURLE_FAILED_INIT; + goto clean; + } + + getResult = curl_url_get(uh, CURLUPART_HOST, &cid, CURLU_URLDECODE); + if(getResult || !cid) + goto clean; + + /* We might have a --ipfs-gateway argument. Check it first and use it. Error + * if we do have something but if it's an invalid url. + */ + if(config->ipfs_gateway) { + /* ensure the gateway ends in a trailing / */ + if(ensure_trailing_slash(&config->ipfs_gateway) != CURLE_OK) { + result = CURLE_OUT_OF_MEMORY; + goto clean; + } + + if(!curl_url_set(gatewayurl, CURLUPART_URL, config->ipfs_gateway, + CURLU_GUESS_SCHEME)) { + gateway = strdup(config->ipfs_gateway); + if(!gateway) { + result = CURLE_URL_MALFORMAT; + goto clean; + } + + } + else { + result = CURLE_BAD_FUNCTION_ARGUMENT; + goto clean; + } + } + else { + /* this is ensured to end in a trailing / within ipfs_gateway() */ + gateway = ipfs_gateway(); + if(!gateway) { + result = CURLE_FILE_COULDNT_READ_FILE; + goto clean; + } + + if(curl_url_set(gatewayurl, CURLUPART_URL, gateway, 0)) { + result = CURLE_URL_MALFORMAT; + goto clean; + } + } + + /* check for unsupported gateway parts */ + if(curl_url_get(gatewayurl, CURLUPART_QUERY, &gwquery, 0) + != CURLUE_NO_QUERY) { + result = CURLE_URL_MALFORMAT; + goto clean; + } + + /* get gateway parts */ + if(curl_url_get(gatewayurl, CURLUPART_HOST, + &gwhost, CURLU_URLDECODE)) { + goto clean; + } + + if(curl_url_get(gatewayurl, CURLUPART_SCHEME, + &gwscheme, CURLU_URLDECODE)) { + goto clean; + } + + curl_url_get(gatewayurl, CURLUPART_PORT, &gwport, CURLU_URLDECODE); + curl_url_get(gatewayurl, CURLUPART_PATH, &gwpath, CURLU_URLDECODE); + + /* get the path from user input */ + curl_url_get(uh, CURLUPART_PATH, &inputpath, CURLU_URLDECODE); + /* inputpath might be NULL or a valid pointer now */ + + /* set gateway parts in input url */ + if(curl_url_set(uh, CURLUPART_SCHEME, gwscheme, CURLU_URLENCODE) || + curl_url_set(uh, CURLUPART_HOST, gwhost, CURLU_URLENCODE) || + curl_url_set(uh, CURLUPART_PORT, gwport, CURLU_URLENCODE)) + goto clean; + + /* if the input path is just a slash, clear it */ + if(inputpath && (inputpath[0] == '/') && !inputpath[1]) + *inputpath = '\0'; + + /* ensure the gateway path ends with a trailing slash */ + ensure_trailing_slash(&gwpath); + + pathbuffer = aprintf("%s%s/%s%s", gwpath, protocol, cid, + inputpath ? inputpath : ""); + if(!pathbuffer) { + goto clean; + } + + if(curl_url_set(uh, CURLUPART_PATH, pathbuffer, CURLU_URLENCODE)) { + goto clean; + } + + /* Free whatever it has now, rewriting is next */ + Curl_safefree(*url); + + if(curl_url_get(uh, CURLUPART_URL, &cloneurl, CURLU_URLENCODE)) { + goto clean; + } + /* we need to strdup the URL so that we can call free() on it later */ + *url = strdup(cloneurl); + curl_free(cloneurl); + if(!*url) + goto clean; + + result = CURLE_OK; + +clean: + free(gateway); + curl_free(gwhost); + curl_free(gwpath); + curl_free(gwquery); + curl_free(inputpath); + curl_free(gwscheme); + curl_free(gwport); + curl_free(cid); + curl_free(pathbuffer); + curl_url_cleanup(gatewayurl); + { + const char *msg = NULL; + switch(result) { + case CURLE_URL_MALFORMAT: + msg = "malformed target URL"; + break; + case CURLE_FILE_COULDNT_READ_FILE: + msg = "IPFS automatic gateway detection failed"; + break; + case CURLE_BAD_FUNCTION_ARGUMENT: + msg = "--ipfs-gateway was given a malformed URL"; + break; + default: + break; + } + if(msg) + helpf(tool_stderr, msg); + } + return result; +} diff --git a/tests/libtest/sethostname.h b/src/tool_ipfs.h similarity index 70% rename from tests/libtest/sethostname.h rename to src/tool_ipfs.h index 1ffcba110..9c8a83e3b 100644 --- a/tests/libtest/sethostname.h +++ b/src/tool_ipfs.h @@ -1,3 +1,5 @@ +#ifndef HEADER_CURL_TOOL_IPFS_H +#define HEADER_CURL_TOOL_IPFS_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -21,22 +23,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ +#include "tool_setup.h" -#ifdef CURL_STATICLIB -# define LIBHOSTNAME_EXTERN -#elif defined(WIN32) -# define LIBHOSTNAME_EXTERN __declspec(dllexport) -#elif defined(CURL_HIDDEN_SYMBOLS) -# define LIBHOSTNAME_EXTERN CURL_EXTERN_SYMBOL -#else -# define LIBHOSTNAME_EXTERN -#endif +#define MAX_GATEWAY_URL_LEN 10000 -#ifdef USE_WINSOCK -# define FUNCALLCONV __stdcall -#else -# define FUNCALLCONV -#endif +CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url, + struct OperationConfig *config); -LIBHOSTNAME_EXTERN int FUNCALLCONV - gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen); +#endif /* HEADER_CURL_TOOL_IPFS_H */ diff --git a/src/tool_main.c b/src/tool_main.c index 2f132e2d2..446806ecb 100644 --- a/src/tool_main.c +++ b/src/tool_main.c @@ -25,7 +25,7 @@ #include -#ifdef WIN32 +#ifdef _WIN32 #include #endif @@ -220,6 +220,7 @@ static void main_free(struct GlobalConfig *config) #ifdef _UNICODE #if defined(__GNUC__) /* GCC doesn't know about wmain() */ +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-prototypes" #pragma GCC diagnostic ignored "-Wmissing-declarations" #endif @@ -234,7 +235,7 @@ int main(int argc, char *argv[]) tool_init_stderr(); -#ifdef WIN32 +#ifdef _WIN32 /* Undocumented diagnostic option to list the full paths of all loaded modules. This is purposely pre-init. */ if(argc == 2 && !_tcscmp(argv[1], _T("--dump-module-paths"))) { @@ -275,7 +276,7 @@ int main(int argc, char *argv[]) main_free(&global); } -#ifdef WIN32 +#ifdef _WIN32 /* Flush buffers of all streams opened in write or update mode */ fflush(NULL); #endif @@ -287,4 +288,10 @@ int main(int argc, char *argv[]) #endif } +#ifdef _UNICODE +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif +#endif + #endif /* ndef UNITTESTS */ diff --git a/src/tool_operate.c b/src/tool_operate.c index 4991186eb..c805b7732 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -81,6 +81,7 @@ #include "tool_help.h" #include "tool_hugehelp.h" #include "tool_progress.h" +#include "tool_ipfs.h" #include "dynbuf.h" #include "memdebug.h" /* keep this as LAST include */ @@ -210,7 +211,7 @@ static curl_off_t all_pers; static CURLcode add_per_transfer(struct per_transfer **per) { struct per_transfer *p; - p = calloc(sizeof(struct per_transfer), 1); + p = calloc(1, sizeof(struct per_transfer)); if(!p) return CURLE_OUT_OF_MEMORY; if(!transfers) @@ -462,7 +463,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, } } -#ifdef WIN32 +#ifdef _WIN32 /* Discard incomplete UTF-8 sequence buffered from body */ if(outs->utf8seq[0]) memset(outs->utf8seq, 0, sizeof(outs->utf8seq)); @@ -697,197 +698,6 @@ static CURLcode post_per_transfer(struct GlobalConfig *global, return result; } -static char *ipfs_gateway(void) -{ - char *gateway = NULL; - char *ipfs_path = NULL; - char *gateway_composed_file_path = NULL; - FILE *gateway_file = NULL; - - gateway = getenv("IPFS_GATEWAY"); - - /* Gateway is found from environment variable. */ - if(gateway && *gateway) { - char *composed_gateway = NULL; - bool add_slash = (gateway[strlen(gateway) - 1] != '/'); - composed_gateway = aprintf("%s%s", gateway, (add_slash) ? "/" : ""); - if(composed_gateway) { - gateway = aprintf("%s", composed_gateway); - Curl_safefree(composed_gateway); - } - return gateway; - } - else - /* a blank string does not count */ - gateway = NULL; - - /* Try to find the gateway in the IPFS data folder. */ - ipfs_path = getenv("IPFS_PATH"); - - if(!ipfs_path) { - char *home = getenv("HOME"); - if(home && *home) - ipfs_path = aprintf("%s/.ipfs/", home); - /* fallback to "~/.ipfs", as that's the default location. */ - } - - if(!ipfs_path) { - Curl_safefree(gateway); - Curl_safefree(ipfs_path); - return NULL; - } - - gateway_composed_file_path = aprintf("%sgateway", ipfs_path); - - if(!gateway_composed_file_path) { - Curl_safefree(gateway); - Curl_safefree(ipfs_path); - return NULL; - } - - gateway_file = fopen(gateway_composed_file_path, FOPEN_READTEXT); - Curl_safefree(gateway_composed_file_path); - - if(gateway_file) { - char *buf = NULL; - - if((PARAM_OK == file2string(&buf, gateway_file)) && buf && *buf) { - bool add_slash = (buf[strlen(buf) - 1] != '/'); - gateway = aprintf("%s%s", buf, (add_slash) ? "/" : ""); - } - Curl_safefree(buf); - - if(gateway_file) - fclose(gateway_file); - - if(!gateway) { - Curl_safefree(gateway); - Curl_safefree(ipfs_path); - return NULL; - } - - Curl_safefree(ipfs_path); - return gateway; - } - - Curl_safefree(gateway); - Curl_safefree(ipfs_path); - return NULL; -} - -/* - * Rewrite ipfs:// and ipns:// to a HTTP(S) - * URL that can be handled by an IPFS gateway. - */ -static CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url, - struct OperationConfig *config) -{ - CURLcode result = CURLE_URL_MALFORMAT; - CURLUcode urlGetResult; - char *gateway = NULL; - char *cid = NULL; - char *pathbuffer = NULL; - CURLU *ipfsurl = curl_url(); - - if(!ipfsurl) { - result = CURLE_FAILED_INIT; - goto clean; - } - - urlGetResult = curl_url_get(uh, CURLUPART_HOST, &cid, CURLU_URLDECODE); - - if(urlGetResult) { - goto clean; - } - - if(!cid) { - goto clean; - } - - /* We might have a --ipfs-gateway argument. Check it first and use it. Error - * if we do have something but if it's an invalid url. - */ - if(config->ipfs_gateway) { - if(curl_url_set(ipfsurl, CURLUPART_URL, config->ipfs_gateway, - CURLU_GUESS_SCHEME) - == CURLUE_OK) { - gateway = strdup(config->ipfs_gateway); - if(!gateway) { - result = CURLE_URL_MALFORMAT; - goto clean; - } - - } - else { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto clean; - } - } - else { - gateway = ipfs_gateway(); - if(!gateway) { - result = CURLE_FILE_COULDNT_READ_FILE; - goto clean; - } - - if(curl_url_set(ipfsurl, CURLUPART_URL, gateway, CURLU_GUESS_SCHEME - | CURLU_NON_SUPPORT_SCHEME) != CURLUE_OK) { - goto clean; - } - } - - pathbuffer = aprintf("%s/%s", protocol, cid); - if(!pathbuffer) { - goto clean; - } - - if(curl_url_set(ipfsurl, CURLUPART_PATH, pathbuffer, CURLU_URLENCODE) - != CURLUE_OK) { - goto clean; - } - - /* Free whatever it has now, rewriting is next */ - Curl_safefree(*url); - - if(curl_url_get(ipfsurl, CURLUPART_URL, url, CURLU_URLENCODE) - != CURLUE_OK) { - goto clean; - } - - result = CURLE_OK; - -clean: - free(gateway); - curl_free(cid); - curl_free(pathbuffer); - curl_url_cleanup(ipfsurl); - - switch(result) { - case CURLE_URL_MALFORMAT: - helpf(tool_stderr, "malformed URL. Visit https://curl.se/" - "docs/ipfs.html#Gateway-file-and-" - "environment-variable for more " - "information"); - break; - case CURLE_FILE_COULDNT_READ_FILE: - helpf(tool_stderr, "IPFS automatic gateway detection " - "failure. Visit https://curl.se/docs/" - "ipfs.html#Malformed-gateway-URL for " - "more information"); - break; - case CURLE_BAD_FUNCTION_ARGUMENT: - helpf(tool_stderr, "--ipfs-gateway argument results in " - "malformed URL. Visit https://curl.se/" - "docs/ipfs.html#Malformed-gateway-URL " - "for more information"); - break; - default: - break; - } - - return result; -} - /* * Return the protocol token for the scheme used in the given URL */ @@ -911,13 +721,13 @@ static CURLcode url_proto(char **url, if(curl_strequal(schemep, proto_ipfs) || curl_strequal(schemep, proto_ipns)) { result = ipfs_url_rewrite(uh, schemep, url, config); - /* short-circuit proto_token, we know it's ipfs or ipns */ if(curl_strequal(schemep, proto_ipfs)) proto = proto_ipfs; else if(curl_strequal(schemep, proto_ipns)) proto = proto_ipns; - + if(result) + config->synthetic_error = TRUE; } else proto = proto_token(schemep); @@ -1776,7 +1586,8 @@ static CURLcode single_transfer(struct GlobalConfig *global, (config->proxy_capath ? config->proxy_capath : config->capath)); - if(result == CURLE_NOT_BUILT_IN) { + if((result == CURLE_NOT_BUILT_IN) || + (result == CURLE_UNKNOWN_OPTION)) { if(config->proxy_capath) { warnf(global, "ignoring --proxy-capath, not supported by libcurl"); @@ -2825,7 +2636,7 @@ static CURLcode transfer_per_config(struct GlobalConfig *global, if(env) curl_free(env); -#ifdef WIN32 +#ifdef _WIN32 else { result = FindWin32CACert(config, tls_backend_info->backend, TEXT("curl-ca-bundle.crt")); diff --git a/src/tool_operate.h b/src/tool_operate.h index 21a7f929d..4993b1c96 100644 --- a/src/tool_operate.h +++ b/src/tool_operate.h @@ -74,7 +74,7 @@ struct per_transfer { /* NULL or malloced */ char *uploadfile; - char *errorbuffer; /* alloced and assigned while this is used for a + char *errorbuffer; /* allocated and assigned while this is used for a transfer */ }; diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c index a964d796d..d1e8352d8 100644 --- a/src/tool_operhlp.c +++ b/src/tool_operhlp.c @@ -215,7 +215,7 @@ CURLcode get_url_file_name(char **filename, const char *url) if(!*filename) return CURLE_OUT_OF_MEMORY; -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) { char *sanitized; SANITIZEcode sc = sanitize_file_name(&sanitized, *filename, 0); @@ -227,7 +227,7 @@ CURLcode get_url_file_name(char **filename, const char *url) } *filename = sanitized; } -#endif /* MSDOS || WIN32 */ +#endif /* _WIN32 || MSDOS */ /* in case we built debug enabled, we allow an environment variable * named CURL_TESTDIR to prefix the given file name to put it into a diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c index c15f21043..da4870066 100644 --- a/src/tool_parsecfg.c +++ b/src/tool_parsecfg.c @@ -46,7 +46,7 @@ static const char *unslashquote(const char *line, char *param); #define MAX_CONFIG_LINE_LENGTH (10*1024*1024) static bool my_get_line(FILE *fp, struct curlx_dynbuf *, bool *error); -#ifdef WIN32 +#ifdef _WIN32 static FILE *execpath(const char *filename, char **pathp) { static char filebuffer[512]; @@ -98,7 +98,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) } filename = pathalloc = curlrc; } -#ifdef WIN32 /* Windows */ +#ifdef _WIN32 /* Windows */ else { char *fullp; /* check for .curlrc then _curlrc in the dir of the executable */ @@ -210,8 +210,9 @@ int parseconfig(const char *filename, struct GlobalConfig *global) break; default: warnf(operation->global, "%s:%d: warning: '%s' uses unquoted " - "whitespace in the line that may cause side-effects", - filename, lineno, option); + "whitespace", filename, lineno, option); + warnf(operation->global, "This may cause side-effects. " + "Consider using double quotes?"); } } if(!*param) diff --git a/src/tool_sdecls.h b/src/tool_sdecls.h index 7b2eb2338..b93c32462 100644 --- a/src/tool_sdecls.h +++ b/src/tool_sdecls.h @@ -71,7 +71,7 @@ struct OutStruct { FILE *stream; curl_off_t bytes; curl_off_t init; -#ifdef WIN32 +#ifdef _WIN32 unsigned char utf8seq[5]; #endif }; diff --git a/src/tool_setup.h b/src/tool_setup.h index 48b355640..c69859ea6 100644 --- a/src/tool_setup.h +++ b/src/tool_setup.h @@ -66,10 +66,12 @@ extern FILE *tool_stderr; # include "tool_strdup.h" #endif -#if defined(WIN32) && !defined(MSDOS) +#if defined(_WIN32) /* set in win32_init() */ extern LARGE_INTEGER tool_freq; extern bool tool_isVistaOrGreater; +/* set in init_terminal() */ +extern bool tool_term_has_bold; #endif #endif /* HEADER_CURL_TOOL_SETUP_H */ diff --git a/src/tool_sleep.c b/src/tool_sleep.c index 08d6f9028..c24f73729 100644 --- a/src/tool_sleep.c +++ b/src/tool_sleep.c @@ -47,7 +47,7 @@ void tool_go_sleep(long ms) { #if defined(MSDOS) delay(ms); -#elif defined(WIN32) +#elif defined(_WIN32) Sleep(ms); #elif defined(HAVE_POLL_FINE) (void)poll((void *)0, 0, (int)ms); diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index 69016179d..e45c7d10b 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -66,13 +66,23 @@ static CURLcode glob_fixed(struct URLGlob *glob, char *fixed, size_t len) */ static int multiply(curl_off_t *amount, curl_off_t with) { - curl_off_t sum = *amount * with; - if(!with) { - *amount = 0; - return 0; + curl_off_t sum; + DEBUGASSERT(*amount >= 0); + DEBUGASSERT(with >= 0); + if((with <= 0) || (*amount <= 0)) { + sum = 0; + } + else { +#if defined(__GNUC__) && \ + ((__GNUC__ > 5) || ((__GNUC__ == 5) && (__GNUC_MINOR__ >= 1))) + if(__builtin_mul_overflow(*amount, with, &sum)) + return 1; +#else + sum = *amount * with; + if(sum/with != *amount) + return 1; /* didn't fit, bail out */ +#endif } - if(sum/with != *amount) - return 1; /* didn't fit, bail out */ *amount = sum; return 0; } @@ -692,7 +702,7 @@ CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob) if(curlx_dyn_addn(&dyn, "", 0)) return CURLE_OUT_OF_MEMORY; -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) { char *sanitized; SANITIZEcode sc = sanitize_file_name(&sanitized, curlx_dyn_ptr(&dyn), @@ -707,5 +717,5 @@ CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob) #else *result = curlx_dyn_ptr(&dyn); return CURLE_OK; -#endif /* MSDOS || WIN32 */ +#endif /* _WIN32 || MSDOS */ } diff --git a/src/tool_util.c b/src/tool_util.c index 7a1c03b20..812a689d0 100644 --- a/src/tool_util.c +++ b/src/tool_util.c @@ -31,7 +31,7 @@ #include "memdebug.h" /* keep this as LAST include */ -#if defined(WIN32) && !defined(MSDOS) +#if defined(_WIN32) /* In case of bug fix this function has a counterpart in timeval.c */ struct timeval tvnow(void) diff --git a/src/tool_writeout_json.c b/src/tool_writeout_json.c index 7bc74a269..4ed6b93fb 100644 --- a/src/tool_writeout_json.c +++ b/src/tool_writeout_json.c @@ -41,8 +41,8 @@ int jsonquoted(const char *in, size_t len, struct curlx_dynbuf *out, bool lowercase) { - const char *i = in; - const char *in_end = &in[len]; + const unsigned char *i = (unsigned char *)in; + const unsigned char *in_end = &i[len]; CURLcode result = CURLE_OK; for(; (i < in_end) && !result; i++) { diff --git a/src/tool_xattr.c b/src/tool_xattr.c index 968cf2f72..9472194fa 100644 --- a/src/tool_xattr.c +++ b/src/tool_xattr.c @@ -87,11 +87,12 @@ static int xattr(int fd, int err = 0; if(value) { #ifdef DEBUGBUILD + (void)fd; if(getenv("CURL_FAKE_XATTR")) { printf("%s => %s\n", attr, value); } return 0; -#endif +#else #ifdef HAVE_FSETXATTR_6 err = fsetxattr(fd, attr, value, strlen(value), 0, 0); #elif defined(HAVE_FSETXATTR_5) @@ -104,6 +105,7 @@ static int xattr(int fd, attribute */ err = (rc < 0 ? -1 : 0); } +#endif #endif } return err; diff --git a/src/var.c b/src/var.c index f8f42f666..388d45592 100644 --- a/src/var.c +++ b/src/var.c @@ -358,7 +358,7 @@ static ParameterError addvariable(struct GlobalConfig *global, if(check) notef(global, "Overwriting variable '%s'", check->name); - p = calloc(sizeof(struct var), 1); + p = calloc(1, sizeof(struct var)); if(!p) return PARAM_NO_MEM; diff --git a/tests/README.md b/tests/README.md index 65af2a0bd..1464eacdc 100644 --- a/tests/README.md +++ b/tests/README.md @@ -8,6 +8,41 @@ SPDX-License-Identifier: curl # Running + See the "Requires to run" section for prerequisites. + + In the root of the curl repository: + + ./configure && make && make test + + To run a specific set of tests (e.g. 303 and 410): + + make test TFLAGS="303 410" + + To run the tests faster, pass the -j (parallelism) flag: + + make test TFLAGS="-j10" + + "make test" builds the test suite support code and invokes the 'runtests.pl' + perl script to run all the tests. The value of `TFLAGS` is passed + directly to 'runtests.pl'. + + When you run tests via make, the flags `-a` and `-s` are passed, meaning + to continue running tests even after one fails, and to emit short output. + + If you'd like to not use those flags, you can run 'runtests.pl' directly. + You must `chdir` into the tests directory, then you can run it like so: + + ./runtests.pl 303 410 + + You must have run `make test` at least once first to build the support code. + + To see what flags are available for runtests.pl, and what output it emits, run: + + man ./tests/runtests.1 + + After a test fails, examine the tests/log directory for stdout, stderr, and + output from the servers used in the test. + ## Requires to run - perl (and a unix-style shell) @@ -15,7 +50,7 @@ SPDX-License-Identifier: curl - python-impacket (for SMB tests) - diff (when a test fails, a diff is shown) - stunnel (for HTTPS and FTPS tests) - - OpenSSH or SunSSH (for SCP, SFTP and SOCKS4/5 tests) + - OpenSSH or SunSSH (for SCP and SFTP tests) - nghttpx (for HTTP/2 and HTTP/3 tests) - nroff (for --manual tests) - An available `en_US.UTF-8` locale @@ -59,9 +94,7 @@ SPDX-License-Identifier: curl The test suite runs stand-alone servers on random ports to which it makes requests. For SSL tests, it runs stunnel to handle encryption to the regular - servers. For SSH, it runs a standard OpenSSH server. For SOCKS4/5 tests SSH - is used to perform the SOCKS functionality and requires a SSH client and - server. + servers. For SSH, it runs a standard OpenSSH server. The listen port numbers for the test servers are picked randomly to allow users to run multiple test cases concurrently and to not collide with other @@ -75,47 +108,9 @@ SPDX-License-Identifier: curl used, set the environment variable `NGHTTPX`. The default can also be changed by specifying `--with-test-nghttpx=` as argument to `configure`. -### Run - - `./configure && make && make test`. This builds the test suite support code - and invokes the 'runtests.pl' perl script to run all the tests. Edit the top - variables of that script in case you have some specific needs, or run the - script manually (after the support code has been built). - - The script breaks on the first test that doesn't do OK. Use `-a` to prevent - the script from aborting on the first error. Run the script with `-v` for - more verbose output. Use `-d` to run the test servers with debug output - enabled as well. Specifying `-k` keeps all the log files generated by the - test intact. - - Use `-s` for shorter output, or pass test numbers to run specific tests only - (like `./runtests.pl 3 4` to test 3 and 4 only). It also supports test case - ranges with 'to', as in `./runtests.pl 3 to 9` which runs the seven tests - from 3 to 9. Any test numbers starting with ! are disabled, as are any test - numbers found in the files `data/DISABLED` or `data/DISABLED.local` (one per - line). The latter is meant for local temporary disables and will be ignored - by git. - - Test cases mentioned in `DISABLED` can still be run if `-f` is provided. - - When `-s` is not present, each successful test will display on one line the - test number and description and on the next line a set of flags, the test - result, current test sequence, total number of tests to be run and an - estimated amount of time to complete the test run. The flags consist of - these letters describing what is checked in this test: - - s stdout - d data - u upload - p protocol - o output - e exit code - m memory - v valgrind - ### Shell startup scripts - Tests which use the ssh test server, SCP/SFTP/SOCKS tests, might be badly + Tests which use the ssh test server, SCP/SFTP tests, might be badly influenced by the output of system wide or user specific shell startup scripts, .bashrc, .profile, /etc/csh.cshrc, .login, /etc/bashrc, etc. which output text messages or escape sequences on user login. When these shell diff --git a/tests/data/DISABLED b/tests/data/DISABLED index 308d27e5a..b077c67a0 100644 --- a/tests/data/DISABLED +++ b/tests/data/DISABLED @@ -70,9 +70,6 @@ 266 579 587 -722 -724 -727 # 1021 re-added here due to flakiness 1021 1117 diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 1472b1954..de13c525e 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -51,7 +51,7 @@ test226 test227 test228 test229 test230 test231 test232 test233 test234 \ test235 test236 test237 test238 test239 test240 test241 test242 test243 \ test244 test245 test246 test247 test248 test249 test250 test251 test252 \ test253 test254 test255 test256 test257 test258 test259 test260 test261 \ -test262 test263 test264 test265 test266 test267 test269 test270 \ +test262 test263 test264 test265 test266 test267 test268 test269 test270 \ test271 test272 test273 test274 test275 test276 test277 test278 test279 \ test280 test281 test282 test283 test284 test285 test286 test287 test288 \ test289 test290 test291 test292 test293 test294 test295 test296 test297 \ @@ -72,7 +72,7 @@ test417 test418 test419 test420 test421 test422 test423 test424 test425 \ test426 test427 test428 test429 test430 test431 test432 test433 test434 \ test435 test436 test437 test438 test439 test440 test441 test442 test443 \ test444 test445 test446 test447 test448 test449 test450 test451 test452 \ -test453 test454 test455 test456 test457 test458 \ +test453 test454 test455 test456 test457 test458 test459 \ \ test490 test491 test492 test493 test494 test495 test496 test497 test498 \ \ @@ -101,7 +101,8 @@ test681 test682 test683 test684 test685 test686 test687 test688 \ test700 test701 test702 test703 test704 test705 test706 test707 test708 \ test709 test710 test711 test712 test713 test714 test715 test716 test717 \ test718 test719 test720 test721 test722 test723 test724 test725 test726 \ -test727 test728 \ +test727 test728 test729 test730 test731 test732 test733 test734 test735 \ +test736 test737 test738 test739 test740 test741 \ \ test799 test800 test801 test802 test803 test804 test805 test806 test807 \ test808 test809 test810 test811 test812 test813 test814 test815 test816 \ @@ -185,14 +186,14 @@ test1439 test1440 test1441 test1442 test1443 test1444 test1445 test1446 \ test1447 test1448 test1449 test1450 test1451 test1452 test1453 test1454 \ test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \ test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \ -test1471 test1472 test1473 test1474 \ +test1471 test1472 test1473 test1474 test1475 test1476 test1477 \ \ test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ 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 test1542 test1543 test1544 \ +test1540 test1542 test1543 test1544 test1545 \ \ test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \ test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \ @@ -218,7 +219,7 @@ test1700 test1701 test1702 test1703 \ \ test1800 test1801 \ \ - test1903 test1904 test1905 test1906 test1907 \ +test1900 test1903 test1904 test1905 test1906 test1907 \ test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \ test1916 test1917 test1918 test1919 \ \ diff --git a/tests/data/test1475 b/tests/data/test1475 new file mode 100644 index 000000000..f88ef74ee --- /dev/null +++ b/tests/data/test1475 @@ -0,0 +1,83 @@ + +# also verified by 1156 in libcurl API terms + + + +HTTP +HTTP GET +Resume + + + +# Server-side + + +HTTP/1.1 416 Invalid range +Connection: close +Content-Length: 0 +Content-Range: */100 + + + +# The file data that exists at the start of the test must be included in +# the verification. + +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +HTTP/1.1 416 Invalid range +Connection: close +Content-Length: 0 +Content-Range: */100 + + + + + +# Client-side + + +http + + +http + + +-f and 416 with Content-Range: */size + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER -C - -f + + +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 +012345678 + + + +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +Range: bytes=100- +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test1476 b/tests/data/test1476 new file mode 100644 index 000000000..101fa95b0 --- /dev/null +++ b/tests/data/test1476 @@ -0,0 +1,59 @@ + + + +HTTP +HTTP GET +cookies + + + +# Server-side + + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 0 +Set-Cookie: super=oops; domain=co.UK; path=/ +Set-Cookie: fine=yesyes; domain=CURL.CO.UK; path=/ + + + + +# Client-side + + +http + + +PSL violating cookie with mixed case domain and cookie domain property + + +-x http://%HOSTIP:%HTTPPORT/%TESTNUMBER http://curl.co.UK -c %LOGDIR/cookies%TESTNUMBER.txt + + +proxy +PSL +cookies + + + +# Verify data after the test has been "shot" + + +GET http://curl.co.UK/ HTTP/1.1 +Host: curl.co.UK +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + + + +# Netscape HTTP Cookie File +# https://curl.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +.CURL.CO.UK TRUE / FALSE 0 fine yesyes + + + diff --git a/tests/data/test1477 b/tests/data/test1477 new file mode 100644 index 000000000..2771d7f1d --- /dev/null +++ b/tests/data/test1477 @@ -0,0 +1,30 @@ + + + +documentation + + + +# +# Client-side + + +none + + + +Verify that error codes in headers and libcurl-errors.3 are in sync + + + +%SRCDIR/errorcodes.pl %SRCDIR/.. + + + + + +Result + + + + diff --git a/tests/data/test1506 b/tests/data/test1506 index 9eb38cf6d..0a62c0c2a 100644 --- a/tests/data/test1506 +++ b/tests/data/test1506 @@ -86,7 +86,6 @@ Accept: */* * Connection #0 to host server1.example.com left intact * Connection #1 to host server2.example.com left intact * Connection #2 to host server3.example.com left intact -* Closing connection * Connection #3 to host server4.example.com left intact diff --git a/tests/data/test1545 b/tests/data/test1545 new file mode 100644 index 000000000..477b5bf44 --- /dev/null +++ b/tests/data/test1545 @@ -0,0 +1,38 @@ + + + +HTTP +HTTP GET + + +# +# Server-side + + + +# Client-side + + +form-api + + +http + +# tool is what to use instead of 'curl' + +lib%TESTNUMBER + + + +use curl_formadd() data twice with unreadable file + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# +# Verify data after the test has been "shot" + + + diff --git a/tests/data/test1683 b/tests/data/test1683 index 178b4054d..581470dfc 100644 --- a/tests/data/test1683 +++ b/tests/data/test1683 @@ -40,11 +40,9 @@ to stay the same perl -e 'for my $i ((1..100)) { my $filename = "%LOGDIR/exist%TESTNUMBER.$i"; open(FH, ">", $filename) or die $!; print FH "to stay the same" ; close(FH) }' -# python3 -c 'for i in range(1, 101): open("%LOGDIR/exist%TESTNUMBER.{}".format(i), mode="w").write("to stay the same")' perl -e 'for my $i ((1..100)) { my $filename = "%LOGDIR/exist%TESTNUMBER.$i"; open(FH, "<", $filename) or die $!; ( eq "to stay the same" and eq "") or die "incorrect $filename" ; close(FH) }' -# python3 -c 'for i in range(1, 101): assert open("%LOGDIR/exist%TESTNUMBER.{}".format(i), mode="r").read(17) == "to stay the same"' diff --git a/tests/data/test1900 b/tests/data/test1900 new file mode 100644 index 000000000..f04e7e2af --- /dev/null +++ b/tests/data/test1900 @@ -0,0 +1,38 @@ + + + +HTTP +HSTS + + + +# Server-side + + + +# Client-side + + +HSTS +http + + +none + + + +HSTS curl_easy_duphandle + + +lib%TESTNUMBER + + + +http://%HOSTIP:%NOLISTENPORT/not-there/%TESTNUMBER + + + +# Verify data after the test has been "shot" + + + diff --git a/tests/data/test194 b/tests/data/test194 index 4de767e3a..074348950 100644 --- a/tests/data/test194 +++ b/tests/data/test194 @@ -64,9 +64,8 @@ User-Agent: curl/%VERSION Accept: */* -# CURLE_HTTP_RETURNED_ERROR -22 +0 diff --git a/tests/data/test268 b/tests/data/test268 new file mode 100644 index 000000000..3a1ab6a9b --- /dev/null +++ b/tests/data/test268 @@ -0,0 +1,59 @@ + + + +HTTP +variables + + + +# +# Server-side + + +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: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +JSON encoding of unicode string + + +%hex[%e2%80%9c]hex% + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --variable hello@%LOGDIR/junk --expand-data {{hello:json}} + + + +# +# Verify data after the test has been "shot" + + +POST /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* +Content-Length: 3 +Content-Type: application/x-www-form-urlencoded + +%hex[%e2%80%9c]hex% + + + diff --git a/tests/data/test3103 b/tests/data/test3103 index 23a0fea17..423c4adaa 100644 --- a/tests/data/test3103 +++ b/tests/data/test3103 @@ -48,7 +48,7 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER # # Verify data after the test has been "shot" - + GET http://localhost/ HTTP/1.1 Host: localhost Accept: */* diff --git a/tests/data/test439 b/tests/data/test439 index da1261531..c997a397a 100644 --- a/tests/data/test439 +++ b/tests/data/test439 @@ -38,7 +38,7 @@ debug aws-sigv4 with query -"http://fake.fake.fake:8000/%TESTNUMBER/?name=me%&aim=b%aad&&&weirdo=*.//-" -u user:secret --aws-sigv4 "aws:amz:us-east-2:es" --connect-to fake.fake.fake:8000:%HOSTIP:%HTTPPORT +"http://fake.fake.fake:8000/%TESTNUMBER/?name=me%&noval&aim=b%aad&&&weirdo=*.//-" -u user:secret --aws-sigv4 "aws:amz:us-east-2:es" --connect-to fake.fake.fake:8000:%HOSTIP:%HTTPPORT @@ -46,9 +46,9 @@ aws-sigv4 with query # Verify data after the test has been "shot" -GET /%TESTNUMBER/?name=me%&aim=b%aad&&&weirdo=*.//- HTTP/1.1 +GET /439/?name=me%&noval&aim=b%aad&&&weirdo=*.//- HTTP/1.1 Host: fake.fake.fake:8000 -Authorization: AWS4-HMAC-SHA256 Credential=user/19700101/us-east-2/es/aws4_request, SignedHeaders=host;x-amz-date, Signature=88884e3b3142133685b2092d29d8b522b785b1a9ec9e4a90cbea83e882f8dcb6 +Authorization: AWS4-HMAC-SHA256 Credential=user/19700101/us-east-2/es/aws4_request, SignedHeaders=host;x-amz-date, Signature=cbbf4a72764e27e396730f5e56cea046d4ce862a2d91db4856fb086b92f49270 X-Amz-Date: 19700101T000000Z User-Agent: curl/%VERSION Accept: */* diff --git a/tests/data/test457 b/tests/data/test457 index 77eb9c855..aa391d7fd 100644 --- a/tests/data/test457 +++ b/tests/data/test457 @@ -20,7 +20,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 30 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 21;heresatest=moooo -cccccccccccccccccccccccccccccccc +cccccccccccccccccccccccccccccc +c 0 @@ -31,7 +32,7 @@ Server: fakeit/0.9 fakeitbad/1.0 Transfer-Encoding: chunked Connection: mooo -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccc +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccc diff --git a/tests/data/test459 b/tests/data/test459 new file mode 100644 index 000000000..e46d02973 --- /dev/null +++ b/tests/data/test459 @@ -0,0 +1,63 @@ + + + +HTTP +--config + + + +# +# Server-side + + +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: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +config file with argument using whitespace missing quotes + + +data = arg with space + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --config %LOGDIR/config --silent + + + +# +# Verify data after the test has been "shot" + + +POST /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* +Content-Length: 3 +Content-Type: application/x-www-form-urlencoded + +arg + + +Warning: %LOGDIR/config:1: warning: 'data' uses unquoted whitespace +Warning: This may cause side-effects. Consider using double quotes? + + + diff --git a/tests/data/test722 b/tests/data/test722 index 674efd14a..c5b8d8610 100644 --- a/tests/data/test722 +++ b/tests/data/test722 @@ -8,7 +8,7 @@ IPFS # # Server-side - + HTTP/1.1 200 OK Date: Tue, 09 Nov 2010 14:49:00 GMT Server: test-server/fake @@ -34,7 +34,7 @@ http IPFS ---ipfs-gateway http://%HOSTIP:%HTTPPORT/%TESTNUMBER ipfs://QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx +--ipfs-gateway http://%HOSTIP:%HTTPPORT ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u @@ -42,7 +42,7 @@ IPFS # Verify data after the test has been "shot" -GET /ipfs/QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx HTTP/1.1 +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 Host: %HOSTIP:%HTTPPORT User-Agent: curl/%VERSION Accept: */* diff --git a/tests/data/test723 b/tests/data/test723 index aaf4d27a3..dac78fc54 100644 --- a/tests/data/test723 +++ b/tests/data/test723 @@ -20,7 +20,7 @@ http IPFS with malformed gateway URL (bad function argument error) ---ipfs-gateway http://nonexisting,local:8080/%TESTNUMBER ipfs://QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx +--ipfs-gateway http://nonexisting,local:8080 ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u diff --git a/tests/data/test724 b/tests/data/test724 index 692046b31..c97354b0d 100644 --- a/tests/data/test724 +++ b/tests/data/test724 @@ -8,7 +8,7 @@ IPFS # # Server-side - + HTTP/1.1 200 OK Date: Tue, 09 Nov 2010 14:49:00 GMT Server: test-server/fake @@ -37,10 +37,10 @@ HOME=%PWD/%LOGDIR IPFS with gateway URL from gateway file -ipfs://QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u -http://%HOSTIP:%HTTPPORT/%TESTNUMBER +http://%HOSTIP:%HTTPPORT @@ -48,7 +48,7 @@ http://%HOSTIP:%HTTPPORT/%TESTNUMBER # Verify data after the test has been "shot" -GET /ipfs/QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx HTTP/1.1 +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 Host: %HOSTIP:%HTTPPORT User-Agent: curl/%VERSION Accept: */* diff --git a/tests/data/test725 b/tests/data/test725 index cf3c19664..de7c39493 100644 --- a/tests/data/test725 +++ b/tests/data/test725 @@ -23,10 +23,10 @@ HOME=%PWD/%LOGDIR IPFS with malformed gateway URL from gateway file -ipfs://QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u -http://nonexisting,local:8080/%TESTNUMBER +http://nonexisting,local:8080 diff --git a/tests/data/test726 b/tests/data/test726 index c0abbf29c..f51adf594 100644 --- a/tests/data/test726 +++ b/tests/data/test726 @@ -26,7 +26,7 @@ HOME=%PWD IPFS with no gateway URL (no environment or home file either) -ipfs://QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u diff --git a/tests/data/test727 b/tests/data/test727 index e71ef5f44..aa2c84fbc 100644 --- a/tests/data/test727 +++ b/tests/data/test727 @@ -8,7 +8,7 @@ IPNS # # Server-side - + HTTP/1.1 200 OK Date: Tue, 09 Nov 2010 14:49:00 GMT Server: test-server/fake @@ -34,7 +34,7 @@ http IPNS ---ipfs-gateway http://%HOSTIP:%HTTPPORT/%TESTNUMBER ipns://QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx +--ipfs-gateway http://%HOSTIP:%HTTPPORT ipns://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u @@ -42,7 +42,7 @@ IPNS # Verify data after the test has been "shot" -GET /ipns/QmV5JejrpgUxnkZeFZYMxVCqAbKy3KdPXWXyuEDiMNZwUx HTTP/1.1 +GET /ipns/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 Host: %HOSTIP:%HTTPPORT User-Agent: curl/%VERSION Accept: */* diff --git a/tests/data/test729 b/tests/data/test729 new file mode 100644 index 000000000..805758921 --- /dev/null +++ b/tests/data/test729 @@ -0,0 +1,41 @@ + + + +HTTP +HTTP GET +SOCKS4 + + + +# +# Server-side + + + +# +# Client-side + + +proxy + + +http +socks4 + + +SOCKS4 with very long proxy user name + + +http://fake --limit-rate 1 -x socks4a://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@%HOSTIP:%SOCKSPORT + + + +# +# Verify data after the test has been "shot" + +# CURLE_PROXY + +97 + + + diff --git a/tests/data/test730 b/tests/data/test730 new file mode 100644 index 000000000..138f85086 --- /dev/null +++ b/tests/data/test730 @@ -0,0 +1,52 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPFS arg gateway with path + + +--ipfs-gateway http://%HOSTIP:%HTTPPORT/foo/bar ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + + +# +# Verify data after the test has been "shot" + + +GET /foo/bar/ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test731 b/tests/data/test731 new file mode 100644 index 000000000..9e135dbec --- /dev/null +++ b/tests/data/test731 @@ -0,0 +1,58 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +HOME=%PWD/%LOGDIR + + +IPFS with gateway URL and path from gateway file + + +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER/ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test732 b/tests/data/test732 new file mode 100644 index 000000000..9adaedb93 --- /dev/null +++ b/tests/data/test732 @@ -0,0 +1,52 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPFS with path + + +--ipfs-gateway http://%HOSTIP:%HTTPPORT "ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u/a/b" + + + +# +# Verify data after the test has been "shot" + + +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u/a/b HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test733 b/tests/data/test733 new file mode 100644 index 000000000..ad17cd4bf --- /dev/null +++ b/tests/data/test733 @@ -0,0 +1,52 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPFS with path and query args + + +--ipfs-gateway http://%HOSTIP:%HTTPPORT "ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u/a/b?foo=bar&aaa=bbb" + + + +# +# Verify data after the test has been "shot" + + +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u/a/b?foo=bar&aaa=bbb HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test734 b/tests/data/test734 new file mode 100644 index 000000000..03f571cc6 --- /dev/null +++ b/tests/data/test734 @@ -0,0 +1,52 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPFS with path, query args and gateway with path + + +--ipfs-gateway http://%HOSTIP:%HTTPPORT/some/path "ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u/a/b?foo=bar&aaa=bbb" + + + +# +# Verify data after the test has been "shot" + + +GET /some/path/ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u/a/b?foo=bar&aaa=bbb HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test735 b/tests/data/test735 new file mode 100644 index 000000000..da1aac4dd --- /dev/null +++ b/tests/data/test735 @@ -0,0 +1,52 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPNS with path, query args and gateway with path + + +--ipfs-gateway http://%HOSTIP:%HTTPPORT/some/path "ipns://fancy.tld/a/b?foo=bar&aaa=bbb" + + + +# +# Verify data after the test has been "shot" + + +GET /some/path/ipns/fancy.tld/a/b?foo=bar&aaa=bbb HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test736 b/tests/data/test736 new file mode 100644 index 000000000..45d9a055a --- /dev/null +++ b/tests/data/test736 @@ -0,0 +1,58 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPFS_PATH=%LOGDIR/.ipfs + + +IPFS with IPFS_PATH set, no trailing slash + + +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + +http://%HOSTIP:%HTTPPORT + + + +# +# Verify data after the test has been "shot" + + +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test737 b/tests/data/test737 new file mode 100644 index 000000000..bc6e8576a --- /dev/null +++ b/tests/data/test737 @@ -0,0 +1,58 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +IPFS_PATH=%LOGDIR/.ipfs/ + + +IPFS with IPFS_PATH set, with trailing slash + + +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + +http://%HOSTIP:%HTTPPORT + + + +# +# Verify data after the test has been "shot" + + +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test738 b/tests/data/test738 new file mode 100644 index 000000000..5c05137dc --- /dev/null +++ b/tests/data/test738 @@ -0,0 +1,37 @@ + + + +IPFS + + + +# +# Server-side + + + +# +# Client-side + + +http + + +IPFS_PATH=%LOGDIR/.ipfs/ + + +IPFS with IPFS_PATH, no gateway file + + +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + + +# +# Verify error code with no gateway file (detection fails) + + +37 + + + diff --git a/tests/data/test739 b/tests/data/test739 new file mode 100644 index 000000000..fe78c41bb --- /dev/null +++ b/tests/data/test739 @@ -0,0 +1,34 @@ + + + +IPFS + + + +# +# Server-side + + + +# +# Client-side + + +http + + +IPNS path and query args for gateway and IPFS url (malformed gateway url) + + +--ipfs-gateway "http://%HOSTIP:%HTTPPORT/some/path?biz=baz" "ipns://fancy.tld/a/b?foo=bar&aaa=bbb" + + + +# +# Verify data after the test has been "shot" + + +3 + + + diff --git a/tests/data/test740 b/tests/data/test740 new file mode 100644 index 000000000..97258d384 --- /dev/null +++ b/tests/data/test740 @@ -0,0 +1,60 @@ + + + +IPFS + + + +# +# Server-side + + +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: 21 +Connection: close +Content-Type: text/plain +Funny-head: yesyes + +Hello curl from IPFS + + + +# +# Client-side + + +http + + +HOME=%PWD/%LOGDIR + + +IPFS with gateway URL from multiline gateway file + + +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + +http://%HOSTIP:%HTTPPORT +foo +bar + + + +# +# Verify data after the test has been "shot" + + +GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + + diff --git a/tests/data/test741 b/tests/data/test741 new file mode 100644 index 000000000..e773cd08a --- /dev/null +++ b/tests/data/test741 @@ -0,0 +1,42 @@ + + + +IPFS + + + +# +# Server-side + + + +# +# Client-side + + +http + + +HOME=%PWD/%LOGDIR + + +IPFS with malformed gateway URL from multiline gateway file, first line no url + + +ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u + + +foo +bar + + + +# +# Verify data after the test has been "shot" + +# malformed gateway URL, first line in file must be a gateway URL + +3 + + + diff --git a/tests/disable-scan.pl b/tests/disable-scan.pl index 99f5436af..b6f3179cf 100644 --- a/tests/disable-scan.pl +++ b/tests/disable-scan.pl @@ -29,6 +29,8 @@ # the DISABLE options that can be set by configure my %disable; +# the DISABLE options that can be set by CMakeLists.txt +my %disable_cmake; # the DISABLE options that are used in C files my %file; # the DISABLE options that are documented @@ -61,6 +63,24 @@ sub scan_configure { } } +sub scanconf_cmake { + my ($f)=@_; + open S, "<$f"; + while() { + if(/(CURL_DISABLE_[A-Z_]+)/g) { + my ($sym)=($1); + if(not $sym =~ /(CURL_DISABLE_INSTALL|CURL_DISABLE_TESTS|CURL_DISABLE_SRP)/) { + $disable_cmake{$sym} = 1; + } + } + } + close S; +} + +sub scan_cmake { + scanconf_cmake("$root/CMakeLists.txt"); +} + sub scan_file { my ($source)=@_; open F, "<$source"; @@ -104,6 +124,7 @@ sub scan_docs { } scan_configure(); +scan_cmake(); scan_sources(); scan_docs(); @@ -121,12 +142,28 @@ sub scan_docs { } } +# Check the CMakeLists.txt symbols for use in code +for my $s (sort keys %disable_cmake) { + if(!$file{$s}) { + printf "Present in CMakeLists.txt, not used by code: %s\n", $s; + $error++; + } + if(!$docs{$s}) { + printf "Present in CMakeLists.txt, not documented in $DOCS: %s\n", $s; + $error++; + } +} + # Check the code symbols for use in configure for my $s (sort keys %file) { if(!$disable{$s}) { printf "Not set by configure: %s (%s)\n", $s, $file{$s}; $error++; } + if(!$disable_cmake{$s}) { + printf "Not set by CMakeLists.txt: %s (%s)\n", $s, $file{$s}; + $error++; + } if(!$docs{$s}) { printf "Used in code, not documented in $DOCS: %s\n", $s; $error++; @@ -139,6 +176,10 @@ sub scan_docs { printf "Documented but not in configure: %s\n", $s; $error++; } + if(!$disable_cmake{$s}) { + printf "Documented but not in CMakeLists.txt: %s\n", $s; + $error++; + } if(!$file{$s}) { printf "Documented, but not used by code: %s\n", $s; $error++; diff --git a/tests/errorcodes.pl b/tests/errorcodes.pl new file mode 100755 index 000000000..9c8f9e882 --- /dev/null +++ b/tests/errorcodes.pl @@ -0,0 +1,99 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# 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 +# +########################################################################### + +# Check that libcurl-errors.3 and the public header files have the same set of +# error codes. + +use strict; +use warnings; + +# we may get the dir roots pointed out +my $root=$ARGV[0] || "."; +my $manpge = "$root/docs/libcurl/libcurl-errors.3"; +my $curlh = "$root/include/curl"; +my $errors=0; + +my @hnames; +my %wherefrom; +my @mnames; +my %manfrom; + +sub scanheader { + my ($file)=@_; + open H, "<$file"; + my $line = 0; + while() { + $line++; + if($_ =~ /^ (CURL(E|UE|SHE|HE|M)_[A-Z0-9_]*)/) { + my ($name)=($1); + if(($name !~ /OBSOLETE/) && ($name !~ /_LAST\z/)) { + push @hnames, $name; + if($wherefrom{$name}) { + print STDERR "double: $name\n"; + } + $wherefrom{$name}="$file:$line"; + } + } + } + close(H); +} + +sub scanmanpage { + my ($file)=@_; + open H, "<$file"; + my $line = 0; + while() { + $line++; + if($_ =~ /^\.IP \"(CURL(E|UE|SHE|HE|M)_[A-Z0-9_]*)/) { + my ($name)=($1); + push @mnames, $name; + $manfrom{$name}="$file:$line"; + } + } + close(H); +} + + +opendir(my $dh, $curlh) || die "Can't opendir $curlh: $!"; +my @hfiles = grep { /\.h$/ } readdir($dh); +closedir $dh; + +for(sort @hfiles) { + scanheader("$curlh/$_"); +} +scanmanpage($manpge); + +print "Result\n"; +for my $h (sort @hnames) { + if(!$manfrom{$h}) { + printf "$h from %s, not in man page\n", $wherefrom{$h}; + } +} + +for my $m (sort @mnames) { + if(!$wherefrom{$m}) { + printf "$m from %s, not in any header\n", $manfrom{$m}; + } +} diff --git a/tests/http/clients/h2-download.c b/tests/http/clients/h2-download.c index 24ccedbdd..53f3ac0d0 100644 --- a/tests/http/clients/h2-download.c +++ b/tests/http/clients/h2-download.c @@ -196,7 +196,6 @@ int main(int argc, char *argv[]) case 'h': usage(NULL); return 2; - break; case 'a': abort_paused = 1; break; diff --git a/tests/http/test_02_download.py b/tests/http/test_02_download.py index 22fa32cd2..391371c31 100644 --- a/tests/http/test_02_download.py +++ b/tests/http/test_02_download.py @@ -108,16 +108,17 @@ def test_02_04_download_100_parallel(self, env: Env, # download 500 files sequential @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) - def test_02_05_download_500_sequential(self, env: Env, - httpd, nghttpx, repeat, proto): + def test_02_05_download_many_sequential(self, env: Env, + httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 shaky here") + count = 200 curl = CurlClient(env=env) - urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-499]' + urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-{count-1}]' r = curl.http_download(urls=[urln], alpn_proto=proto) - r.check_response(http_status=200, count=500) + r.check_response(http_status=200, count=count) if proto == 'http/1.1': # http/1.1 parallel transfers will open multiple connections assert r.total_connects > 1, r.dump_logs() @@ -127,11 +128,11 @@ def test_02_05_download_500_sequential(self, env: Env, # download 500 files parallel @pytest.mark.parametrize("proto", ['h2', 'h3']) - def test_02_06_download_500_parallel(self, env: Env, - httpd, nghttpx, repeat, proto): + def test_02_06_download_many_parallel(self, env: Env, + httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 500 + count = 200 max_parallel = 50 curl = CurlClient(env=env) urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[000-{count-1}]' @@ -207,7 +208,7 @@ def test_02_10_10MB_serial(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 20 + count = 10 urln = f'https://{env.authority_for(env.domain1, proto)}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto) @@ -222,7 +223,7 @@ def test_02_11_10MB_parallel(self, env: Env, pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") - count = 20 + count = 10 urln = f'https://{env.authority_for(env.domain1, proto)}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ @@ -235,7 +236,7 @@ def test_02_12_head_serial_https(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 100 + count = 50 urln = f'https://{env.authority_for(env.domain1, proto)}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ @@ -248,7 +249,7 @@ def test_02_13_head_serial_h2c(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") - count = 100 + count = 50 urln = f'http://{env.domain1}:{env.http_port}/data-10m?[0-{count-1}]' curl = CurlClient(env=env) r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[ diff --git a/tests/http/test_07_upload.py b/tests/http/test_07_upload.py index 5aee3ea26..018a56c6e 100644 --- a/tests/http/test_07_upload.py +++ b/tests/http/test_07_upload.py @@ -124,7 +124,7 @@ def test_07_12_upload_seq_large(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") fdata = os.path.join(env.gen_dir, 'data-100k') - count = 50 + count = 20 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto) @@ -161,7 +161,7 @@ def test_07_20_upload_parallel(self, env: Env, httpd, nghttpx, repeat, proto): if proto == 'h3' and env.curl_uses_lib('msh3'): pytest.skip("msh3 stalls here") # limit since we use a separate connection in h1 - count = 50 + count = 20 data = '0123456789' curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' @@ -181,7 +181,7 @@ def test_07_21_upload_parallel_large(self, env: Env, httpd, nghttpx, repeat, pro pytest.skip("msh3 stalls here") fdata = os.path.join(env.gen_dir, 'data-100k') # limit since we use a separate connection in h1 - count = 50 + count = 20 curl = CurlClient(env=env) url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo?id=[0-{count-1}]' r = curl.http_upload(urls=[url], data=f'@{fdata}', alpn_proto=proto, @@ -219,7 +219,7 @@ def test_07_31_put_10m(self, env: Env, httpd, nghttpx, repeat, proto): fdata = os.path.join(env.gen_dir, 'data-10m') count = 1 curl = CurlClient(env=env) - url = f'https://{env.authority_for(env.domain1, proto)}/curltest/put?id=[0-{count-1}]&chunk_delay=10ms' + url = f'https://{env.authority_for(env.domain1, proto)}/curltest/put?id=[0-{count-1}]&chunk_delay=2ms' r = curl.http_put(urls=[url], fdata=fdata, alpn_proto=proto, extra_args=['--parallel']) r.check_stats(count=count, http_status=200, exitcode=0) diff --git a/tests/http/test_10_proxy.py b/tests/http/test_10_proxy.py index df234013c..0e4060b67 100644 --- a/tests/http/test_10_proxy.py +++ b/tests/http/test_10_proxy.py @@ -247,3 +247,105 @@ def test_10_09_reuse_ser(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): assert r.total_connects == 2 else: assert r.total_connects == 2 + + @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") + @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) + @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") + def test_10_10_reuse_proxy(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): + # url twice via https: proxy separated with '--next', will reuse + if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): + pytest.skip('only supported with nghttp2') + curl = CurlClient(env=env) + url = f'https://localhost:{env.https_port}/data.json' + proxy_args = curl.get_proxy_args(tunnel=True, proto=tunnel) + r1 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=proxy_args) + r1.check_response(count=1, http_status=200) + assert self.get_tunnel_proto_used(r1) == 'HTTP/2' \ + if tunnel == 'h2' else 'HTTP/1.1' + # get the args, duplicate separated with '--next' + x2_args = r1.args[1:] + x2_args.append('--next') + x2_args.extend(proxy_args) + r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=x2_args) + r2.check_response(count=2, http_status=200) + assert r2.total_connects == 1 + + @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") + @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) + @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") + @pytest.mark.skipif(condition=not Env.curl_uses_lib('openssl'), reason="tls13-ciphers not supported") + def test_10_11_noreuse_proxy_https(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): + # different --proxy-tls13-ciphers, no reuse of connection for https: + curl = CurlClient(env=env) + if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): + pytest.skip('only supported with nghttp2') + url = f'https://localhost:{env.https_port}/data.json' + proxy_args = curl.get_proxy_args(tunnel=True, proto=tunnel) + r1 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=proxy_args) + r1.check_response(count=1, http_status=200) + assert self.get_tunnel_proto_used(r1) == 'HTTP/2' \ + if tunnel == 'h2' else 'HTTP/1.1' + # get the args, duplicate separated with '--next' + x2_args = r1.args[1:] + x2_args.append('--next') + x2_args.extend(proxy_args) + x2_args.extend(['--proxy-tls13-ciphers', 'TLS_AES_128_GCM_SHA256']) + r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=x2_args) + r2.check_response(count=2, http_status=200) + assert r2.total_connects == 2 + + @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") + @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) + @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") + @pytest.mark.skipif(condition=not Env.curl_uses_lib('openssl'), reason="tls13-ciphers not supported") + def test_10_12_noreuse_proxy_http(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): + # different --proxy-tls13-ciphers, no reuse of connection for http: + if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): + pytest.skip('only supported with nghttp2') + curl = CurlClient(env=env) + url = f'http://localhost:{env.http_port}/data.json' + proxy_args = curl.get_proxy_args(tunnel=True, proto=tunnel) + r1 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=proxy_args) + r1.check_response(count=1, http_status=200) + assert self.get_tunnel_proto_used(r1) == 'HTTP/2' \ + if tunnel == 'h2' else 'HTTP/1.1' + # get the args, duplicate separated with '--next' + x2_args = r1.args[1:] + x2_args.append('--next') + x2_args.extend(proxy_args) + x2_args.extend(['--proxy-tls13-ciphers', 'TLS_AES_128_GCM_SHA256']) + r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=x2_args) + r2.check_response(count=2, http_status=200) + assert r2.total_connects == 2 + + @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason=f"curl without SSL") + @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) + @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") + @pytest.mark.skipif(condition=not Env.curl_uses_lib('openssl'), reason="tls13-ciphers not supported") + def test_10_13_noreuse_https(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): + # different --tls13-ciphers on https: same proxy config + if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): + pytest.skip('only supported with nghttp2') + curl = CurlClient(env=env) + url = f'https://localhost:{env.https_port}/data.json' + proxy_args = curl.get_proxy_args(tunnel=True, proto=tunnel) + r1 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=proxy_args) + r1.check_response(count=1, http_status=200) + assert self.get_tunnel_proto_used(r1) == 'HTTP/2' \ + if tunnel == 'h2' else 'HTTP/1.1' + # get the args, duplicate separated with '--next' + x2_args = r1.args[1:] + x2_args.append('--next') + x2_args.extend(proxy_args) + x2_args.extend(['--tls13-ciphers', 'TLS_AES_128_GCM_SHA256']) + r2 = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True, + extra_args=x2_args) + r2.check_response(count=2, http_status=200) + assert r2.total_connects == 2 diff --git a/tests/http/testenv/curl.py b/tests/http/testenv/curl.py index 9f92f629c..bc5b4881c 100644 --- a/tests/http/testenv/curl.py +++ b/tests/http/testenv/curl.py @@ -504,14 +504,20 @@ def _complete_args(self, urls, timeout=None, options=None, args = [self._curl, "-s", "--path-as-is"] if with_headers: args.extend(["-D", self._headerfile]) - if def_tracing is not False: - args.extend(['-v', '--trace-config', 'ids,time']) + if def_tracing is not False and not self._silent: + args.extend(['-v', '--trace-ids', '--trace-time']) if self.env.verbose > 1: args.extend(['--trace-config', 'http/2,http/3,h2-proxy,h1-proxy']) pass + active_options = options + if options is not None and '--next' in options: + active_options = options[options.index('--next') + 1:] + for url in urls: u = urlparse(urls[0]) + if options: + args.extend(options) if alpn_proto is not None: if alpn_proto not in self.ALPN_ARG: raise Exception(f'unknown ALPN protocol: "{alpn_proto}"') @@ -521,7 +527,7 @@ def _complete_args(self, urls, timeout=None, options=None, pass elif insecure: args.append('--insecure') - elif options and "--cacert" in options: + elif active_options and "--cacert" in active_options: pass elif u.hostname: args.extend(["--cacert", self.env.ca.cert_file]) @@ -532,8 +538,6 @@ def _complete_args(self, urls, timeout=None, options=None, args.extend(["--resolve", f"{u.hostname}:{port}:127.0.0.1"]) if timeout is not None and int(timeout) > 0: args.extend(["--connect-timeout", str(int(timeout))]) - if options: - args.extend(options) args.append(url) return args diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt index 98f5b9c67..b6450ff3a 100644 --- a/tests/libtest/CMakeLists.txt +++ b/tests/libtest/CMakeLists.txt @@ -67,7 +67,7 @@ endforeach() # Allows for hostname override to make tests machine independent. # TODO this cmake build assumes a shared build, detect static linking here! if(NOT WIN32) - add_library(hostname MODULE EXCLUDE_FROM_ALL sethostname.c sethostname.h) + add_library(hostname MODULE EXCLUDE_FROM_ALL sethostname.c) add_dependencies(testdeps hostname) # Output to .libs for compatibility with autotools, the test data expects a # library at (tests)/libtest/.libs/libhostname.so diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am index 09a13914a..8ae972a24 100644 --- a/tests/libtest/Makefile.am +++ b/tests/libtest/Makefile.am @@ -103,7 +103,7 @@ libhostname_la_CPPFLAGS = $(AM_CPPFLAGS) $(libhostname_la_CPPFLAGS_EXTRA) libhostname_la_LDFLAGS = $(AM_LDFLAGS) $(libhostname_la_LDFLAGS_EXTRA) libhostname_la_CFLAGS = $(AM_CFLAGS) $(libhostname_la_CFLAGS_EXTRA) -libhostname_la_SOURCES = sethostname.c sethostname.h +libhostname_la_SOURCES = sethostname.c libhostname_la_LIBADD = libhostname_la_DEPENDENCIES = diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 85801e002..c4d36a26b 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -58,13 +58,14 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect libprereq \ lib1518 lib1520 lib1521 lib1522 lib1523 \ lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 lib1532 lib1533 \ lib1534 lib1535 lib1536 lib1537 lib1538 lib1539 \ - lib1540 lib1542 lib1543 \ + lib1540 lib1542 lib1543 lib1545 \ lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \ lib1558 lib1559 lib1560 lib1564 lib1565 lib1567 lib1568 lib1569 \ lib1591 lib1592 lib1593 lib1594 lib1596 lib1597 \ \ lib1662 \ \ + lib1900 \ lib1903 lib1905 lib1906 lib1907 lib1908 lib1910 lib1911 lib1912 lib1913 \ lib1915 lib1916 lib1917 lib1918 lib1919 \ lib1933 lib1934 lib1935 lib1936 lib1937 lib1938 lib1939 lib1940 \ @@ -466,6 +467,9 @@ lib1542_LDADD = $(TESTUTIL_LIBS) lib1543_SOURCES = lib1518.c $(SUPPORTFILES) lib1543_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1543 +lib1545_SOURCES = lib1545.c $(SUPPORTFILES) +lib1545_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_DISABLE_DEPRECATION + lib1550_SOURCES = lib1550.c $(SUPPORTFILES) lib1551_SOURCES = lib1551.c $(SUPPORTFILES) @@ -530,6 +534,8 @@ lib1597_LDADD = $(TESTUTIL_LIBS) lib1662_SOURCES = lib1662.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1662_LDADD = $(TESTUTIL_LIBS) +lib1900_SOURCES = lib1900.c $(SUPPORTFILES) + lib1903_SOURCES = lib1903.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1903_LDADD = $(TESTUTIL_LIBS) diff --git a/tests/libtest/first.c b/tests/libtest/first.c index 7bd129ab3..6d1380688 100644 --- a/tests/libtest/first.c +++ b/tests/libtest/first.c @@ -174,7 +174,7 @@ int main(int argc, char **argv) result = test(URL); fprintf(stderr, "Test ended with result %d\n", result); -#ifdef WIN32 +#ifdef _WIN32 /* flush buffers of all streams regardless of mode */ _flushall(); #endif diff --git a/tests/libtest/lib1156.c b/tests/libtest/lib1156.c index aae2893ef..b512ef67a 100644 --- a/tests/libtest/lib1156.c +++ b/tests/libtest/lib1156.c @@ -68,7 +68,7 @@ static const struct testparams params[] = { { F_RESUME | F_HTTP416 | F_CONTENTRANGE | F_IGNOREBODY, CURLE_OK }, { F_RESUME | F_HTTP416 | F_FAIL | F_IGNOREBODY, CURLE_OK }, { F_RESUME | F_HTTP416 | F_FAIL | F_CONTENTRANGE | F_IGNOREBODY, - CURLE_HTTP_RETURNED_ERROR } + CURLE_OK } }; static int hasbody; diff --git a/tests/libtest/lib1517.c b/tests/libtest/lib1517.c index 706b5567c..126792017 100644 --- a/tests/libtest/lib1517.c +++ b/tests/libtest/lib1517.c @@ -61,7 +61,7 @@ int test(char *URL) struct WriteThis pooh; if(!strcmp(URL, "check")) { -#if (defined(WIN32) || defined(__CYGWIN__)) +#if (defined(_WIN32) || defined(__CYGWIN__)) printf("Windows TCP does not deliver response data but reports " "CONNABORTED\n"); return 1; /* skip since test will fail on Windows without workaround */ diff --git a/tests/libtest/lib1531.c b/tests/libtest/lib1531.c index 703400178..b64e16603 100644 --- a/tests/libtest/lib1531.c +++ b/tests/libtest/lib1531.c @@ -110,7 +110,7 @@ int test(char *URL) curl_multi_fdset() doc. */ if(maxfd == -1) { -#if defined(WIN32) || defined(_WIN32) +#if defined(_WIN32) Sleep(100); rc = 0; #else diff --git a/tests/libtest/lib1545.c b/tests/libtest/lib1545.c new file mode 100644 index 000000000..f31baa0c4 --- /dev/null +++ b/tests/libtest/lib1545.c @@ -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 + * + ***************************************************************************/ +#ifndef CURL_DISABLE_DEPRECATION +#define CURL_DISABLE_DEPRECATION /* Using and testing the form api */ +#endif +#include "test.h" + +int test(char *URL) +{ + CURL *eh = NULL; + int res = 0; + struct curl_httppost *lastptr = NULL; + struct curl_httppost *m_formpost = NULL; + + global_init(CURL_GLOBAL_ALL); + + easy_init(eh); + + easy_setopt(eh, CURLOPT_URL, URL); + curl_formadd(&m_formpost, &lastptr, CURLFORM_COPYNAME, "file", + CURLFORM_FILE, "missing-file", CURLFORM_END); + curl_easy_setopt(eh, CURLOPT_HTTPPOST, m_formpost); + + (void)curl_easy_perform(eh); + (void)curl_easy_perform(eh); + +test_cleanup: + + curl_formfree(m_formpost); + + curl_easy_cleanup(eh); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c index 765df0a27..87420a330 100644 --- a/tests/libtest/lib1560.c +++ b/tests/libtest/lib1560.c @@ -151,6 +151,9 @@ struct clearurlcase { }; static const struct testcase get_parts_list[] ={ + {"https://curl.se/# ", + "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | %20%20", + CURLU_URLENCODE|CURLU_ALLOW_SPACE, 0, CURLUE_OK}, {"", "", 0, 0, CURLUE_MALFORMED_INPUT}, {" ", "", 0, 0, CURLUE_MALFORMED_INPUT}, {"1h://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, @@ -316,7 +319,7 @@ static const struct testcase get_parts_list[] ={ "http | ftp.user | moo | [13] | example.com | [15] | /color/ | [16] | " "green?no-red", CURLU_GUESS_SCHEME, 0, CURLUE_OK }, -#ifdef WIN32 +#ifdef _WIN32 {"file:/C:\\programs\\foo", "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, @@ -785,6 +788,18 @@ static const struct setgetcase setget_parts_list[] = { /* !checksrc! disable SPACEBEFORECOMMA 1 */ static const struct setcase set_parts_list[] = { + {"https://example.com/?param=value", + "query=\"\",", + "https://example.com/", + 0, CURLU_APPENDQUERY | CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, + {"https://example.com/", + "host=\"\",", + "https://example.com/", + 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_BAD_HOSTNAME}, + {"https://example.com/", + "host=\"\",", + "https://example.com/", + 0, 0, CURLUE_OK, CURLUE_BAD_HOSTNAME}, {"https://example.com", "path=get,", "https://example.com/get", diff --git a/tests/libtest/lib1900.c b/tests/libtest/lib1900.c new file mode 100644 index 000000000..92f89c4c4 --- /dev/null +++ b/tests/libtest/lib1900.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "test.h" + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +int test(char *URL) +{ + CURLcode res = CURLE_OK; + CURL *hnd = NULL; + CURL *second = NULL; + + global_init(CURL_GLOBAL_ALL); + + easy_init(hnd); + easy_setopt(hnd, CURLOPT_URL, URL); + easy_setopt(hnd, CURLOPT_HSTS, "first-hsts.txt"); + easy_setopt(hnd, CURLOPT_HSTS, "second-hsts.txt"); + + second = curl_easy_duphandle(hnd); + + curl_easy_cleanup(hnd); + curl_easy_cleanup(second); + curl_global_cleanup(); + return 0; + +test_cleanup: + curl_easy_cleanup(hnd); + curl_easy_cleanup(second); + curl_global_cleanup(); + return (int)res; +} diff --git a/tests/libtest/lib1960.c b/tests/libtest/lib1960.c index fc2f4b0af..b01370e6e 100644 --- a/tests/libtest/lib1960.c +++ b/tests/libtest/lib1960.c @@ -25,7 +25,7 @@ #ifdef HAVE_INET_PTON -#ifdef WIN32 +#ifdef _WIN32 #include #include #include diff --git a/tests/libtest/lib2305.c b/tests/libtest/lib2305.c index 0778e0b58..374423f0f 100644 --- a/tests/libtest/lib2305.c +++ b/tests/libtest/lib2305.c @@ -71,8 +71,6 @@ static void websocket(CURL *curl) websocket_close(curl); } -extern struct libtest_trace_cfg libtest_debug_config; - int test(char *URL) { CURL *curl; diff --git a/tests/libtest/lib3026.c b/tests/libtest/lib3026.c index 42b44c890..34dcafc50 100644 --- a/tests/libtest/lib3026.c +++ b/tests/libtest/lib3026.c @@ -28,7 +28,7 @@ #define NUM_THREADS 100 -#ifdef WIN32 +#ifdef _WIN32 #ifdef _WIN32_WCE static DWORD WINAPI run_thread(LPVOID ptr) #else diff --git a/tests/libtest/lib518.c b/tests/libtest/lib518.c index 87b6f2d88..e61d80a6f 100644 --- a/tests/libtest/lib518.c +++ b/tests/libtest/lib518.c @@ -42,7 +42,7 @@ #define NUM_OPEN (FD_SETSIZE + 10) #define NUM_NEEDED (NUM_OPEN + SAFETY_MARGIN) -#if defined(WIN32) || defined(_WIN32) || defined(MSDOS) +#if defined(_WIN32) || defined(MSDOS) #define DEV_NULL "NUL" #else #define DEV_NULL "/dev/null" diff --git a/tests/libtest/lib537.c b/tests/libtest/lib537.c index 3782282b8..8735947cf 100644 --- a/tests/libtest/lib537.c +++ b/tests/libtest/lib537.c @@ -42,7 +42,7 @@ #define SAFETY_MARGIN (11) -#if defined(WIN32) || defined(_WIN32) || defined(MSDOS) +#if defined(_WIN32) || defined(MSDOS) #define DEV_NULL "NUL" #else #define DEV_NULL "/dev/null" diff --git a/tests/libtest/lib544.c b/tests/libtest/lib544.c index 192bfb2e7..a58fa05e3 100644 --- a/tests/libtest/lib544.c +++ b/tests/libtest/lib544.c @@ -63,7 +63,6 @@ int test(char *URL) /* Update the original data to detect non-copy. */ strcpy(teststring, "FAIL"); -#ifdef LIB545 { CURL *handle2; handle2 = curl_easy_duphandle(curl); @@ -71,7 +70,6 @@ int test(char *URL) curl = handle2; } -#endif /* Now, this is a POST request with binary 0 embedded in POST data. */ res = curl_easy_perform(curl); diff --git a/tests/libtest/lib670.c b/tests/libtest/lib670.c index 700b908cf..b348343c2 100644 --- a/tests/libtest/lib670.c +++ b/tests/libtest/lib670.c @@ -215,7 +215,7 @@ int test(char *URL) mres = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcept, &maxfd); if(mres) break; -#if defined(WIN32) || defined(_WIN32) +#if defined(_WIN32) if(maxfd == -1) Sleep(100); else diff --git a/tests/libtest/sethostname.c b/tests/libtest/sethostname.c index 9dcad976c..1e07d26bc 100644 --- a/tests/libtest/sethostname.c +++ b/tests/libtest/sethostname.c @@ -23,8 +23,6 @@ ***************************************************************************/ #include "curl_setup.h" -#include "sethostname.h" - /* * we force our own host name, in order to make some tests machine independent */ diff --git a/tests/libtest/stub_gssapi.c b/tests/libtest/stub_gssapi.c index 634dddfd0..85c760c2d 100644 --- a/tests/libtest/stub_gssapi.c +++ b/tests/libtest/stub_gssapi.c @@ -183,7 +183,7 @@ OM_uint32 gss_init_sec_context(OM_uint32 *min, return GSS_S_FAILURE; } - ctx = (gss_ctx_id_t) calloc(sizeof(*ctx), 1); + ctx = (gss_ctx_id_t) calloc(1, sizeof(*ctx)); if(!ctx) { *min = GSS_NO_MEMORY; return GSS_S_FAILURE; diff --git a/tests/libtest/test.h b/tests/libtest/test.h index 7eb7fdaa2..7f29db117 100644 --- a/tests/libtest/test.h +++ b/tests/libtest/test.h @@ -42,7 +42,7 @@ #include "curl_printf.h" -#ifdef WIN32 +#ifdef _WIN32 #define sleep(sec) Sleep ((sec)*1000) #endif diff --git a/tests/libtest/test613.pl b/tests/libtest/test613.pl index 3ad7805af..dee3b1754 100644 --- a/tests/libtest/test613.pl +++ b/tests/libtest/test613.pl @@ -81,7 +81,7 @@ sub errout { rmdir $dirname || die "$!"; - if ($logfile) { + if ($logfile && -s $logfile) { # Process the directory file to remove all information that # could be inconsistent from one test run to the next (e.g. # file date) or may be unsupported on some platforms (e.g. diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c index 1a1e689e7..4a3cd944a 100644 --- a/tests/libtest/testutil.c +++ b/tests/libtest/testutil.c @@ -26,7 +26,7 @@ #include "testutil.h" #include "memdebug.h" -#if defined(WIN32) && !defined(MSDOS) +#if defined(_WIN32) struct timeval tutil_tvnow(void) { @@ -130,7 +130,7 @@ double tutil_tvdiff_secs(struct timeval newer, struct timeval older) return (double)(newer.tv_usec-older.tv_usec)/1000000.0; } -#ifdef WIN32 +#ifdef _WIN32 HMODULE win32_load_system_library(const TCHAR *filename) { size_t filenamelen = _tcslen(filename); diff --git a/tests/libtest/testutil.h b/tests/libtest/testutil.h index 36b944834..9f063795a 100644 --- a/tests/libtest/testutil.h +++ b/tests/libtest/testutil.h @@ -42,7 +42,7 @@ long tutil_tvdiff(struct timeval t1, struct timeval t2); */ double tutil_tvdiff_secs(struct timeval t1, struct timeval t2); -#ifdef WIN32 +#ifdef _WIN32 HMODULE win32_load_system_library(const TCHAR *filename); #endif diff --git a/tests/pathhelp.pm b/tests/pathhelp.pm index 7d924b862..3afc5dacb 100644 --- a/tests/pathhelp.pm +++ b/tests/pathhelp.pm @@ -789,6 +789,7 @@ sub exe_ext { $^O eq 'dos' || $^O eq 'os2') { return '.exe'; } + return ''; } 1; # End of module diff --git a/tests/runtests.1 b/tests/runtests.1 index 59167c515..6ea656d98 100644 --- a/tests/runtests.1 +++ b/tests/runtests.1 @@ -54,6 +54,35 @@ this keyword. Remember that the exclamation marks and spaces will need to be quoted somehow when entered at many command shells. Prefix a keyword with a tilde (~) to still run it, but ignore the results. + +.SH "OUTPUT" + +When running without -s (short output), for instance when running runtests.pl +directly rather than via make, each test will emits a pair of lines like this: + +Test 0045...[simple HTTP Location: without protocol in initial URL] +--pd---e-v- OK (45 out of 1427, remaining: 16:08, took 6.188s, duration: 00:31) + +the first line contains the test number and a description. On the second line, +the characters at the beginning are flags indicating which aspects of curl's +behavior were checked by the test: + + s stdout + r stderr + p protocol + d data + u upload + P proxy + o output + e exit code + m memory + v valgrind + E the test was run event-based + +The remainder of the second line contains the test result, current test sequence, +total number of tests to be run and an estimated amount of time to complete the +test run. + .SH OPTIONS .IP "-a" Continue running the rest of the test cases even if one test fails. By @@ -92,9 +121,6 @@ start. Run the given test(s) with gdb as a windowed application. .IP "-h, --help" Displays a help text about this program's command line options. -.IP "-k" -Keep output and log files in log/ after a test run, even if no error was -detected. Useful for debugging. .IP "-j[num]" Spawn num processes to run tests. This defaults to 0 to run tests serially within a single process. Using a number greater than one allows multiple tests @@ -102,6 +128,9 @@ to run in parallel, speeding up a test run. The optimum number is dependent on the system and set of tests to run, but 7*number of CPU cores is a good figure to start with, or 1.3*number of CPU cores if Valgrind is in use. Enabling parallel tests is not recommended in conjunction with the \-g option. +.IP "-k" +Keep output and log files in log/ after a test run, even if no error was +detected. Useful for debugging. .IP "-L " Load and execute the specified file which should contain perl code. This option allows one to change \fIruntests.pl\fP behaviour by overwriting diff --git a/tests/runtests.pl b/tests/runtests.pl index 32e068037..e7b9f01f6 100644 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -23,6 +23,8 @@ # ########################################################################### +# For documentation, run `man ./runtests.1` and see README.md. + # Experimental hooks are available to run tests remotely on machines that # are able to run curl but are unable to run the test harness. # The following sections need to be modified: @@ -1503,7 +1505,7 @@ sub singletest_check { } else { - $ok .= "-"; # protocol not checked + $ok .= "-"; # proxy not checked } my $outputok; diff --git a/tests/server/getpart.c b/tests/server/getpart.c index 7d3bff75a..9ab9e88d5 100644 --- a/tests/server/getpart.c +++ b/tests/server/getpart.c @@ -60,7 +60,7 @@ 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) +#if defined(_WIN32) && defined(UNICODE) curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; #endif @@ -149,7 +149,7 @@ static int readline(char **buffer, size_t *bufsize, size_t *length, char *newptr; if(!*buffer) { - *buffer = calloc(128, 1); + *buffer = calloc(1, 128); if(!*buffer) return GPE_OUT_OF_MEMORY; *bufsize = 128; diff --git a/tests/server/mqttd.c b/tests/server/mqttd.c index 55ef02cdb..8a0da3ee6 100644 --- a/tests/server/mqttd.c +++ b/tests/server/mqttd.c @@ -98,7 +98,6 @@ #define MQTT_CONNACK_LEN 4 #define MQTT_SUBACK_LEN 5 #define MQTT_CLIENTID_LEN 12 /* "curl0123abcd" */ -#define MQTT_HEADER_LEN 5 /* max 5 bytes */ struct configurable { unsigned char version; /* initial version byte in the request must match @@ -1017,7 +1016,7 @@ int main(int argc, char *argv[]) msnprintf(loglockfile, sizeof(loglockfile), "%s/%s/mqtt-%s.lock", logdir, SERVERLOGS_LOCKDIR, ipv_inuse); -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); diff --git a/tests/server/resolve.c b/tests/server/resolve.c index 221df64b0..8ae31bc59 100644 --- a/tests/server/resolve.c +++ b/tests/server/resolve.c @@ -102,7 +102,7 @@ int main(int argc, char *argv[]) return 1; } -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); #endif diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c index dbe8a48b0..9c01ce871 100644 --- a/tests/server/rtspd.c +++ b/tests/server/rtspd.c @@ -1150,7 +1150,7 @@ int main(int argc, char *argv[]) msnprintf(loglockfile, sizeof(loglockfile), "%s/%s/rtsp-%s.lock", logdir, SERVERLOGS_LOCKDIR, ipv_inuse); -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); #endif diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c index 7e342e330..f87d1c8f9 100644 --- a/tests/server/sockfilt.c +++ b/tests/server/sockfilt.c @@ -152,7 +152,7 @@ enum sockmode { ACTIVE_DISCONNECT /* as a client, disconnected from server */ }; -#ifdef WIN32 +#ifdef _WIN32 /* * read-wrapper to support reading from stdin on Windows. */ @@ -1461,7 +1461,7 @@ int main(int argc, char *argv[]) } } -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); diff --git a/tests/server/socksd.c b/tests/server/socksd.c index cf9a14fd8..490085d49 100644 --- a/tests/server/socksd.c +++ b/tests/server/socksd.c @@ -379,6 +379,10 @@ static curl_socket_t sockit(curl_socket_t fd) getconfig(); rc = recv(fd, (char *)buffer, sizeof(buffer), 0); + if(rc <= 0) { + logmsg("SOCKS identifier message missing, recv returned %d", rc); + return CURL_SOCKET_BAD; + } logmsg("READ %d bytes", rc); loghex(buffer, rc); @@ -386,6 +390,11 @@ static curl_socket_t sockit(curl_socket_t fd) if(buffer[SOCKS5_VERSION] == 4) return socks4(fd, buffer, rc); + if(rc < 3) { + logmsg("SOCKS5 identifier message too short: %d", rc); + return CURL_SOCKET_BAD; + } + if(buffer[SOCKS5_VERSION] != config.version) { logmsg("VERSION byte not %d", config.version); return CURL_SOCKET_BAD; @@ -417,6 +426,10 @@ static curl_socket_t sockit(curl_socket_t fd) /* expect the request or auth */ rc = recv(fd, (char *)buffer, sizeof(buffer), 0); + if(rc <= 0) { + logmsg("SOCKS5 request or auth message missing, recv returned %d", rc); + return CURL_SOCKET_BAD; + } logmsg("READ %d bytes", rc); loghex(buffer, rc); @@ -472,6 +485,10 @@ static curl_socket_t sockit(curl_socket_t fd) /* expect the request */ rc = recv(fd, (char *)buffer, sizeof(buffer), 0); + if(rc <= 0) { + logmsg("SOCKS5 request message missing, recv returned %d", rc); + return CURL_SOCKET_BAD; + } logmsg("READ %d bytes", rc); loghex(buffer, rc); @@ -1059,7 +1076,7 @@ int main(int argc, char *argv[]) } } -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); diff --git a/tests/server/sws.c b/tests/server/sws.c index bea3191a2..fa9b1ac80 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -2119,7 +2119,7 @@ int main(int argc, char *argv[]) logdir, SERVERLOGS_LOCKDIR, protocol_type, is_proxy ? "-proxy" : "", socket_type); -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); #endif diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c index 670897c0d..9f93f4c6b 100644 --- a/tests/server/tftpd.c +++ b/tests/server/tftpd.c @@ -453,7 +453,7 @@ static ssize_t write_behind(struct testcase *test, int convert) if(!test->ofile) { char outfile[256]; msnprintf(outfile, sizeof(outfile), "%s/upload.%ld", logdir, test->testno); -#ifdef WIN32 +#ifdef _WIN32 test->ofile = open(outfile, O_CREAT|O_RDWR|O_BINARY, 0777); #else test->ofile = open(outfile, O_CREAT|O_RDWR, 0777); @@ -642,7 +642,7 @@ int main(int argc, char **argv) msnprintf(loglockfile, sizeof(loglockfile), "%s/%s/tftp-%s.lock", logdir, SERVERLOGS_LOCKDIR, ipv_inuse); -#ifdef WIN32 +#ifdef _WIN32 win32_init(); atexit(win32_cleanup); #endif diff --git a/tests/server/util.c b/tests/server/util.c index 19faa2615..5cfdab269 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -144,7 +144,7 @@ void logmsg(const char *msg, ...) } } -#ifdef WIN32 +#ifdef _WIN32 /* use instead of strerror() on generic Windows */ static const char *win32_strerror(int err, char *buf, size_t buflen) { @@ -208,7 +208,7 @@ const char *sstrerror(int err) static char buf[512]; return win32_strerror(err, buf, sizeof(buf)); } -#endif /* WIN32 */ +#endif /* _WIN32 */ /* set by the main code to point to where the test dir is */ const char *path = "."; @@ -292,7 +292,7 @@ curl_off_t our_getpid(void) curl_off_t pid; pid = (curl_off_t)getpid(); -#if defined(WIN32) || defined(_WIN32) +#if defined(_WIN32) || defined(_WIN32) /* store pid + 65536 to avoid conflict with Cygwin/msys PIDs, see also: * - https://cygwin.com/git/?p=newlib-cygwin.git;a=commit; ↵ * h=b5e1003722cb14235c4f166be72c09acdffc62ea @@ -378,7 +378,7 @@ void clear_advisor_read_lock(const char *filename) } -#if defined(WIN32) && !defined(MSDOS) +#if defined(_WIN32) && !defined(MSDOS) static struct timeval tvnow(void) { @@ -501,11 +501,11 @@ static SIGHANDLER_T old_sigint_handler = SIG_ERR; static SIGHANDLER_T old_sigterm_handler = SIG_ERR; #endif -#if defined(SIGBREAK) && defined(WIN32) +#if defined(SIGBREAK) && defined(_WIN32) static SIGHANDLER_T old_sigbreak_handler = SIG_ERR; #endif -#ifdef WIN32 +#ifdef _WIN32 #ifdef _WIN32_WCE static DWORD thread_main_id = 0; #else @@ -521,7 +521,7 @@ 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 +#ifdef _WIN32 /* event which if set indicates that the program should finish */ HANDLE exit_event = NULL; #endif @@ -538,7 +538,7 @@ static void exit_signal_handler(int signum) if(got_exit_signal == 0) { got_exit_signal = 1; exit_signal = signum; -#ifdef WIN32 +#ifdef _WIN32 if(exit_event) (void)SetEvent(exit_event); #endif @@ -547,7 +547,7 @@ static void exit_signal_handler(int signum) errno = old_errno; } -#ifdef WIN32 +#ifdef _WIN32 /* CTRL event handler for Windows Console applications to simulate * SIGINT, SIGTERM and SIGBREAK on CTRL events and trigger signal handler. * @@ -698,7 +698,7 @@ static SIGHANDLER_T set_signal(int signum, SIGHANDLER_T handler, void install_signal_handlers(bool keep_sigalrm) { -#ifdef WIN32 +#ifdef _WIN32 #ifdef _WIN32_WCE typedef HANDLE curl_win_thread_handle_t; #else @@ -744,13 +744,13 @@ void install_signal_handlers(bool keep_sigalrm) if(old_sigterm_handler == SIG_ERR) logmsg("cannot install SIGTERM handler: %s", strerror(errno)); #endif -#if defined(SIGBREAK) && defined(WIN32) +#if defined(SIGBREAK) && defined(_WIN32) /* handle SIGBREAK signal with our exit_signal_handler */ old_sigbreak_handler = set_signal(SIGBREAK, exit_signal_handler, TRUE); if(old_sigbreak_handler == SIG_ERR) logmsg("cannot install SIGBREAK handler: %s", strerror(errno)); #endif -#ifdef WIN32 +#ifdef _WIN32 if(!SetConsoleCtrlHandler(ctrl_event_handler, TRUE)) logmsg("cannot install CTRL event handler"); #ifdef _WIN32_WCE @@ -792,11 +792,11 @@ void restore_signal_handlers(bool keep_sigalrm) if(SIG_ERR != old_sigterm_handler) (void) set_signal(SIGTERM, old_sigterm_handler, FALSE); #endif -#if defined(SIGBREAK) && defined(WIN32) +#if defined(SIGBREAK) && defined(_WIN32) if(SIG_ERR != old_sigbreak_handler) (void) set_signal(SIGBREAK, old_sigbreak_handler, FALSE); #endif -#ifdef WIN32 +#ifdef _WIN32 (void)SetConsoleCtrlHandler(ctrl_event_handler, FALSE); if(thread_main_window && thread_main_id) { if(PostThreadMessage(thread_main_id, WM_APP, 0, 0)) { @@ -846,7 +846,7 @@ int bind_unix_socket(curl_socket_t sock, const char *unix_socket, return rc; } /* socket server is not alive, now check if it was actually a socket. */ -#ifdef WIN32 +#ifdef _WIN32 /* Windows does not have lstat function. */ rc = curlx_win32_stat(unix_socket, &statbuf); #else diff --git a/tests/server/util.h b/tests/server/util.h index a12f4dbf0..4dff40e81 100644 --- a/tests/server/util.h +++ b/tests/server/util.h @@ -41,7 +41,7 @@ extern const char *serverlogfile; extern const char *cmdfile; -#ifdef WIN32 +#ifdef _WIN32 #include #include @@ -54,10 +54,10 @@ void win32_perror(const char *msg); void win32_init(void); void win32_cleanup(void); const char *sstrerror(int err); -#else /* WIN32 */ +#else /* _WIN32 */ #define sstrerror(e) strerror(e) -#endif /* WIN32 */ +#endif /* _WIN32 */ /* fopens the test case file */ FILE *test2fopen(long testno, const char *logdir); @@ -68,7 +68,6 @@ int write_pidfile(const char *filename); int write_portfile(const char *filename, int port); void set_advisor_read_lock(const char *filename); void clear_advisor_read_lock(const char *filename); -int strncasecompare(const char *first, const char *second, size_t max); /* global variable which if set indicates that the program should finish */ extern volatile int got_exit_signal; @@ -76,7 +75,7 @@ extern volatile int got_exit_signal; /* global variable which if set indicates the first signal handled */ extern volatile int exit_signal; -#ifdef WIN32 +#ifdef _WIN32 /* global event which if set indicates that the program should finish */ extern HANDLE exit_event; #endif diff --git a/tests/servers.pm b/tests/servers.pm index 4f67432c6..9416ba758 100644 --- a/tests/servers.pm +++ b/tests/servers.pm @@ -153,10 +153,15 @@ our $stunnel; # path to stunnel command # sub checkcmd { my ($cmd, @extrapaths)=@_; - my @paths=(split(m/[:]/, $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin", + my $sep = '[:]'; + if ($^O eq 'MSWin32' || $^O eq 'dos' || $^O eq 'os2') { + # PATH separator is different + $sep = '[;]'; + } + my @paths=(split(m/$sep/, $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin", "/sbin", "/usr/bin", "/usr/local/bin", @extrapaths); for(@paths) { - if( -x "$_/$cmd" && ! -d "$_/$cmd") { + if( -x "$_/$cmd" . exe_ext('SYS') && ! -d "$_/$cmd" . exe_ext('SYS')) { # executable bit but not a directory! return "$_/$cmd"; } @@ -264,19 +269,22 @@ sub clearlocks { if(os_is_win()) { $dir = sys_native_abs_path($dir); $dir =~ s/\//\\\\/g; - my $handle = "handle.exe"; + my $handle = "handle"; if($ENV{"PROCESSOR_ARCHITECTURE"} =~ /64$/) { - $handle = "handle64.exe"; + $handle = "handle64"; } - my @handles = `$handle $dir -accepteula -nobanner`; - for my $tryhandle (@handles) { - if($tryhandle =~ /^(\S+)\s+pid:\s+(\d+)\s+type:\s+(\w+)\s+([0-9A-F]+):\s+(.+)\r\r/) { - logmsg "Found $3 lock of '$5' ($4) by $1 ($2)\n"; - # Ignore stunnel since we cannot do anything about its locks - if("$3" eq "File" && "$1" ne "tstunnel.exe") { - logmsg "Killing IMAGENAME eq $1 and PID eq $2\n"; - system("taskkill.exe -f -fi \"IMAGENAME eq $1\" -fi \"PID eq $2\" >nul 2>&1"); - $done = 1; + if(checkcmd($handle)) { + my @handles = `$handle $dir -accepteula -nobanner`; + for my $tryhandle (@handles) { + # Skip the "No matching handles found." warning when returned + if($tryhandle =~ /^(\S+)\s+pid:\s+(\d+)\s+type:\s+(\w+)\s+([0-9A-F]+):\s+(.+)\r\r/) { + logmsg "Found $3 lock of '$5' ($4) by $1 ($2)\n"; + # Ignore stunnel since we cannot do anything about its locks + if("$3" eq "File" && "$1" ne "tstunnel.exe") { + logmsg "Killing IMAGENAME eq $1 and PID eq $2\n"; + system("taskkill.exe -f -fi \"IMAGENAME eq $1\" -fi \"PID eq $2\" >nul 2>&1"); + $done = 1; + } } } } diff --git a/tests/unit/curlcheck.h b/tests/unit/curlcheck.h index 756f76e36..928964422 100644 --- a/tests/unit/curlcheck.h +++ b/tests/unit/curlcheck.h @@ -93,8 +93,6 @@ } while(0) -extern int unitfail; - #define UNITTEST_START \ int test(char *arg) \ { \ diff --git a/tests/unit/unit1394.c b/tests/unit/unit1394.c index e4e998184..ef398ab22 100644 --- a/tests/unit/unit1394.c +++ b/tests/unit/unit1394.c @@ -61,7 +61,7 @@ UNITTEST_START "pkcs11:foobar", "pkcs11:foobar", NULL, "PKCS11:foobar", "PKCS11:foobar", NULL, "PkCs11:foobar", "PkCs11:foobar", NULL, -#ifdef WIN32 +#ifdef _WIN32 "c:\\foo:bar:baz", "c:\\foo", "bar:baz", "c:\\foo\\:bar:baz", "c:\\foo:bar", "baz", "c:\\foo\\\\:bar:baz", "c:\\foo\\", "bar:baz", diff --git a/tests/unit/unit1395.c b/tests/unit/unit1395.c index d01403f33..017b45a0e 100644 --- a/tests/unit/unit1395.c +++ b/tests/unit/unit1395.c @@ -83,15 +83,17 @@ UNITTEST_START abort_unless(err == 0, "returned error"); abort_if(err && out, "returned error with output"); - if(out && strcmp(out, pairs[i].output)) { + if(out && pairs[i].output && strcmp(out, pairs[i].output)) { fprintf(stderr, "Test %u: '%s' gave '%s' instead of '%s'\n", i, pairs[i].input, out, pairs[i].output); fail("Test case output mismatched"); fails++; } - else if(!out && pairs[i].output) { - fprintf(stderr, "Test %u: '%s' gave '%s' instead of NULL\n", - i, pairs[i].input, out); + else if((!out && pairs[i].output) || + (out && !pairs[i].output)) { + fprintf(stderr, "Test %u: '%s' gave '%s' instead of '%s'\n", + i, pairs[i].input, out ? out : "(null)", + pairs[i].output ? pairs[i].output : "(null)"); fail("Test case output mismatched"); fails++; } diff --git a/tests/unit/unit1604.c b/tests/unit/unit1604.c index 411b94a02..cba3dfcf6 100644 --- a/tests/unit/unit1604.c +++ b/tests/unit/unit1604.c @@ -42,7 +42,7 @@ static void unit_stop(void) } -#if defined(MSDOS) || defined(WIN32) +#if defined(_WIN32) || defined(MSDOS) static char *getflagstr(int flags) { @@ -353,6 +353,6 @@ UNITTEST_START { fprintf(stderr, "Skipped test not for this platform\n"); } -#endif /* MSDOS || WIN32 */ +#endif /* _WIN32 || MSDOS */ UNITTEST_STOP diff --git a/tests/unit/unit2600.c b/tests/unit/unit2600.c index d7b1efdd7..a2089b275 100644 --- a/tests/unit/unit2600.c +++ b/tests/unit/unit2600.c @@ -124,7 +124,7 @@ static void cf_test_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) struct cf_test_ctx *ctx = cf->ctx; #ifndef CURL_DISABLE_VERBOSE_STRINGS infof(data, "%04dms: cf[%s] destroyed", - (int)Curl_timediff(Curl_now(), current_tr->started), ctx->id); + (int)Curl_timediff(Curl_now(), current_tr->started), ctx->id); #else (void)data; #endif @@ -145,7 +145,7 @@ static CURLcode cf_test_connect(struct Curl_cfilter *cf, duration_ms = Curl_timediff(Curl_now(), ctx->started); if(duration_ms >= ctx->fail_delay_ms) { infof(data, "%04dms: cf[%s] fail delay reached", - (int)duration_ms, ctx->id); + (int)duration_ms, ctx->id); return CURLE_COULDNT_CONNECT; } if(duration_ms) @@ -162,7 +162,7 @@ static struct Curl_cftype cft_test = { cf_test_connect, Curl_cf_def_close, Curl_cf_def_get_host, - Curl_cf_def_get_select_socks, + Curl_cf_def_adjust_pollset, Curl_cf_def_data_pending, Curl_cf_def_send, Curl_cf_def_recv, @@ -185,7 +185,7 @@ static CURLcode cf_test_create(struct Curl_cfilter **pcf, (void)data; (void)conn; - ctx = calloc(sizeof(*ctx), 1); + ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; goto out; diff --git a/tests/unit/unit3200.c b/tests/unit/unit3200.c index eff566772..0544bcc93 100644 --- a/tests/unit/unit3200.c +++ b/tests/unit/unit3200.c @@ -47,6 +47,7 @@ static CURLcode unit_stop(void) } #ifdef __GNUC__ +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Woverlength-strings" #endif @@ -161,6 +162,10 @@ UNITTEST_START } UNITTEST_STOP +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #else static CURLcode unit_setup(void) {