Compare commits

..

1 Commits

Author SHA1 Message Date
Daniel Stenberg
7cfd58457e
GHA: re-introduce CodeQL
This mostly reverts commit 173805b2e7.

Add "queries: security-and-quality" which should make a difference
compared to before.
2025-02-22 15:15:10 +01:00
166 changed files with 2563 additions and 3269 deletions

View File

@ -3,117 +3,55 @@
#
# SPDX-License-Identifier: curl
#
# Input: cmdline docs markdown files, they get modified *in place*
#
# Strip off the leading meta-data/header part, remove all known curl symbols
# and long command line options. Also clean up whatever else the spell checker
# might have a problem with that we still deem is fine.
# Input: a cmdline docs markdown, it gets modified *in place*
#
# The main purpose is to strip off the leading meta-data part, but also to
# clean up whatever else the spell checker might have a problem with that we
# still deem is fine.
open(S, "<./docs/libcurl/symbols-in-versions")
|| die "can't find symbols-in-versions";
while(<S>) {
if(/^([^ ]*) /) {
push @asyms, $1;
my $header = 1;
while(1) {
# set this if the markdown has no meta-data header to skip
if($ARGV[0] eq "--no-header") {
shift @ARGV;
$header = 0;
}
else {
last;
}
}
close(S);
# init the opts table with "special" options not easy to figure out
my @aopts = (
'--ftp-ssl-reqd', # old alias
);
my $f = $ARGV[0];
open(O, "<./docs/options-in-versions")
|| die "can't find options-in-versions";
while(<O>) {
chomp;
if(/^([^ ]+)/) {
my $o = $1;
push @aopts, $o;
if($o =~ /^--no-(.*)/) {
# for the --no options, also make one without it
push @aopts, "--$1";
}
elsif($o =~ /^--disable-(.*)/) {
# for the --disable options, also make the special ones
push @aopts, "--$1";
push @aopts, "--no-$1";
}
}
}
close(O);
open(F, "<$f") or die;
open(C, "<./.github/scripts/spellcheck.curl")
|| die "can't find spellcheck.curl";
while(<C>) {
if(/^\#/) {
next;
}
chomp;
if(/^([^ ]+)/) {
push @asyms, $1;
}
}
close(C);
# longest symbols first
my @syms = sort { length($b) <=> length($a) } @asyms;
# longest cmdline options first
my @opts = sort { length($b) <=> length($a) } @aopts;
sub process {
my ($f) = @_;
my $ignore = 0;
my $sepcount = 0;
my $out;
my $line = 0;
open(F, "<$f") or die;
while(<F>) {
$line++;
if(/^---/ && ($line == 1)) {
$ignore = 1;
next;
}
elsif(/^---/ && $ignore) {
my $ignore = $header;
my $sepcount = 0;
my @out;
while(<F>) {
if(/^---/ && $header) {
if(++$sepcount == 2) {
$ignore = 0;
}
next;
}
next if($ignore);
my $l = $_;
# strip out backticked words
$l =~ s/`[^`]+`//g;
$_ =~ s/`[^`]+`//g;
# **bold**
$l =~ s/\*\*(\S.*?)\*\*//g;
# *italics*
$l =~ s/\*(\S.*?)\*//g;
# strip out all long command line options
$_ =~ s/--[a-z0-9-]+//g;
# strip out https URLs, we don't want them spellchecked
$l =~ s!https://[a-z0-9\#_/.-]+!!gi;
$_ =~ s!https://[a-z0-9\#_/.-]+!!gi;
$out .= $l;
}
close(F);
push @out, $_;
}
close(F);
# cut out all known curl cmdline options
map { $out =~ s/$_//g; } (@opts);
# cut out all known curl symbols
map { $out =~ s/\b$_\b//g; } (@syms);
if(!$ignore) {
if(!$ignore) {
open(O, ">$f") or die;
print O $out;
print O @out;
close(O);
}
}
for my $f (@ARGV) {
process($f);
}

86
.github/scripts/cleanspell.pl vendored Executable file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env perl
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# Given: a libcurl curldown man page
# Outputs: the same file, minus the SYNOPSIS and the EXAMPLE sections
#
my $f = $ARGV[0];
open(F, "<$f") or die;
my @out;
my $ignore = 0;
while(<F>) {
if($_ =~ /^# (SYNOPSIS|EXAMPLE)/) {
$ignore = 1;
}
elsif($ignore && ($_ =~ /^# [A-Z]/)) {
$ignore = 0;
}
elsif(!$ignore) {
# **bold**
$_ =~ s/\*\*(\S.*?)\*\*//g;
# *italics*
$_ =~ s/\*(\S.*?)\*//g;
$_ =~ s/CURL(M|SH|U|H)code//g;
$_ =~ s/CURL_[A-Z0-9_]*//g;
$_ =~ s/CURLALTSVC_[A-Z0-9_]*//g;
$_ =~ s/CURLAUTH_[A-Z0-9_]*//g;
$_ =~ s/CURLE_[A-Z0-9_]*//g;
$_ =~ s/CURLFORM_[A-Z0-9_]*//g;
$_ =~ s/CURLFTP_[A-Z0-9_]*//g;
$_ =~ s/CURLFTPAUTH_[A-Z0-9_]*//g;
$_ =~ s/CURLFTPMETHOD_[A-Z0-9_]*//g;
$_ =~ s/CURLFTPSSL_[A-Z0-9_]*//g;
$_ =~ s/CURLGSSAPI_[A-Z0-9_]*//g;
$_ =~ s/CURLHEADER_[A-Z0-9_]*//g;
$_ =~ s/CURLINFO_[A-Z0-9_]*//g;
$_ =~ s/CURLM_[A-Z0-9_]*//g;
$_ =~ s/CURLMIMEOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLMOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLPIPE_[A-Z0-9_]*//g;
$_ =~ s/CURLPROTO_[A-Z0-9_]*//g;
$_ =~ s/CURLPROXY_[A-Z0-9_]*//g;
$_ =~ s/CURLPX_[A-Z0-9_]*//g;
$_ =~ s/CURLSHE_[A-Z0-9_]*//g;
$_ =~ s/CURLSHOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLSSLOPT_[A-Z0-9_]*//g;
$_ =~ s/CURLSSH_[A-Z0-9_]*//g;
$_ =~ s/CURLSSLBACKEND_[A-Z0-9_]*//g;
$_ =~ s/CURLU_[A-Z0-9_]*//g;
$_ =~ s/CURLUPART_[A-Z0-9_]*//g;
#$_ =~ s/\bCURLU\b//g; # stand-alone CURLU
$_ =~ s/CURLUE_[A-Z0-9_]*//g;
$_ =~ s/CURLHE_[A-Z0-9_]*//g;
$_ =~ s/CURLWS_[A-Z0-9_]*//g;
$_ =~ s/CURLKH[A-Z0-9_]*//g;
$_ =~ s/CURLUPART_[A-Z0-9_]*//g;
$_ =~ s/CURLUSESSL_[A-Z0-9_]*//g;
$_ =~ s/CURLPAUSE_[A-Z0-9_]*//g;
$_ =~ s/CURLHSTS_[A-Z0-9_]*//g;
$_ =~ s/curl_global_([a-z_]*)//g;
$_ =~ s/curl_(strequal|strnequal|formadd|waitfd|formget|getdate|formfree)//g;
$_ =~ s/curl_easy_([a-z]*)//g;
$_ =~ s/curl_multi_([a-z_]*)//g;
$_ =~ s/curl_mime_(subparts|addpart|filedata|data_cb)//g;
$_ =~ s/curl_ws_(send|recv|meta)//g;
$_ =~ s/curl_url_(dup)//g;
$_ =~ s/curl_pushheader_by(name|num)//g;
$_ =~ s/libcurl-(env|ws)//g;
$_ =~ s/libcurl\\-(env|ws)//g;
$_ =~ s/(^|\W)((tftp|https|http|ftp):\/\/[a-z0-9\-._~%:\/?\#\[\]\@!\$&'()*+,;=\\]+)//gi;
push @out, $_;
}
}
close(F);
open(O, ">$f") or die;
for my $l (@out) {
print O $l;
}
close(O);

View File

@ -1,151 +0,0 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
#
# common variable types + structs
# callback typedefs
# public functions names
# some man page names
curl_fileinfo
curl_forms
curl_hstsentry
curl_httppost
curl_index
curl_khkey
curl_pushheaders
curl_waitfd
CURLcode
CURLformoption
CURLHcode
CURLMcode
CURLMsg
CURLSHcode
CURLUcode
curl_calloc_callback
curl_chunk_bgn_callback
curl_chunk_end_callback
curl_conv_callback
curl_debug_callback
curl_fnmatch_callback
curl_formget_callback
curl_free_callback
curl_hstsread_callback
curl_hstswrite_callback
curl_ioctl_callback
curl_malloc_callback
curl_multi_timer_callback
curl_opensocket_callback
curl_prereq_callback
curl_progress_callback
curl_push_callback
curl_read_callback
curl_realloc_callback
curl_resolver_start_callback
curl_seek_callback
curl_socket_callback
curl_sockopt_callback
curl_ssl_ctx_callback
curl_strdup_callback
curl_trailer_callback
curl_write_callback
curl_xferinfo_callback
curl_strequal
curl_strnequal
curl_mime_init
curl_mime_free
curl_mime_addpart
curl_mime_name
curl_mime_filename
curl_mime_type
curl_mime_encoder
curl_mime_data
curl_mime_filedata
curl_mime_data_cb
curl_mime_subparts
curl_mime_headers
curl_formadd
curl_formget
curl_formfree
curl_getdate
curl_getenv
curl_version
curl_easy_escape
curl_escape
curl_easy_unescape
curl_unescape
curl_free
curl_global_init
curl_global_init_mem
curl_global_cleanup
curl_global_trace
curl_global_sslset
curl_slist_append
curl_slist_free_all
curl_getdate
curl_share_init
curl_share_setopt
curl_share_cleanup
curl_version_info
curl_easy_strerror
curl_share_strerror
curl_easy_pause
curl_easy_ssls_import
curl_easy_ssls_export
curl_easy_init
curl_easy_setopt
curl_easy_perform
curl_easy_cleanup
curl_easy_getinfo
curl_easy_duphandle
curl_easy_reset
curl_easy_recv
curl_easy_send
curl_easy_upkeep
curl_easy_header
curl_easy_nextheader
curl_mprintf
curl_mfprintf
curl_msprintf
curl_msnprintf
curl_mvprintf
curl_mvfprintf
curl_mvsprintf
curl_mvsnprintf
curl_maprintf
curl_mvaprintf
curl_multi_init
curl_multi_add_handle
curl_multi_remove_handle
curl_multi_fdset
curl_multi_waitfds
curl_multi_wait
curl_multi_poll
curl_multi_wakeup
curl_multi_perform
curl_multi_cleanup
curl_multi_info_read
curl_multi_strerror
curl_multi_socket
curl_multi_socket_action
curl_multi_socket_all
curl_multi_timeout
curl_multi_setopt
curl_multi_assign
curl_multi_get_handles
curl_pushheader_bynum
curl_pushheader_byname
curl_multi_waitfds
curl_easy_option_by_name
curl_easy_option_by_id
curl_easy_option_next
curl_url
curl_url_cleanup
curl_url_dup
curl_url_get
curl_url_set
curl_url_strerror
curl_ws_recv
curl_ws_send
curl_ws_meta
libcurl-env
libcurl-ws

View File

@ -121,6 +121,8 @@ CMakeLists
CNA
CNAME
CNAMEs
CodeQL
codeql
CODESET
codeset
CodeSonar
@ -251,7 +253,6 @@ Feltzing
ffi
filesize
filesystem
FindCURL
FLOSS
fnmatch
footguns
@ -951,6 +952,7 @@ winbuild
WinIDN
WinLDAP
winsock
winssl
Wireshark
wolfSSH
wolfSSL

View File

@ -107,8 +107,20 @@ jobs:
persist-credentials: false
name: checkout
- name: trim all *.md files in docs/
run: .github/scripts/cleancmd.pl $(find docs -name "*.md")
- name: trim all man page *.md files
run: find docs -name "*.md" ! -name "_*" -print0 | xargs -0 -n1 .github/scripts/cleancmd.pl
- name: trim libcurl man page *.md files
run: find docs/libcurl \( -name "curl_*.md" -o -name "libcurl*.md" \) -print0 | xargs -0 -n1 .github/scripts/cleanspell.pl
- name: trim libcurl option man page *.md files
run: find docs/libcurl/opts -name "CURL*.md" -print0 | xargs -0 -n1 .github/scripts/cleanspell.pl
- name: trim cmdline docs markdown _*.md files
run: find docs/cmdline-opts -name "_*.md" -print0 | xargs -0 -n1 .github/scripts/cleancmd.pl --no-header
- name: trim docs/ markdown _*.md files
run: git ls-files docs/*.md docs/internals/*.md | xargs -n1 .github/scripts/cleancmd.pl --no-header
- name: setup the custom wordlist
run: grep -v '^#' .github/scripts/spellcheck.words > wordlist.txt

85
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,85 @@
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# SPDX-License-Identifier: curl
name: CodeQL
'on':
push:
branches:
- master
- '*/ci'
paths-ignore:
- '**/*.md'
- '.circleci/**'
- 'appveyor.*'
- 'docs/**'
- 'packages/**'
- 'plan9/**'
- 'projects/**'
- 'tests/data/**'
- 'winbuild/**'
pull_request:
branches:
- master
paths-ignore:
- '**/*.md'
- '.circleci/**'
- 'appveyor.*'
- 'docs/**'
- 'packages/**'
- 'plan9/**'
- 'projects/**'
- 'tests/data/**'
- 'winbuild/**'
schedule:
- cron: '0 0 * * 4'
concurrency:
group: ${{ github.workflow }}
permissions: {}
jobs:
codeql:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: 'install prereqs'
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get -o Dpkg::Use-Pty=0 update
sudo apt-get -o Dpkg::Use-Pty=0 install \
libpsl-dev
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3
with:
languages: cpp
queries: security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# - run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3

View File

@ -19,9 +19,6 @@ concurrency:
permissions: {}
env:
MAKEFLAGS: -j 5
jobs:
maketgz-and-verify-in-tree:
runs-on: ubuntu-latest
@ -58,9 +55,9 @@ jobs:
tar xvf curl-99.98.97.tar.gz
pushd curl-99.98.97
./configure --prefix=$HOME/temp --without-ssl --without-libpsl
make
make test-ci
make install
make -j5
make -j5 test-ci
make -j5 install
popd
# basic check of the installed files
bash scripts/installcheck.sh $HOME/temp
@ -83,8 +80,8 @@ jobs:
mkdir build
pushd build
../curl-99.98.97/configure --without-ssl --without-libpsl
make
make test-ci
make -j5
make -j5 test-ci
popd
rm -rf build
rm -rf curl-99.98.97
@ -106,9 +103,9 @@ jobs:
mkdir build
pushd build
../configure --without-ssl --enable-debug "--prefix=${PWD}/pkg" --without-libpsl
make
make test-ci
make install
make -j5
make -j5 test-ci
make -j5 install
verify-out-of-tree-cmake:
runs-on: ubuntu-latest
@ -125,7 +122,7 @@ jobs:
tar xvf curl-99.98.97.tar.gz
pushd curl-99.98.97
cmake -B build -DCURL_WERROR=ON -DCURL_USE_LIBPSL=OFF
make -C build
make -C build -j5
missing-files:
runs-on: ubuntu-latest

View File

@ -434,45 +434,46 @@ jobs:
export PKG_CONFIG_PATH="${{ matrix.build.PKG_CONFIG_PATH }}"
fi
if [ -n '${{ matrix.build.generate }}' ]; then
cmake -B bld -G Ninja \
cmake -B . -G Ninja \
-DCMAKE_C_COMPILER_TARGET=$(uname -m)-pc-linux-gnu -DBUILD_STATIC_LIBS=ON \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON -DCURL_WERROR=ON \
${{ matrix.build.generate }}
else
mkdir bld && cd bld && ../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \
--disable-dependency-tracking \
./configure --disable-dependency-tracking --enable-unity --enable-test-bundles --enable-warnings --enable-werror \
${{ matrix.build.configure }}
fi
- name: 'configure log'
if: ${{ !cancelled() }}
run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
run: cat config.log CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: 'curl_config.h'
run: |
echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' bld/lib/curl_config.h | sort || true
echo '::group::raw'; cat lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' lib/curl_config.h | sort || true
- name: 'test configs'
run: grep -H -v '^#' bld/tests/config bld/tests/http/config.ini || true
run: |
cat tests/config || true
cat tests/http/config.ini || true
- name: 'build'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose
cmake --build . --verbose
else
make -C bld V=1
make V=1
fi
- name: 'check curl -V output'
run: bld/src/curl -V
run: ./src/curl -V
- name: 'build tests'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target testdeps
cmake --build . --verbose --target testdeps
else
make -C bld V=1 -C tests
make V=1 -C tests
fi
- name: 'install test prereqs'
@ -486,9 +487,9 @@ jobs:
run: |
source $HOME/venv/bin/activate
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target test-ci
cmake --build . --verbose --target test-ci
else
make -C bld V=1 test-ci
make V=1 test-ci
fi
- name: 'install pytest prereqs'
@ -498,21 +499,22 @@ jobs:
- name: 'run pytest event based'
env:
TFLAGS: '${{ matrix.build.tflags }}'
CURL_TEST_EVENT: 1
CURL_CI: github
PYTEST_ADDOPTS: '--color=yes'
run: |
source $HOME/venv/bin/activate
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target curl-pytest-ci
cmake --build . --verbose --target curl-pytest-ci
else
make -C bld V=1 pytest-ci
make V=1 pytest-ci
fi
- name: 'build examples'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target curl-examples
cmake --build . --verbose --target curl-examples
else
make -C bld V=1 examples
make V=1 examples
fi

View File

@ -304,8 +304,7 @@ jobs:
libtool autoconf automake pkgconf ninja-build \
${{ matrix.build.install_steps != 'skipall' && matrix.build.install_steps != 'skiprun' && 'stunnel4' || '' }} \
libpsl-dev libbrotli-dev libzstd-dev \
${{ matrix.build.install_packages }} \
${{ contains(matrix.build.install_steps, 'pytest') && 'apache2 apache2-dev libnghttp2-dev vsftpd' || '' }}
${{ matrix.build.install_packages }}
python3 -m venv $HOME/venv
- name: 'install prereqs'
@ -320,6 +319,11 @@ jobs:
${{ matrix.build.install_packages }}
python3 -m venv $HOME/venv
- name: 'install prereqs for pytest'
if: contains(matrix.build.install_steps, 'pytest')
run: |
sudo apt-get -o Dpkg::Use-Pty=0 install apache2 apache2-dev libnghttp2-dev vsftpd
- name: 'install dependencies'
if: startsWith(matrix.build.container, 'alpine')
run: |
@ -556,7 +560,7 @@ jobs:
cd $HOME
curl -sSf --compressed https://sh.rustup.rs/ | sh -s -- -y
source $HOME/.cargo/env
rustup toolchain install stable --profile minimal
rustup toolchain install nightly
- name: 'build rustls'
if: contains(matrix.build.install_steps, 'rustls') && steps.cache-rustls.outputs.cache-hit != 'true'
@ -589,37 +593,37 @@ jobs:
export PKG_CONFIG_PATH="${{ matrix.build.PKG_CONFIG_PATH }}"
fi
if [ -n '${{ matrix.build.generate }}' ]; then
cmake -B bld -G Ninja \
cmake -B . -G Ninja \
-DCMAKE_INSTALL_PREFIX="$HOME/curl" \
-DCMAKE_C_COMPILER_TARGET=$(uname -m)-pc-linux-gnu -DBUILD_STATIC_LIBS=ON \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON -DCURL_WERROR=ON \
${{ matrix.build.generate }}
else
mkdir bld && cd bld && \
${{ matrix.build.configure-prefix }} \
../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \
--disable-dependency-tracking \
./configure --disable-dependency-tracking --enable-unity --enable-test-bundles --enable-warnings --enable-werror \
${{ matrix.build.configure }}
fi
- name: 'configure log'
if: ${{ !cancelled() }}
run: cat bld/config.log bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
run: cat config.log CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: 'curl_config.h'
run: |
echo '::group::raw'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' bld/lib/curl_config.h | sort || true
echo '::group::raw'; cat lib/curl_config.h || true; echo '::endgroup::'
grep -F '#define' lib/curl_config.h | sort || true
- name: 'test configs'
run: grep -H -v '^#' bld/tests/config bld/tests/http/config.ini || true
run: |
cat tests/config || true
cat tests/http/config.ini || true
- name: 'build'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
${{ matrix.build.make-prefix }} cmake --build bld --verbose
${{ matrix.build.make-prefix }} cmake --build . --verbose
else
${{ matrix.build.make-prefix }} make -C bld V=1 ${{ matrix.build.make-custom-target }}
${{ matrix.build.make-prefix }} make V=1 ${{ matrix.build.make-custom-target }}
fi
- name: 'single-use function check'
@ -627,27 +631,27 @@ jobs:
run: |
git config --global --add safe.directory "*"
if [ -n '${{ matrix.build.generate }}' ]; then
libcurla=bld/lib/libcurl.a
libcurla=lib/libcurl.a
else
libcurla=bld/lib/.libs/libcurl.a
libcurla=lib/.libs/libcurl.a
fi
./scripts/singleuse.pl --unit ${libcurla}
- name: 'check curl -V output'
if: ${{ matrix.build.make-custom-target != 'tidy' }}
run: bld/src/curl -V
run: ./src/curl -V
- name: 'cmake install'
if: ${{ matrix.build.generate }}
run: cmake --install bld --strip
run: cmake --install . --strip
- name: 'build tests'
if: ${{ matrix.build.install_steps != 'skipall' }}
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target testdeps
cmake --build . --verbose --target testdeps
else
make -C bld V=1 -C tests
make V=1 -C tests
fi
- name: 'install test prereqs'
@ -674,9 +678,9 @@ jobs:
fi
[ -x "$HOME/venv/bin/activate" ] && source $HOME/venv/bin/activate
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target ${{ matrix.build.torture && 'test-torture' || 'test-ci' }}
cmake --build . --verbose --target ${{ matrix.build.torture && 'test-torture' || 'test-ci' }}
else
make -C bld V=1 ${{ matrix.build.torture && 'test-torture' || 'test-ci' }}
make V=1 ${{ matrix.build.torture && 'test-torture' || 'test-ci' }}
fi
- name: 'install pytest prereqs'
@ -688,21 +692,22 @@ jobs:
- name: 'run pytest'
if: contains(matrix.build.install_steps, 'pytest')
env:
TFLAGS: '${{ matrix.build.tflags }}'
CURL_CI: github
PYTEST_ADDOPTS: '--color=yes'
run: |
[ -x "$HOME/venv/bin/activate" ] && source $HOME/venv/bin/activate
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target curl-pytest-ci
cmake --build . --verbose --target curl-pytest-ci
else
make -C bld V=1 pytest-ci
make V=1 pytest-ci
fi
- name: 'build examples'
if: ${{ matrix.build.make-custom-target != 'tidy' }}
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
${{ matrix.build.make-prefix }} cmake --build bld --verbose --target curl-examples
${{ matrix.build.make-prefix }} cmake --build . --verbose --target curl-examples
else
${{ matrix.build.make-prefix }} make -C bld V=1 examples
${{ matrix.build.make-prefix }} make V=1 examples
fi

View File

@ -47,8 +47,8 @@ permissions: {}
# newer than the 10.8 required by `CFURLCreateDataAndPropertiesFromResource`.
env:
MAKEFLAGS: -j 4
LDFLAGS: -w # suppress 'object file was built for newer macOS version than being linked' warnings
MAKEFLAGS: -j 4
jobs:
macos:
@ -123,10 +123,9 @@ jobs:
compiler: clang
configure: --enable-debug --with-openssl=$(brew --prefix openssl)
tflags: --test-event
- name: 'quictls libssh2 !ldap 10.15'
- name: 'OpenSSL libssh2 !ldap 10.15'
compiler: clang
install: quictls
configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix quictls) LDFLAGS="${LDFLAGS} -L$(brew --prefix quictls)/lib"
configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix openssl)
macos-version-min: '10.15'
# cmake
- name: 'OpenSSL gsasl rtmp AppleIDN'
@ -137,9 +136,9 @@ jobs:
generate: -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DUSE_APPLE_IDN=ON -DCURL_CLANG_TIDY=ON -DCLANG_TIDY=$(brew --prefix llvm)/bin/clang-tidy
clang-tidy: true
chkprefill: _chkprefill
- name: 'quictls +static libssh +examples'
install: quictls libssh
generate: -DOPENSSL_ROOT_DIR=$(brew --prefix quictls) -DBUILD_STATIC_LIBS=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON
- name: 'OpenSSL +static libssh +examples'
install: libssh
generate: -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) -DBUILD_STATIC_LIBS=ON -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=ON
- name: 'SecureTransport debug'
generate: -DCURL_USE_SECTRANSP=ON -DENABLE_DEBUG=ON
macos-version-min: '10.8'
@ -185,12 +184,11 @@ jobs:
run: |
echo ${{ matrix.build.generate && 'ninja' || 'automake libtool' }} \
pkgconf libpsl libssh2 \
${{ !matrix.build.clang-tidy && 'libnghttp2 stunnel' || '' }} \
${{ !matrix.build.clang-tidy && 'nghttp2 stunnel' || '' }} \
${{ matrix.build.install }} | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile
while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --no-lock --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done
- name: 'brew unlink openssl'
if: ${{ contains(matrix.build.install, 'libressl') || contains(matrix.build.install, 'quictls') }}
run: |
if test -d $(brew --prefix)/include/openssl; then
brew unlink openssl
@ -315,6 +313,7 @@ jobs:
if [ -z '${{ matrix.build.torture }}' ]; then
TFLAGS+=' ~2037 ~2041' # flaky
if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then
TFLAGS+=' ~RTSP' # 567 568 569 570 571 572 577 689 3100
TFLAGS+=' ~1156 ~1539' # HTTP Content-Range, Content-Length
if [[ -n '${{ matrix.build.configure }}' || \
'${{ matrix.build.generate }}' = *'-DCURL_USE_SECTRANSP=ON'* ]]; then
@ -345,7 +344,7 @@ jobs:
if: ${{ contains(matrix.build.name, '+examples') }}
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld --verbose --target curl-examples
cmake --build bld --target curl-examples --verbose
else
make -C bld examples V=1
fi

View File

@ -59,21 +59,21 @@ jobs:
time cmake -B bld -G Ninja \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
-DENABLE_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug \
-DENABLE_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-DCURL_USE_OPENSSL=ON \
-DCURL_USE_GSSAPI=ON \
|| { cat bld/CMakeFiles/CMake*.yaml; false; }
echo '::group::curl_config.h (raw)'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
echo '::group::curl_config.h'; grep -F '#define' bld/lib/curl_config.h | sort || true; echo '::endgroup::'
time cmake --build bld
time cmake --build bld --config Debug
bld/src/curl --disable --version
if [ '${{ matrix.arch }}' = 'x86_64' ]; then # Slow on emulated CPU
time cmake --build bld --target testdeps
time cmake --build bld --config Debug --target testdeps
export TFLAGS='-j4'
time cmake --build bld --target test-ci
time cmake --build bld --config Debug --target test-ci
fi
echo '::group::build examples'
time cmake --build bld --target curl-examples
time cmake --build bld --config Debug --target curl-examples
echo '::endgroup::'
openbsd:
@ -100,20 +100,20 @@ jobs:
time cmake -B bld -G Ninja \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
-DENABLE_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug \
-DENABLE_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-DCURL_USE_OPENSSL=ON \
|| { cat bld/CMakeFiles/CMake*.yaml; false; }
echo '::group::curl_config.h (raw)'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
echo '::group::curl_config.h'; grep -F '#define' bld/lib/curl_config.h | sort || true; echo '::endgroup::'
time cmake --build bld
time cmake --build bld --config Debug
bld/src/curl --disable --version
if [ '${{ matrix.arch }}' = 'x86_64' ]; then # Slow on emulated CPU
time cmake --build bld --target testdeps
time cmake --build bld --config Debug --target testdeps
export TFLAGS='-j8 ~3017 ~TFTP ~FTP' # FIXME: TFTP requests executed twice? Related: `curl: (69) TFTP: Access Violation`?
time cmake --build bld --target test-ci
time cmake --build bld --config Debug --target test-ci
fi
echo '::group::build examples'
time cmake --build bld --target curl-examples
time cmake --build bld --config Debug --target curl-examples
echo '::endgroup::'
freebsd:
@ -140,7 +140,6 @@ jobs:
version: '14.1'
architecture: ${{ matrix.arch }}
run: |
export MAKEFLAGS=-j3
# https://ports.freebsd.org/
time sudo pkg install -y autoconf automake libtool \
pkgconf brotli openldap26-client libidn2 libnghttp2 stunnel py311-impacket
@ -155,18 +154,18 @@ jobs:
|| { tail -n 1000 config.log; false; }
echo '::group::curl_config.h (raw)'; cat lib/curl_config.h || true; echo '::endgroup::'
echo '::group::curl_config.h'; grep -F '#define' lib/curl_config.h | sort || true; echo '::endgroup::'
time make install
time make -j3 install
src/curl --disable --version
desc='${{ matrix.desc }}'
if [ '${{ matrix.arch }}' = 'x86_64' ]; then # Slow on emulated CPU
time make -C tests
time make -j3 -C tests
if [ "${desc#*!runtests*}" = "${desc}" ]; then
time make test-ci V=1 TFLAGS='-j4'
fi
fi
if [ "${desc#*!examples*}" = "${desc}" ]; then
echo '::group::build examples'
time make examples
time make -j3 examples
echo '::endgroup::'
fi
@ -185,25 +184,25 @@ jobs:
-DCMAKE_C_COMPILER='${{ matrix.compiler }}' \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
-DENABLE_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug \
-DENABLE_DEBUG=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-DCURL_USE_OPENSSL=ON \
-DCURL_USE_GSSAPI=ON \
${{ matrix.options }} \
|| { cat bld/CMakeFiles/CMake*.yaml; false; }
echo '::group::curl_config.h (raw)'; cat bld/lib/curl_config.h || true; echo '::endgroup::'
echo '::group::curl_config.h'; grep -F '#define' bld/lib/curl_config.h | sort || true; echo '::endgroup::'
time cmake --build bld
time cmake --build bld --config Debug
bld/src/curl --disable --version
desc='${{ matrix.desc }}'
if [ '${{ matrix.arch }}' = 'x86_64' ]; then # Slow on emulated CPU
time cmake --build bld --target testdeps
time cmake --build bld --config Debug --target testdeps
if [ "${desc#*!runtests*}" = "${desc}" ]; then
time cmake --build bld --target test-ci
time cmake --build bld --config Debug --target test-ci
fi
fi
if [ "${desc#*!examples*}" = "${desc}" ]; then
echo '::group::build examples'
time cmake --build bld --target curl-examples
time cmake --build bld --config Debug --target curl-examples
echo '::endgroup::'
fi
@ -224,7 +223,6 @@ jobs:
run: |
set -e
ln -s /usr/bin/gcpp /usr/bin/cpp # Some tests expect `cpp`, which is named `gcpp` in this env.
export MAKEFLAGS=-j3
time autoreconf -fi
mkdir bld && cd bld && time ../configure --enable-unity --enable-test-bundles --enable-debug --enable-warnings --enable-werror \
--prefix="${HOME}"/install \
@ -233,12 +231,12 @@ jobs:
|| { tail -n 1000 config.log; false; }
echo '::group::curl_config.h (raw)'; cat lib/curl_config.h || true; echo '::endgroup::'
echo '::group::curl_config.h'; grep -F '#define' lib/curl_config.h | sort || true; echo '::endgroup::'
time gmake install
time gmake -j3 install
src/curl --disable --version
time gmake -C tests
time gmake -j3 -C tests
time gmake test-ci V=1
echo '::group::build examples'
time gmake examples
time gmake -j3 examples
echo '::endgroup::'
ios:
@ -246,9 +244,9 @@ jobs:
runs-on: 'macos-latest'
timeout-minutes: 10
env:
MAKEFLAGS: -j 4
DEVELOPER_DIR: "/Applications/Xcode${{ matrix.build.xcode && format('_{0}', matrix.build.xcode) || '' }}.app/Contents/Developer"
CC: ${{ matrix.build.compiler || 'clang' }}
MAKEFLAGS: -j 4
# renovate: datasource=github-tags depName=libressl-portable/portable versioning=semver registryUrl=https://github.com
libressl-version: 4.0.0
strategy:
@ -263,7 +261,6 @@ jobs:
install_steps: libressl
# FIXME: Could not make OPENSSL_ROOT_DIR work. CMake seems to prepend sysroot to it.
generate: >-
-DCMAKE_BUILD_TYPE=Release -DCMAKE_UNITY_BUILD_BATCH_SIZE=50
-DOPENSSL_INCLUDE_DIR="$HOME/libressl/include"
-DOPENSSL_SSL_LIBRARY="$HOME/libressl/lib/libssl.a"
-DOPENSSL_CRYPTO_LIBRARY="$HOME/libressl/lib/libcrypto.a"
@ -272,7 +269,6 @@ jobs:
- name: 'libressl'
install_steps: libressl
generator: Xcode
options: --config Debug
generate: >-
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=OFF
-DMACOSX_BUNDLE_GUI_IDENTIFIER=se.curl
@ -365,7 +361,7 @@ jobs:
- name: 'build'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld ${{ matrix.build.options }} --parallel 4 --verbose
cmake --build bld --verbose
else
make -C bld V=1
fi
@ -376,7 +372,7 @@ jobs:
- name: 'build tests'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld ${{ matrix.build.options }} --parallel 4 --target testdeps --verbose
cmake --build bld --target testdeps --verbose
else
make -C bld V=1 -C tests
fi
@ -384,7 +380,7 @@ jobs:
- name: 'build examples'
run: |
if [ -n '${{ matrix.build.generate }}' ]; then
cmake --build bld ${{ matrix.build.options }} --parallel 4 --target curl-examples --verbose
cmake --build bld --target curl-examples --verbose
else
make -C bld examples V=1
fi
@ -394,9 +390,9 @@ jobs:
runs-on: 'ubuntu-latest'
timeout-minutes: 25
env:
MAKEFLAGS: -j 5
VCPKG_BINARY_SOURCES: 'clear;x-gha,readwrite'
VCPKG_DISABLE_METRICS: '1'
MAKEFLAGS: -j 5
strategy:
matrix:
include:
@ -494,7 +490,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --verbose
else
make -C bld V=1
make -j5 -C bld V=1
fi
- name: 'curl info'
@ -505,7 +501,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
else
make -C bld -C tests
make -j5 -C bld -C tests
fi
- name: 'build examples'
@ -513,7 +509,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
else
make -C bld examples
make -j5 -C bld examples
fi
amiga:
@ -521,7 +517,6 @@ jobs:
runs-on: 'ubuntu-latest'
timeout-minutes: 5
env:
MAKEFLAGS: -j 5
amissl-version: 5.18
strategy:
matrix:
@ -589,9 +584,9 @@ jobs:
- name: 'build'
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld
cmake --build bld --parallel 5
else
make -C bld
make -j5 -C bld
fi
- name: 'curl info'
@ -601,18 +596,18 @@ jobs:
if: ${{ matrix.build == 'cmake' }} # skip for autotools to save time
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
cmake --build bld --parallel 5 --target testdeps
else
make -C bld -C tests
make -j5 -C bld -C tests
fi
- name: 'build examples'
if: ${{ matrix.build == 'cmake' }} # skip for autotools to save time
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
cmake --build bld --parallel 5 --target curl-examples
else
make -C bld examples
make -j5 -C bld examples
fi
msdos:
@ -620,7 +615,6 @@ jobs:
runs-on: 'ubuntu-latest'
timeout-minutes: 5
env:
MAKEFLAGS: -j 5
toolchain-version: '3.4'
strategy:
matrix:
@ -700,7 +694,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld
else
make -C bld
make -j5 -C bld
fi
- name: 'curl info'
@ -712,7 +706,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
else
make -C bld -C tests
make -j5 -C bld -C tests
fi
- name: 'build examples'
@ -721,5 +715,5 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
else
make -C bld examples
make -j5 -C bld examples
fi

View File

@ -44,7 +44,6 @@ jobs:
run:
shell: C:\cygwin\bin\bash.exe '{0}'
env:
MAKEFLAGS: -j 5
SHELLOPTS: 'igncr'
strategy:
matrix:
@ -84,13 +83,14 @@ jobs:
- name: 'configure'
timeout-minutes: 5
run: |
PATH=/usr/bin
if [ '${{ matrix.build }}' = 'cmake' ]; then
PATH="/usr/bin:$(cygpath "${SYSTEMROOT}")/System32"
cmake -B bld -G Ninja -D_CURL_PREFILL=ON ${options} \
-DCMAKE_UNITY_BUILD=ON -DCMAKE_UNITY_BUILD_BATCH_SIZE=30 -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
${{ matrix.config }}
else
PATH="/usr/bin:$(cygpath "${SYSTEMROOT}")/System32"
mkdir bld && cd bld && ../configure --enable-unity --enable-test-bundles --enable-warnings --enable-werror \
--prefix="${HOME}"/install \
--with-openssl \
@ -112,9 +112,9 @@ jobs:
timeout-minutes: 10
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld
cmake --build bld --config '${{ matrix.type }}'
else
make -C bld V=1 install
make -C bld -j5 V=1 install
fi
- name: 'curl version'
@ -131,9 +131,9 @@ jobs:
timeout-minutes: 15
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
cmake --build bld --config '${{ matrix.type }}' --target testdeps
else
make -C bld V=1 -C tests
make -C bld -j5 V=1 -C tests
fi
- name: 'run tests'
@ -146,9 +146,9 @@ jobs:
fi
if [ '${{ matrix.build }}' = 'cmake' ]; then
PATH="$PWD/bld/lib:$PATH"
cmake --build bld --target test-ci
cmake --build bld --config '${{ matrix.type }}' --target test-ci
else
make -C bld V=1 test-ci
make -C bld -j5 V=1 test-ci
fi
- name: 'build examples'
@ -156,9 +156,9 @@ jobs:
timeout-minutes: 5
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
cmake --build bld --config '${{ matrix.type }}' --target curl-examples
else
make -C bld V=1 examples
make -C bld -j5 V=1 examples
fi
msys2: # both msys and mingw-w64
@ -168,8 +168,6 @@ jobs:
defaults:
run:
shell: msys2 {0}
env:
MAKEFLAGS: -j 5
strategy:
matrix:
include:
@ -207,7 +205,6 @@ jobs:
libnghttp2-devel
libpsl-devel
libssh2-devel
${{ matrix.chkprefill == '_chkprefill' && 'diffutils' || '' }}
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # v2
if: ${{ matrix.sys != 'msys' }}
@ -253,6 +250,8 @@ jobs:
fi
[ '${{ matrix.sys }}' = 'msys' ] && options+=' -D_CURL_PREFILL=ON'
[ '${{ matrix.test }}' = 'uwp' ] && options+=' -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0'
[ '${{ matrix.type }}' = 'Debug' ] && options+=' -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG='
[ '${{ matrix.type }}' = 'Release' ] && options+=' -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE='
[ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF'
cmake -B "bld${_chkprefill}" -G Ninja ${options} \
-DCMAKE_C_FLAGS="${{ matrix.cflags }} ${CFLAGS_CMAKE} ${CPPFLAGS}" \
@ -287,9 +286,9 @@ jobs:
timeout-minutes: 10
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld
cmake --build bld --config '${{ matrix.type }}'
else
make -C bld V=1 install
make -C bld -j5 V=1 install
fi
- name: 'curl version'
@ -312,9 +311,9 @@ jobs:
timeout-minutes: 10
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
cmake --build bld --config '${{ matrix.type }}' --target testdeps
else
make -C bld V=1 -C tests
make -C bld -j5 V=1 -C tests
fi
if [ '${{ matrix.build }}' != 'cmake' ]; then
# avoid libtool's .exe wrappers
@ -348,10 +347,10 @@ jobs:
PATH="$PATH:/c/Program Files (x86)/stunnel/bin"
if [ '${{ matrix.build }}' = 'cmake' ]; then
PATH="$PWD/bld/lib:$PATH"
cmake --build bld --target test-ci
cmake --build bld --config '${{ matrix.type }}' --target test-ci
else
PATH="$PWD/bld/lib/.libs:$PATH"
make -C bld V=1 test-ci
make -C bld -j5 V=1 test-ci
fi
- name: 'build examples'
@ -359,9 +358,9 @@ jobs:
timeout-minutes: 5
run: |
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
cmake --build bld --config '${{ matrix.type }}' --target curl-examples
else
make -C bld V=1 examples
make -C bld -j5 V=1 examples
fi
mingw-w64-standalone-downloads:
@ -371,8 +370,6 @@ jobs:
defaults:
run:
shell: C:\msys64\usr\bin\bash.exe {0}
env:
MAKEFLAGS: -j 5
strategy:
matrix:
include:
@ -429,21 +426,15 @@ jobs:
timeout-minutes: 5
run: |
PATH="$(cygpath "${USERPROFILE}")/my-cache/${{ matrix.dir }}/bin:/c/msys64/usr/bin:$PATH"
for _chkprefill in '' ${{ matrix.chkprefill }}; do
options=''
[ "${_chkprefill}" = '_chkprefill' ] && options+=' -D_CURL_PREFILL=OFF'
cmake -B "bld${_chkprefill}" -G 'MSYS Makefiles' ${options} \
[ '${{ matrix.type }}' = 'Debug' ] && options+=' -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG='
[ '${{ matrix.type }}' = 'Release' ] && options+=' -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE='
cmake -B bld -G 'MSYS Makefiles' ${options} \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_BUILD_TYPE='${{ matrix.type }}' \
-DCMAKE_UNITY_BUILD=ON -DCMAKE_UNITY_BUILD_BATCH_SIZE=30 -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
-DCURL_USE_LIBPSL=OFF \
${{ matrix.config }}
done
if [ -d bld_chkprefill ] && ! diff -u bld/lib/curl_config.h bld_chkprefill/lib/curl_config.h; then
echo '::group::reference configure log'; cat bld_chkprefill/CMakeFiles/CMake*.yaml 2>/dev/null || true; echo '::endgroup::'
false
fi
- name: 'configure log'
if: ${{ !cancelled() }}
@ -458,7 +449,7 @@ jobs:
timeout-minutes: 5
run: |
PATH="$(cygpath "${USERPROFILE}")/my-cache/${{ matrix.dir }}/bin:/c/msys64/usr/bin:$PATH"
cmake --build bld
cmake --build bld --config '${{ matrix.type }}' --parallel 5
- name: 'curl version'
timeout-minutes: 1
@ -472,7 +463,7 @@ jobs:
timeout-minutes: 10
run: |
PATH="$(cygpath "${USERPROFILE}")/my-cache/${{ matrix.dir }}/bin:/c/msys64/usr/bin:$PATH"
cmake --build bld --target testdeps
cmake --build bld --config '${{ matrix.type }}' --parallel 5 --target testdeps
- name: 'install test prereqs'
if: ${{ matrix.tflags != 'skipall' && matrix.tflags != 'skiprun' }}
@ -501,29 +492,27 @@ jobs:
TFLAGS+=" -ac $(cygpath "${SYSTEMROOT}/System32/curl.exe")"
fi
PATH="$PWD/bld/lib:$PATH:/c/Program Files (x86)/stunnel/bin"
cmake --build bld --target test-ci
cmake --build bld --config '${{ matrix.type }}' --target test-ci
- name: 'build examples'
timeout-minutes: 5
run: |
PATH="$(cygpath "${USERPROFILE}")/my-cache/${{ matrix.dir }}/bin:/c/msys64/usr/bin:$PATH"
cmake --build bld --target curl-examples
cmake --build bld --config '${{ matrix.type }}' --parallel 5 --target curl-examples
linux-cross-mingw-w64:
name: "linux-mingw, ${{ matrix.build == 'cmake' && 'CM' || 'AM' }} ${{ matrix.compiler }}"
runs-on: ubuntu-latest
timeout-minutes: 15
env:
MAKEFLAGS: -j 5
TRIPLET: 'x86_64-w64-mingw32'
strategy:
fail-fast: false
matrix:
build: [autotools, cmake]
compiler: [gcc]
env:
TRIPLET: 'x86_64-w64-mingw32'
steps:
- name: 'install packages'
timeout-minutes: 5
run: sudo apt-get -o Dpkg::Use-Pty=0 install mingw-w64 ${{ matrix.build == 'cmake' && 'ninja-build' || '' }}
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@ -567,7 +556,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld
else
make -C bld
make -C bld -j5
fi
- name: 'curl info'
@ -579,7 +568,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
else
make -C bld -C tests
make -C bld -j5 -C tests
fi
- name: 'build examples'
@ -587,7 +576,7 @@ jobs:
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
else
make -C bld examples
make -C bld -j5 examples
fi
wince:
@ -595,7 +584,6 @@ jobs:
runs-on: 'macos-latest'
timeout-minutes: 10
env:
MAKEFLAGS: -j 4
toolchain-version: '0.59.1'
strategy:
matrix:
@ -604,7 +592,6 @@ jobs:
steps:
- name: 'install packages'
if: ${{ matrix.build == 'autotools' }}
timeout-minutes: 5
run: |
echo automake libtool | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile
while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew bundle install --no-lock --file /tmp/Brewfile && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done
@ -618,7 +605,6 @@ jobs:
- name: 'install compiler (mingw32ce)'
if: ${{ steps.cache-compiler.outputs.cache-hit != 'true' }}
timeout-minutes: 5
run: |
cd "${HOME}" || exit 1
curl --disable --fail --silent --show-error --connect-timeout 15 --max-time 120 --retry 3 --retry-connrefused --proto-redir =https \
@ -629,19 +615,18 @@ jobs:
- name: 'configure'
run: |
PATH="$HOME/opt/mingw32ce/bin:$PATH"
MINGW32CE_ROOT="${HOME}/opt/mingw32ce"
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake -B bld \
-DCMAKE_SYSTEM_NAME=WindowsCE \
-DCMAKE_SYSTEM_VERSION=8.0 \
-DCMAKE_SYSTEM_PROCESSOR=arm \
-DCMAKE_C_FLAGS='-O3 -DNDEBUG' \
-DCMAKE_C_COMPILER_TARGET=arm-mingw32ce \
-DCMAKE_C_COMPILER=arm-mingw32ce-gcc \
-DCMAKE_RC_COMPILER=arm-mingw32ce-windres \
-DMINGW32CE_LIBRARY_DIR="$HOME/opt/mingw32ce/arm-mingw32ce/lib" \
-DCMAKE_C_COMPILER_TARGET=arm-wince-mingw32ce \
-DCMAKE_C_COMPILER="${MINGW32CE_ROOT}/bin/arm-mingw32ce-gcc" \
-DCMAKE_RC_COMPILER="${MINGW32CE_ROOT}/bin/arm-mingw32ce-windres" \
-DMINGW32CE_LIBRARY_DIR="${MINGW32CE_ROOT}/arm-mingw32ce/lib" \
-DCMAKE_IGNORE_PREFIX_PATH="$(brew --prefix)" \
-DCMAKE_UNITY_BUILD=ON -DCMAKE_UNITY_BUILD_BATCH_SIZE=50 -DCURL_TEST_BUNDLES=ON \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
-DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_STATIC_CURL=OFF \
-DCURL_WERROR=ON \
-DCURL_USE_SCHANNEL=ON \
@ -649,7 +634,12 @@ jobs:
else
autoreconf -fi
mkdir bld && cd bld && ../configure --disable-dependency-tracking --enable-unity --enable-test-bundles --enable-warnings --enable-werror \
--host=arm-mingw32ce \
ac_cv_prog_cc_c99=no \
CC="${MINGW32CE_ROOT}/bin/arm-mingw32ce-gcc" \
AR="${MINGW32CE_ROOT}/bin/arm-mingw32ce-ar" \
RANLIB="${MINGW32CE_ROOT}/bin/arm-mingw32ce-ranlib" \
RC="${MINGW32CE_ROOT}/bin/arm-mingw32ce-windres" \
--host=arm-wince-mingw32ce \
--with-schannel \
--without-libpsl \
--disable-shared
@ -666,11 +656,10 @@ jobs:
- name: 'build'
run: |
PATH="$HOME/opt/mingw32ce/bin:$PATH"
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld
else
make -C bld
make -j5 -C bld
fi
- name: 'curl info'
@ -680,21 +669,19 @@ jobs:
- name: 'build tests'
if: ${{ matrix.build == 'cmake' }} # skip for autotools to save time
run: |
PATH="$HOME/opt/mingw32ce/bin:$PATH"
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target testdeps
else
make -C bld -C tests
make -j5 -C bld -C tests
fi
- name: 'build examples'
if: ${{ matrix.build == 'cmake' }} # skip for autotools to save time
run: |
PATH="$HOME/opt/mingw32ce/bin:$PATH"
if [ '${{ matrix.build }}' = 'cmake' ]; then
cmake --build bld --target curl-examples
else
make -C bld examples
make -j5 -C bld examples
fi
msvc:
@ -710,16 +697,16 @@ jobs:
strategy:
matrix:
include:
- name: 'openssl'
install: 'brotli zlib zstd nghttp2 nghttp3 openssl libssh2'
- name: 'schannel MultiSSL U'
install: 'brotli zlib zstd libpsl nghttp2 libssh2[core,zlib] pkgconf gsasl openssl mbedtls wolfssl'
arch: 'x64'
plat: 'uwp'
plat: 'windows'
type: 'Debug'
tflags: 'skiprun'
tflags: '~1516 ~2301 ~2302 ~2303 ~2307 ~2310'
config: >-
-DCURL_USE_LIBSSH2=ON
-DCURL_USE_SCHANNEL=OFF -DCURL_USE_OPENSSL=ON -DUSE_OPENSSL_QUIC=ON
-DCURL_USE_LIBPSL=OFF
-DCURL_USE_SCHANNEL=ON -DCURL_USE_OPENSSL=ON -DCURL_USE_MBEDTLS=ON -DCURL_USE_WOLFSSL=ON -DCURL_DEFAULT_SSL_BACKEND=schannel
-DCURL_USE_GSASL=ON -DUSE_WIN32_IDN=ON -DENABLE_UNICODE=ON -DUSE_SSLS_EXPORT=ON
- name: 'openssl'
install: 'brotli zlib zstd libpsl nghttp2 nghttp3 openssl libssh2 pkgconf gsasl c-ares libuv krb5'
@ -732,16 +719,16 @@ jobs:
-DCURL_USE_SCHANNEL=OFF -DCURL_USE_OPENSSL=ON -DUSE_OPENSSL_QUIC=ON
-DCURL_USE_GSASL=ON -DENABLE_ARES=ON -DCURL_USE_LIBUV=ON -DCURL_USE_GSSAPI=ON
- name: 'schannel MultiSSL U'
install: 'brotli zlib zstd libpsl nghttp2 libssh2[core,zlib] pkgconf gsasl openssl mbedtls wolfssl'
- name: 'openssl'
install: 'brotli zlib zstd nghttp2 nghttp3 openssl libssh2'
arch: 'x64'
plat: 'windows'
plat: 'uwp'
type: 'Debug'
tflags: '~1516 ~2301 ~2302 ~2303 ~2307 ~2310'
tflags: 'skiprun'
config: >-
-DCURL_USE_LIBSSH2=ON
-DCURL_USE_SCHANNEL=ON -DCURL_USE_OPENSSL=ON -DCURL_USE_MBEDTLS=ON -DCURL_USE_WOLFSSL=ON -DCURL_DEFAULT_SSL_BACKEND=schannel
-DCURL_USE_GSASL=ON -DUSE_WIN32_IDN=ON -DENABLE_UNICODE=ON -DUSE_SSLS_EXPORT=ON
-DCURL_USE_SCHANNEL=OFF -DCURL_USE_OPENSSL=ON -DUSE_OPENSSL_QUIC=ON
-DCURL_USE_LIBPSL=OFF
- name: 'libressl'
install: 'brotli zlib zstd libpsl nghttp2 libressl libssh2[core,zlib] pkgconf ngtcp2[libressl] nghttp3'
@ -840,6 +827,8 @@ jobs:
-DCMAKE_EXE_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
-DCMAKE_SHARED_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
-DCMAKE_VS_GLOBALS="TrackFileAccess=false${vsglobals}" \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE= \
-DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
-DBUILD_SHARED_LIBS=OFF \
@ -869,10 +858,10 @@ jobs:
- name: 'curl version'
timeout-minutes: 1
run: |
PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' -o -name '*.pdb' \) -exec file '{}' \;
PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' \) -exec file '{}' \;
if [ '${{ matrix.plat }}' != 'uwp' ]; then # Missing: ucrtbased.dll, VCRUNTIME140D.dll, VCRUNTIME140D_APP.dll
PATH="$PWD/bld/lib/${{ matrix.type }}:$PATH"
'bld/src/${{ matrix.type }}/curl.exe' --disable --version
PATH="$PWD/bld/lib:$PATH"
bld/src/curl.exe --disable --version
fi
- name: 'build tests'
@ -907,14 +896,13 @@ jobs:
if: ${{ matrix.tflags != 'skipall' && matrix.tflags != 'skiprun' }}
timeout-minutes: 10
run: |
export CURL_DIRSUFFIX='${{ matrix.type }}'
export TFLAGS='-j8 ~WebSockets ~SCP ~612 ${{ matrix.tflags }}'
if [[ '${{ matrix.install }}' = *'libssh2[core,zlib]'* ]]; then
TFLAGS+=' ~SFTP'
elif [[ '${{ matrix.install }}' = *'libssh '* ]]; then
TFLAGS+=' ~614' # 'SFTP pre-quote chmod' SFTP, pre-quote, directory
fi
PATH="$PWD/bld/lib/${{ matrix.type }}:$PATH:/c/Program Files (x86)/stunnel/bin:/c/Program Files/OpenSSH-Win64"
PATH="$PWD/bld/lib:$PATH:/c/Program Files (x86)/stunnel/bin:/c/Program Files/OpenSSH-Win64"
PATH="/c/msys64/usr/bin:$PATH"
cmake --build bld --config '${{ matrix.type }}' --target test-ci

View File

@ -87,10 +87,3 @@ macro(curl_required_libpaths _libpaths_arg)
list(APPEND CMAKE_REQUIRED_LINK_DIRECTORIES "${_libpaths_arg}")
endif()
endmacro()
# Pre-fill variables set by a check_type_size() call.
macro(curl_prefill_type_size _type _size)
set(HAVE_SIZEOF_${_type} TRUE)
set(SIZEOF_${_type} ${_size})
set(SIZEOF_${_type}_CODE "#define SIZEOF_${_type} ${_size}")
endmacro()

View File

@ -182,7 +182,6 @@ if(PICKY_COMPILER)
-Wold-style-declaration # gcc 4.3
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
-Wstrict-aliasing=3 # gcc 4.0
-ftree-vrp # gcc 4.3 (required for -Warray-bounds, included in -Wall)
)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
@ -205,7 +204,7 @@ if(PICKY_COMPILER)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
list(APPEND _picky_enable
-Warray-bounds=2 # clang 3.0 gcc 5.0 (clang default: -Warray-bounds)
-Warray-bounds=2 -ftree-vrp # clang 3.0 gcc 5.0 (clang default: -Warray-bounds)
)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)

View File

@ -44,6 +44,10 @@ if(MINGW)
set(HAVE_UTIME_H 1) # wrapper to sys/utime.h
set(HAVE_DIRENT_H 1)
set(HAVE_OPENDIR 1)
if(MINGW32CE)
set(HAVE_STRTOK_R 0)
set(HAVE_FILE_OFFSET_BITS 0)
endif()
else()
set(HAVE_LIBGEN_H 0)
set(HAVE_FTRUNCATE 0)
@ -74,6 +78,7 @@ else()
set(HAVE_SNPRINTF 0)
endif()
set(HAVE_BASENAME 0)
set(HAVE_FILE_OFFSET_BITS 0)
endif()
endif()
@ -191,37 +196,6 @@ set(STDC_HEADERS 1)
set(HAVE_SIZEOF_SUSECONDS_T 0)
set(HAVE_SIZEOF_SA_FAMILY_T 0)
if(MINGW OR MSVC)
curl_prefill_type_size("INT" 4)
curl_prefill_type_size("LONG" 4)
curl_prefill_type_size("LONG_LONG" 8)
curl_prefill_type_size("__INT64" 8)
curl_prefill_type_size("CURL_OFF_T" 8)
# CURL_SOCKET_T, SIZE_T: 8 for _WIN64, 4 otherwise
# TIME_T: 8 for _WIN64 or UCRT or MSVC and not Windows CE, 4 otherwise
# Also 4 for non-UCRT 32-bit when _USE_32BIT_TIME_T is set.
# mingw-w64 sets _USE_32BIT_TIME_T unless __MINGW_USE_VC2005_COMPAT is explicit defined.
if(MSVC)
set(HAVE_SIZEOF_SSIZE_T 0)
set(HAVE_FILE_OFFSET_BITS 0)
curl_prefill_type_size("OFF_T" 4)
curl_prefill_type_size("ADDRESS_FAMILY" 2)
else()
# SSIZE_T: 8 for _WIN64, 4 otherwise
if(MINGW64_VERSION)
if(NOT MINGW64_VERSION VERSION_LESS 3.0)
set(HAVE_FILE_OFFSET_BITS 1)
curl_prefill_type_size("OFF_T" 8)
endif()
if(NOT MINGW64_VERSION VERSION_LESS 2.0)
curl_prefill_type_size("ADDRESS_FAMILY" 2)
else()
set(HAVE_SIZEOF_ADDRESS_FAMILY 0)
endif()
endif()
endif()
endif()
if(WINCE) # Windows CE exceptions
set(HAVE_LOCALE_H 0)
set(HAVE_GETADDRINFO 0)
@ -230,15 +204,7 @@ if(WINCE) # Windows CE exceptions
set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 0)
set(HAVE_SIGNAL 0)
set(HAVE_SETMODE 0)
curl_prefill_type_size("CURL_SOCKET_T" 4)
curl_prefill_type_size("TIME_T" 4)
curl_prefill_type_size("SIZE_T" 4)
if(MINGW32CE)
set(HAVE_STRTOK_R 0)
set(HAVE__SETMODE 0)
set(HAVE_FILE_OFFSET_BITS 0)
set(HAVE_SIZEOF_ADDRESS_FAMILY 0)
curl_prefill_type_size("SSIZE_T" 4)
curl_prefill_type_size("OFF_T" 4)
endif()
endif()

View File

@ -217,6 +217,13 @@ option(ENABLE_ARES "Enable c-ares support" OFF)
option(CURL_DISABLE_INSTALL "Disable installation targets" OFF)
if(WIN32)
option(CURL_STATIC_CRT "Build libcurl with static CRT with MSVC (/MT)" OFF)
if(CURL_STATIC_CRT AND MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
string(APPEND CMAKE_C_FLAGS_RELEASE " -MT")
string(APPEND CMAKE_C_FLAGS_DEBUG " -MTd")
endif()
option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF)
if(WINDOWS_STORE OR WINCE)
set(ENABLE_UNICODE ON)
@ -257,10 +264,8 @@ if(WIN32)
if(MINGW64_VERSION)
string(REGEX MATCH "MINGW64_VERSION=[0-9]+\.[0-9]+" CURL_TEST_OUTPUT "${CURL_TEST_OUTPUT}")
string(REGEX REPLACE "MINGW64_VERSION=" "" MINGW64_VERSION "${CURL_TEST_OUTPUT}")
if(MINGW64_VERSION)
message(STATUS "Found MINGW64_VERSION=${MINGW64_VERSION}")
endif()
endif()
unset(MINGW64_VERSION CACHE) # Avoid storing in CMake cache
endif()
elseif(DOS OR AMIGA)
@ -349,19 +354,6 @@ else()
set(LIB_SELECTED ${LIB_STATIC})
endif()
if(WIN32)
option(CURL_STATIC_CRT "Build libcurl with static CRT with MSVC (/MT)" OFF)
if(CURL_STATIC_CRT AND MSVC)
if(BUILD_STATIC_CURL OR NOT BUILD_CURL_EXE)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
string(APPEND CMAKE_C_FLAGS_RELEASE " -MT")
string(APPEND CMAKE_C_FLAGS_DEBUG " -MTd")
else()
message(WARNING "Static CRT requires static or no curl executable.")
endif()
endif()
endif()
# Override to force-disable or force-enable the use of pkg-config.
if((UNIX AND NOT ANDROID AND (NOT APPLE OR CMAKE_SYSTEM_NAME MATCHES "Darwin")) OR
VCPKG_TOOLCHAIN OR
@ -827,6 +819,9 @@ if(CURL_USE_OPENSSL)
set(_openssl "AmiSSL")
else()
set(_openssl "OpenSSL")
if(OPENSSL_VERSION VERSION_LESS 1.1.1)
message(WARNING "OpenSSL ${OPENSSL_VERSION} does not support TLS 1.3.")
endif()
endif()
endif()
@ -1953,6 +1948,22 @@ endif()
# Some other minor tests
if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
include(CheckCCompilerFlag)
check_c_compiler_flag("-Wno-long-double" HAVE_C_FLAG_Wno_long_double)
if(HAVE_C_FLAG_Wno_long_double)
# The Mac version of GCC warns about use of long double. Disable it.
get_source_file_property(_mprintf_compile_flags "mprintf.c" COMPILE_FLAGS)
if(_mprintf_compile_flags)
string(APPEND _mprintf_compile_flags " -Wno-long-double")
else()
set(_mprintf_compile_flags "-Wno-long-double")
endif()
set_source_files_properties("mprintf.c" PROPERTIES
COMPILE_FLAGS ${_mprintf_compile_flags})
endif()
endif()
if(_cmake_try_compile_target_type_save)
set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_cmake_try_compile_target_type_save})
unset(_cmake_try_compile_target_type_save)
@ -1972,6 +1983,9 @@ if(WIN32)
set(USE_WIN32_LARGE_FILES ON)
endif()
# Use the manifest embedded in the Windows Resource
string(APPEND CMAKE_RC_FLAGS " -DCURL_EMBED_MANIFEST")
# We use crypto functions that are not available for UWP apps
if(NOT WINDOWS_STORE)
set(USE_WIN32_CRYPTO ON)
@ -1987,6 +2001,9 @@ if(WIN32)
endif()
if(MSVC)
# Disable default manifest added by CMake
string(APPEND CMAKE_EXE_LINKER_FLAGS " -MANIFEST:NO")
string(APPEND CMAKE_C_FLAGS " -MP") # Parallel compilation
endif()

View File

@ -4,15 +4,10 @@ curl and libcurl 8.13.0
Command line options: 267
curl_easy_setopt() options: 306
Public functions in libcurl: 96
Contributors: 3354
Contributors: 3349
This release includes the following changes:
o curl: add write-out variable 'tls_earlydata' [79]
o rustls: add support for CERTINFO [106]
o tool_getparam: make --url support a file with URLs [104]
o var: add a '64dec' function that can base64 decode a string [78]
o wolfssl: tls early data support [50]
This release includes the following bugfixes:
@ -21,111 +16,67 @@ This release includes the following bugfixes:
o asyn-thread: avoid the separate curl_mutex_t alloc [6]
o asyn-thread: do not allocate thread_data separately [21]
o asyn-thread: remove 'status' from struct Curl_async [36]
o build: add Windows CE / CeGCC support, with CI jobs [87]
o build: drop unused `getpart` tool [107]
o build: enable -Wjump-misses-init for GCC 4.5+ [62]
o build: fix compiler warnings in feature detections [39]
o build: set `HAVE_WRITABLE_ARGV` for Apple cross-builds [8]
o build: silence bogus `-Wconversion` warnings with gcc 5.1-5.4 [68]
o c-ares: error out for unsupported versions, drop unused macros [85]
o ca-native.md: sync with CURLSSLOPT_NATIVE_CA [72]
o cf-socket: deduplicate Windows Vista detection [11]
o client writer: handle pause before deocding [61]
o cmake: `SHARE_LIB_OBJECT=ON` requires CMake 3.12 or newer [46]
o cmake: add pre-fill for Unix, enable in GHA/macos, verify pre-fills [42]
o cmake: allow empty `IMPORT_LIB_SUFFIX`, add suffix collision detection [41]
o cmake: avoid `-Wnonnull` warning in `HAVE_FSETXATTR_5` detection [81]
o cmake: disable HTTPS-proxy as a feature if proxy is disabled [77]
o cmake: drop `CURL_DISABLE_TESTS` option [94]
o cmake: allow empty custom `IMPORT_LIB_SUFFIX`, add suffix collision detection [41]
o cmake: drop `HAVE_IN_ADDR_T` from pre-fill too
o cmake: drop two stray TLS feature checks for wolfSSL [9]
o cmake: fix `HAVE_ATOMIC`/`HAVE_STDATOMIC` pre-fill for clang-cl [28]
o cmake: fix ECH detection in custom-patched OpenSSL [32]
o cmake: hide empty `MINGW64_VERSION` output for mingw32ce [114]
o cmake: mention 'insecure' in the debug build warning [15]
o cmake: misc tidy-ups [38]
o cmake: pre-fill known type sizes for Windows OSes [100]
o cmake: restrict static CRT builds to static curl exe, test in CI [113]
o cmake: sync cutoff version with autotools for picky option `-ftree-vrp` [99]
o cmake: sync OpenSSL(-fork) feature checks with `./configure` [49]
o CODE_STYLE: readability and banned functions [35]
o configure: silence compiler warnings in feature checks, drop duplicates [86]
o configure: use `curl_cv_apple` variable [40]
o conn: fix connection reuse when SSL is optional [54]
o contributors.sh: lowercase 'github' for consistency [52]
o contrithanks.sh: update docs/THANKS in place [119]
o cookie: do prefix matching case-sensitively [82]
o cookie: minor parser simplification [58]
o cookie: simplify invalid_octets() [24]
o curl.h: change some enums to defines with L suffix [84]
o curl_msh3: remove verify bypass from DEBUGBUILDs [43]
o curl_trc: fix build with CURL_DISABLE_VERBOSE_STRINGS [109]
o CURLMOPT_SOCKETFUNCTION.md: add advice for socket callback invocation[69]
o CURLOPT_HTTPHEADER.md: add comments to the example [90]
o CURLOPT_HTTPHEADER.md: rephrases [108]
o docs: add FD_ZERO to curl_multi_fdset example [19]
o docs: bump `rustls` to 0.14.1 [111]
o docs: correct argument names & URL redirection [4]
o eventfd: allow use on all CPUs [93]
o gnutls: fix connection state check on handshake [80]
o hash: use single linked list for entries [57]
o hostip: make CURLOPT_RESOLVE support replacing IPv6 addresses [47]
o HTTP3.md: only speak about minimal versions [18]
o http: convert parsers to strparse [48]
o http: fix NTLM info message typo [22]
o http: fix the auth check [88]
o http: make the RTSP version check stricter [73]
o http: negotiation and room for alt-svc/https rr to navigate [64]
o http: version negotiation [45]
o http_aws_sigv4: use strparse more for parsing [55]
o https-rr: implementation improvements [44]
o httpsrr: fix port detection [51]
o httpsrr: fix the HTTPS-RR threaded-resolver build combo [67]
o INSTALL-CMAKE.md: CMake usage updates [101]
o INSTALL-CMAKE.md: mention `ZLIB_USE_STATIC_LIBS` [112]
o lib: better optimized casecompare() and ncasecompare() [3]
o lib: simplify more white space loops [60]
o lib: strtoofft.h header cleanup [17]
o lib: use Curl_str_* instead of strtok_r() [59]
o lib: use Curl_str_number() for parsing decimal numbers [13]
o libtest/libprereq.c: set CURLOPT_FOLLOWLOCATION with a long [89]
o managen: correct the warning for un-escaped '<' and '>' [1]
o msvc: drop support for VS2005 and older [96]
o multi: event based rework [74]
o openssl: check return value of X509_get0_pubkey [105]
o openssl: drop support for old OpenSSL/LibreSSL versions [95]
o openssl: remove bad `goto`s into other scope [63]
o runtests: drop recognizing 'winssl' as Schannel [102]
o runtests: drop ref to unused external function
o runtests: recognize AWS-LC as OpenSSL [103]
o runtests: support multi-target cmake, drop workarounds from CI [116]
o schannel: deduplicate Windows Vista detection [98]
o schannel: enable ALPN support under WINE 6.0+ [92]
o schannel: enable ALPN with MinGW, fix ALPN for UWP builds [71]
o schannel: guard ALPN init code to ALPN builds [91]
o scripts/managen: fix option 'single' [31]
o scripts/managen: fix parsing of markdown code sections [30]
o setopt: remove unnecesary void pointer typecasts [76]
o ssh: consider sftp quote commands case sensitive [33]
o ssl session cache: add exportable flag [56]
o strparse: make Curl_str_number() return error for no digits [14]
o strparse: switch the API to work on 'const char *' [2]
o strparse: switch to curl_off_t as base data type [7]
o tests: fix enum/int confusion, fix autotools `CFLAGS` for `servers` [27]
o tidy-up: align MSYS2/Cygwin codepaths, follow Cygwin `MAX_PID` bump [97]
o tests: fix enum/int confusion (Intel C), fix autotools `CFLAGS` for `servers` [27]
o tidy-up: delete, comment or scope C macros reported unused [16]
o tidy-up: drop unused `CURL_INADDR_NONE` macro and `in_addr_t` type [26]
o tidy-up: use `CURL_ARRAYSIZE()` [37]
o timediff: fix comment for curlx_mstotv() [25]
o timediff: remove unnecessary double typecast [53]
o tool_getparam: clear sensitive arguments better [66]
o tool_operate: fail SSH transfers without server auth [70]
o urlapi: simplify junkscan [23]
o variable.md: clarify 'trim' example [12]
o windows: drop code and curl manifest targeting W2K and older [115]
o wolfssh: retrieve the error using wolfSSH_get_error [5]
o wolfssl: fix CA certificate multiple location import [34]
o wolfssl: warn if CA native import option is ignored [65]
o wolfssl: when using PQ KEM, use ML-KEM, not Kyber [10]
This release includes the following known bugs:
@ -147,13 +98,12 @@ Planned upcoming removals include:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Anthony Hu, Dan Fandrich, Daniel Stenberg, dependabot[bot], Derek Huang,
Dexter Gerig, Harry Sintonen, Jeremy Drake, John Bampton, Joseph Chen,
kayrus on github, kriztalz, Laurențiu Nicola, lf- on github, Marcel Raad,
Mark Phillips, qhill on github, Ray Satiro, renovate[bot], rmg-x on github,
RubisetCie on github, Sergey, Stefan Eissing, Tianyi Song, Timo Tijhof,
Viktor Szakats, Yedaya Katsman, Zenju on github
(28 contributors)
Anthony Hu, Daniel Stenberg, dependabot[bot], Dexter Gerig, Harry Sintonen,
John Bampton, Joseph Chen, kayrus on github, kriztalz, lf- on github,
Marcel Raad, Mark Phillips, Ray Satiro, rmg-x on github,
RubisetCie on Github, Sergey, Stefan Eissing, Viktor Szakats,
Zenju on github
(19 contributors)
References to bug reports and discussions on issues:
@ -204,11 +154,8 @@ References to bug reports and discussions on issues:
[45] = https://curl.se/bug/?i=16100
[46] = https://curl.se/bug/?i=16375
[47] = https://curl.se/bug/?i=16357
[48] = https://curl.se/bug/?i=16436
[49] = https://curl.se/bug/?i=16352
[50] = https://curl.se/bug/?i=16167
[51] = https://curl.se/bug/?i=16409
[52] = https://curl.se/bug/?i=16443
[53] = https://curl.se/bug/?i=16367
[54] = https://curl.se/bug/?i=16384
[55] = https://curl.se/bug/?i=16366
@ -221,53 +168,8 @@ References to bug reports and discussions on issues:
[62] = https://curl.se/bug/?i=16252
[63] = https://curl.se/bug/?i=16356
[64] = https://curl.se/bug/?i=16117
[65] = https://curl.se/bug/?i=16417
[66] = https://curl.se/bug/?i=16396
[67] = https://curl.se/bug/?i=16399
[68] = https://curl.se/bug/?i=16398
[69] = https://curl.se/bug/?i=16441
[70] = https://curl.se/bug/?i=16205
[71] = https://curl.se/bug/?i=16385
[72] = https://curl.se/bug/?i=16373
[73] = https://curl.se/bug/?i=16435
[74] = https://curl.se/bug/?i=16308
[76] = https://curl.se/bug/?i=16426
[77] = https://curl.se/bug/?i=16434
[78] = https://curl.se/bug/?i=16330
[79] = https://curl.se/bug/?i=15956
[80] = https://curl.se/bug/?i=16423
[81] = https://curl.se/bug/?i=16427
[82] = https://curl.se/bug/?i=16494
[84] = https://curl.se/bug/?i=16482
[85] = https://curl.se/bug/?i=16407
[86] = https://curl.se/bug/?i=16377
[87] = https://curl.se/bug/?i=15975
[88] = https://curl.se/bug/?i=16419
[89] = https://curl.se/bug/?i=16487
[90] = https://curl.se/bug/?i=16488
[91] = https://curl.se/bug/?i=16420
[92] = https://curl.se/bug/?i=16393
[93] = https://curl.se/bug/?i=16277
[94] = https://curl.se/bug/?i=16134
[95] = https://curl.se/bug/?i=16104
[96] = https://curl.se/bug/?i=16004
[97] = https://curl.se/bug/?i=16217
[98] = https://curl.se/bug/?i=16408
[99] = https://curl.se/bug/?i=16478
[100] = https://curl.se/bug/?i=16464
[101] = https://curl.se/bug/?i=16329
[102] = https://curl.se/bug/?i=16467
[103] = https://curl.se/bug/?i=16466
[104] = https://curl.se/bug/?i=16099
[105] = https://curl.se/bug/?i=16468
[106] = https://curl.se/bug/?i=16459
[107] = https://curl.se/bug/?i=16460
[108] = https://curl.se/bug/?i=16461
[109] = https://curl.se/bug/?i=16462
[111] = https://curl.se/bug/?i=16446
[112] = https://curl.se/bug/?i=16457
[113] = https://curl.se/bug/?i=16456
[114] = https://curl.se/bug/?i=16455
[115] = https://curl.se/bug/?i=16453
[116] = https://curl.se/bug/?i=16452
[119] = https://curl.se/bug/?i=16448

View File

@ -36,8 +36,6 @@ esac
if [ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2022' ]; then
openssl_root_win="C:/OpenSSL-v34${openssl_suffix}"
elif [ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2019' ]; then
openssl_root_win="C:/OpenSSL-v11${openssl_suffix}"
elif [ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2013' ]; then
openssl_root_win="C:/OpenSSL${openssl_suffix}"
else
openssl_root_win="C:/OpenSSL-v111${openssl_suffix}"
@ -54,49 +52,35 @@ if [ "${BUILD_SYSTEM}" = 'CMake' ]; then
[ -n "${TOOLSET:-}" ] && options+=" -T ${TOOLSET}"
[ "${OPENSSL}" = 'ON' ] && options+=" -DOPENSSL_ROOT_DIR=${openssl_root_win}"
[ -n "${CURLDEBUG:-}" ] && options+=" -DENABLE_CURLDEBUG=${CURLDEBUG}"
if [ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2013' ]; then
mkdir "_bld${_chkprefill}"
cd "_bld${_chkprefill}"
options+=' ..'
root='..'
else
options+=" -B _bld${_chkprefill}"
options+=' -DCMAKE_VS_GLOBALS=TrackFileAccess=false'
options+=" -DCMAKE_UNITY_BUILD=${UNITY}"
root='.'
fi
# shellcheck disable=SC2086
time cmake -G "${PRJ_GEN}" ${TARGET} \
-DCURL_TEST_BUNDLES=ON \
cmake -B "_bld${_chkprefill}" -G "${PRJ_GEN}" ${TARGET} \
-DCMAKE_VS_GLOBALS=TrackFileAccess=false \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE= \
-DCMAKE_UNITY_BUILD="${UNITY}" -DCURL_TEST_BUNDLES=ON \
-DCURL_WERROR=ON \
-DBUILD_SHARED_LIBS="${SHARED}" \
-DCURL_STATIC_CRT=ON \
-DENABLE_DEBUG="${DEBUG}" \
-DENABLE_UNICODE="${ENABLE_UNICODE}" \
-DHTTP_ONLY="${HTTP_ONLY}" \
-DCURL_USE_SCHANNEL="${SCHANNEL}" \
-DCURL_USE_OPENSSL="${OPENSSL}" \
-DCURL_USE_LIBPSL=OFF \
${options} \
|| { cat ${root}/_bld/CMakeFiles/CMake* 2>/dev/null; false; }
[ "${APPVEYOR_BUILD_WORKER_IMAGE}" = 'Visual Studio 2013' ] && cd ..
${options}
done
if [ -d _bld_chkprefill ] && ! diff -u _bld/lib/curl_config.h _bld_chkprefill/lib/curl_config.h; then
cat _bld_chkprefill/CMakeFiles/CMake* 2>/dev/null || true
cat _bld_chkprefill/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
false
fi
if false; then
cat _bld/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
fi
echo 'curl_config.h'; grep -F '#define' _bld/lib/curl_config.h | sort || true
# shellcheck disable=SC2086
if ! time cmake --build _bld --config "${PRJ_CFG}" --parallel 2 -- ${BUILD_OPT:-}; then
if [ "${PRJ_GEN}" = 'Visual Studio 9 2008' ]; then
find . -name BuildLog.htm -exec dos2unix '{}' +
find . -name BuildLog.htm -exec cat '{}' +
fi
false
fi
[ "${SHARED}" = 'ON' ] && PATH="$PWD/_bld/lib/${PRJ_CFG}:$PATH"
[ "${OPENSSL}" = 'ON' ] && { PATH="${openssl_root}:$PATH"; cp "${openssl_root}"/*.dll "_bld/src/${PRJ_CFG}"; }
curl="_bld/src/${PRJ_CFG}/curl.exe"
cmake --build _bld --config "${PRJ_CFG}" --parallel 2 -- ${BUILD_OPT:-}
[ "${SHARED}" = 'ON' ] && PATH="$PWD/_bld/lib:$PATH"
[ "${OPENSSL}" = 'ON' ] && PATH="${openssl_root}:$PATH"
curl='_bld/src/curl.exe'
elif [ "${BUILD_SYSTEM}" = 'VisualStudioSolution' ]; then
(
cd projects
@ -129,7 +113,7 @@ EOF
curl="builds/libcurl-vc14.10-x64-${PATHPART}-dll-ssl-dll-ipv6-sspi/bin/curl.exe"
fi
find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' -o -name '*.pdb' \) -exec file '{}' \;
find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' \) -exec file '{}' \;
if [ -z "${SKIP_RUN:-}" ]; then
"${curl}" --disable --version
else
@ -140,14 +124,13 @@ fi
if [ "${TFLAGS}" != 'skipall' ] && \
[ "${BUILD_SYSTEM}" = 'CMake' ]; then
time cmake --build _bld --config "${PRJ_CFG}" --parallel 2 --target testdeps
cmake --build _bld --config "${PRJ_CFG}" --parallel 2 --target testdeps
fi
# run tests
if [ "${TFLAGS}" != 'skipall' ] && \
[ "${TFLAGS}" != 'skiprun' ]; then
export CURL_DIRSUFFIX="${PRJ_CFG}"
if [ -x "$(cygpath "${SYSTEMROOT}/System32/curl.exe")" ]; then
TFLAGS+=" -ac $(cygpath "${SYSTEMROOT}/System32/curl.exe")"
elif [ -x "$(cygpath 'C:/msys64/usr/bin/curl.exe')" ]; then
@ -155,12 +138,12 @@ if [ "${TFLAGS}" != 'skipall' ] && \
fi
TFLAGS+=' -j0'
if [ "${BUILD_SYSTEM}" = 'CMake' ]; then
time cmake --build _bld --config "${PRJ_CFG}" --target test-ci
cmake --build _bld --config "${PRJ_CFG}" --target test-ci
else
(
TFLAGS="-a -p !flaky -r -rm ${TFLAGS}"
cd _bld/tests
time ./runtests.pl
./runtests.pl
)
fi
fi
@ -169,5 +152,5 @@ fi
if [ "${EXAMPLES}" = 'ON' ] && \
[ "${BUILD_SYSTEM}" = 'CMake' ]; then
time cmake --build _bld --config "${PRJ_CFG}" --parallel 2 --target curl-examples
cmake --build _bld --config "${PRJ_CFG}" --parallel 2 --target curl-examples
fi

View File

@ -31,11 +31,8 @@
version: 7.50.0.{build}
environment:
BUILD_SYSTEM: CMake
UNITY: 'ON'
OPENSSL: 'OFF'
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
DEBUG: 'ON'
SHARED: 'OFF'
HTTP_ONLY: 'OFF'
@ -48,77 +45,89 @@ environment:
- job_name: 'CMake, VS2022, Release, x64, OpenSSL 3.4, Shared, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A x64'
PRJ_CFG: Release
OPENSSL: 'ON'
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
SHARED: 'ON'
- job_name: 'CMake, VS2022, Release, arm64, Schannel, Static, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A ARM64'
PRJ_CFG: Release
SCHANNEL: 'ON'
ENABLE_UNICODE: 'OFF'
DEBUG: 'OFF'
CURLDEBUG: 'ON'
- job_name: 'CMake, VS2008, Debug, x86, OpenSSL 1.0.2 + Schannel, Shared, Build-tests & examples'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2013'
PRJ_GEN: 'Visual Studio 9 2008'
TARGET: '-A Win32'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'ON'
SHARED: 'ON'
EXAMPLES: 'ON'
- job_name: 'CMake, VS2010, Debug, x64, Schannel, Shared, Build-tests & examples'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 10 2010'
TARGET: '-A x64'
PRJ_CFG: Debug
SCHANNEL: 'ON'
ENABLE_UNICODE: 'OFF'
SHARED: 'ON'
EXAMPLES: 'ON'
- job_name: 'CMake, VS2012, Release, x86, OpenSSL 1.1.1 + Schannel, Shared, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 11 2012'
TARGET: '-A Win32'
PRJ_CFG: Release
OPENSSL: 'ON'
SCHANNEL: 'ON'
ENABLE_UNICODE: 'OFF'
SHARED: 'ON'
- job_name: 'CMake, VS2013, Debug, x64, OpenSSL 1.1.1, Shared, Build-only'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 12 2013'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
SHARED: 'ON'
TFLAGS: 'skipall'
- job_name: 'CMake, VS2015, Debug, x64, OpenSSL 1.1.1, Static, Build-only'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 14 2015'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
TFLAGS: 'skipall'
- job_name: 'CMake, VS2017, Debug, x64, OpenSSL 1.1.1, Shared, Build-only'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2017'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 15 2017'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
SHARED: 'ON'
TFLAGS: 'skipall'
- job_name: 'CMake, VS2019, Debug, x64, OpenSSL 1.1.0 + Schannel, Shared, Build-tests'
- job_name: 'CMake, VS2019, Debug, x64, OpenSSL 1.0.2 + Schannel, Shared, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2019'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 16 2019'
TARGET: '-A x64'
PRJ_CFG: Debug
OPENSSL: 'ON'
SCHANNEL: 'ON'
ENABLE_UNICODE: 'OFF'
SHARED: 'ON'
- job_name: 'CMake, VS2022, Debug, x64, Schannel, Static, Unicode, Build-tests & examples, clang-cl'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A x64'
PRJ_CFG: Debug
@ -128,6 +137,7 @@ environment:
TOOLSET: 'ClangCl'
- job_name: 'CMake, VS2022, Debug, x64, Schannel, Static, Unicode, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A x64'
PRJ_CFG: Debug
@ -135,6 +145,7 @@ environment:
ENABLE_UNICODE: 'ON'
- job_name: 'CMake, VS2022, Release, x64, Schannel, Shared, Unicode, DEBUGBUILD, no-CURLDEBUG, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A x64'
PRJ_CFG: Release
@ -144,14 +155,20 @@ environment:
CURLDEBUG: 'OFF'
- job_name: 'CMake, VS2022, Debug, x64, no SSL, Static, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A x64'
PRJ_CFG: Debug
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
- job_name: 'CMake, VS2022, Debug, x64, no SSL, Static, HTTP only, Build-tests'
APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2022'
BUILD_SYSTEM: CMake
PRJ_GEN: 'Visual Studio 17 2022'
TARGET: '-A x64'
PRJ_CFG: Debug
SCHANNEL: 'OFF'
ENABLE_UNICODE: 'OFF'
HTTP_ONLY: 'ON'
# winbuild-based builds
@ -237,5 +254,5 @@ skip_commits:
#artifacts:
# - path: '**/curl.exe'
# name: curl
# - path: '**/*.dll'
# - path: '**/*curl*.dll'
# name: libcurl dll

View File

@ -21,12 +21,6 @@ CMake's GUIs.
A CMake configuration of curl is similar to the autotools build of curl.
It consists of the following steps after you have unpacked the source.
We recommend building with CMake on Windows. For instructions on migrating
from the `projects/Windows` Visual Studio solution files, see
[this section](#migrating-from-visual-studio-ide-project-files). For
instructions on migrating from the winbuild builds, see
[the following section](#migrating-from-winbuild-builds).
## Using `cmake`
You can configure for in source tree builds or for a build tree
@ -37,14 +31,10 @@ that is apart from the source tree.
$ cmake -B .
- Build in a separate directory (parallel to the curl source tree in this
example). The build directory is created for you. This is recommended over
building in the source tree to separate source and build artifacts.
example). The build directory is created for you.
$ cmake -B ../curl-build
For the full list of CMake build configuration variables see
[the corresponding section](#cmake-build-options).
### Fallback for CMake before version 3.13
CMake before version 3.13 does not support the `-B` option. In that case,
@ -139,12 +129,6 @@ Install to default location (you have to specify the build directory).
$ cmake --install ../curl-build
Do not use `--prefix` to change the installation prefix as the output produced
by the `curl-config` script is determined at CMake configure time. If you want
to set a custom install prefix for curl, set
[`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)
when configuring the CMake build.
### Fallback for CMake before version 3.15
CMake before version 3.15 does not support the `--install` option. In that
@ -155,68 +139,6 @@ assumes that CMake generates `Makefile`:
$ cd ../curl-build
$ make install
# CMake usage
Just as curl can be built and installed using CMake, it can also be used from
CMake.
## Using `find_package`
To locate libcurl from CMake, one can use the standard
[`find_package`](https://cmake.org/cmake/help/latest/command/find_package.html)
command in the typical fashion:
```cmake
find_package(CURL 8.12.0 REQUIRED) # FATAL_ERROR if CURL is not found
```
This invokes the CMake-provided
[FindCURL](https://cmake.org/cmake/help/latest/module/FindCURL.html) find module,
which first performs a search using the `find_package`
[config mode](https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure).
This is supported by the `CURLConfig.cmake` CMake config script which is
available if the given CURL was built and installed using CMake.
### Detecting CURL features/protocols
Since version 8.12.0, `CURLConfig.cmake` publishes the supported CURL features
and protocols (see [release notes](https://curl.se/ch/8.12.0.html)). These can
be specified using the `find_package` keywords `COMPONENTS` and
`OPTIONAL_COMPONENTS`, with protocols in all caps, e.g. `HTTPS`, `LDAP`, while
features should be in their original sentence case, e.g. `AsynchDNS`,
`UnixSockets`. If any of the `COMPONENTS` are missing, then CURL is considered
as *not* found.
Here is an example of using `COMPONENTS` and `OPTIONAL_COMPONENTS` in
`find_package` with CURL:
```cmake
# CURL_FOUND is FALSE if no HTTPS but brotli and zstd can be missing
find_package(CURL 8.12.0 COMPONENTS HTTPS OPTIONAL_COMPONENTS brotli zstd)
```
One can also check the defined `CURL_SUPPORTS_<feature-or-protocol>` variables
if a particular feature/protocol is supported. For example:
```cmake
# check HTTPS
if(CURL_SUPPORTS_HTTPS)
message(STATUS "CURL supports HTTPS")
else()
message(STATUS "CURL does NOT support HTTPS")
endif()
```
### Linking against libcurl
To link a CMake target against libcurl one can use
[`target_link_libraries`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html)
as usual:
```cmake
target_link_libraries(my_target PRIVATE CURL::libcurl)
```
# CMake build options
- `BUILD_CURL_EXE`: Build curl executable. Default: `ON`
@ -238,7 +160,7 @@ target_link_libraries(my_target PRIVATE CURL::libcurl)
- `CURL_LIBCURL_VERSIONED_SYMBOLS`: Enable libcurl versioned symbols. Default: `OFF`
- `CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX`: Override default versioned symbol prefix. Default: `<TLS-BACKEND>_` or `MULTISSL_`
- `CURL_LTO`: Enable compiler Link Time Optimizations. Default: `OFF`
- `CURL_STATIC_CRT`: Build libcurl with static CRT with MSVC (`/MT`) (requires static or no curl executable). Default: `OFF`
- `CURL_STATIC_CRT`: Build libcurl with static CRT with MSVC (`/MT`). Default: `OFF`
- `CURL_TARGET_WINDOWS_VERSION`: Minimum target Windows version as hex string.
- `CURL_TEST_BUNDLES`: Bundle `libtest` and `unittest` tests into single binaries. Default: `OFF`
- `CURL_WERROR`: Turn compiler warnings into errors. Default: `OFF`
@ -384,7 +306,6 @@ Details via CMake
- `OPENSSL_USE_STATIC_LIBS`: Look for static OpenSSL libraries.
- `ZLIB_INCLUDE_DIR`: The zlib include directory.
- `ZLIB_LIBRARY`: Path to `zlib` library.
- `ZLIB_USE_STATIC_LIBS`: Look for static ZLIB library (requires CMake v3.24).
## Dependency options
@ -458,7 +379,7 @@ Details via CMake
# Migrating from Visual Studio IDE Project Files
We recommend using CMake to build curl with MSVC.
We recommend CMake to build curl with MSVC.
The project build files reside in project/Windows/VC\* for VS2010, VS2010 and
VS2013 respectively.
@ -478,8 +399,8 @@ Configuration element | Equivalent CMake options
`Win32` | `-A Win32`
`DLL` | `BUILD_SHARED_LIBS=ON`, `BUILD_STATIC_LIBS=OFF`, (default)
`LIB` | `BUILD_SHARED_LIBS=OFF`, `BUILD_STATIC_LIBS=ON`
`Debug` | `CMAKE_BUILD_TYPE=Debug` (`-G "NMake Makefiles"` only)
`Release` | `CMAKE_BUILD_TYPE=Release` (`-G "NMake Makefiles"` only)
`Debug` | `CMAKE_BUILD_TYPE=Debug`
`Release` | `CMAKE_BUILD_TYPE=Release`
`DLL Windows SSPI` | `CURL_USE_SCHANNEL=ON` (with SSPI enabled by default)
`DLL OpenSSL` | `CURL_USE_OPENSSL=ON`, optional: `OPENSSL_ROOT_DIR`, `OPENSSL_USE_STATIC_LIBS=ON`
`DLL libssh2` | `CURL_USE_LIBSSH2=ON`, optional: `LIBSSH2_INCLUDE_DIR`, `LIBSSH2_LIBRARY`
@ -493,13 +414,7 @@ For example these commands:
translate to:
> cmake . -G "Visual Studio 12 2013" -A x64 -DCURL_USE_SCHANNEL=ON -DUSE_WIN32_IDN=ON -DCURL_USE_LIBPSL=OFF
> cmake --build . --config Debug --parallel
We do *not* specify `-DCMAKE_BUILD_TYPE=Debug` here as we might do for the
`"NMake Makefiles"` generator because the Visual Studio generators are
[multi-config generators](https://cmake.org/cmake/help/latest/prop_gbl/GENERATOR_IS_MULTI_CONFIG.html)
and therefore ignore the value of `CMAKE_BUILD_TYPE`.
> cmake . -G "Visual Studio 12 2013" -A x64 -DCMAKE_BUILD_TYPE=Debug -DCURL_USE_SCHANNEL=ON -DUSE_WIN32_IDN=ON -DCURL_USE_LIBPSL=OFF
# Migrating from winbuild builds
@ -522,7 +437,7 @@ winbuild options | Equivalent CMake options
`DEBUG` | `CMAKE_BUILD_TYPE=Debug`
`GEN_PDB` | `CMAKE_EXE_LINKER_FLAGS=/Fd<path>`, `CMAKE_SHARED_LINKER_FLAGS=/Fd<path>`
`LIB_NAME_DLL`, `LIB_NAME_STATIC` | `IMPORT_LIB_SUFFIX`, `LIBCURL_OUTPUT_NAME`, `STATIC_LIB_SUFFIX`
`VC`: `<N>` | see the CMake [Visual Studio generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators)
`VC` | see CMake `-G` [options](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html)
`MACHINE`: `x64`, `x86` | `-A x64`, `-A Win32`
`MODE`: `dll`, `static` | `BUILD_SHARED_LIBS=ON/OFF`, `BUILD_STATIC_LIBS=ON/OFF`, `BUILD_STATIC_CURL=ON/OFF` (default: dll)
`RTLIBCFG`: `static` | `CURL_STATIC_CRT=ON`
@ -552,8 +467,4 @@ For example this command-line:
translates to:
> cmake . -G "Visual Studio 17 2022" -A x64 -DBUILD_SHARED_LIBS=ON -DOPENSSL_ROOT_DIR=C:\OpenSSL -DCURL_USE_OPENSSL=ON -DENABLE_UNICODE=ON -DCURL_USE_LIBPSL=OFF
> cmake --build . --config Debug
We use `--config` with `cmake --build` because the Visual Studio CMake
generators are multi-config and therefore ignore `CMAKE_BUILD_TYPE`.
> cmake . -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON -DOPENSSL_ROOT_DIR=C:\OpenSSL -DCURL_USE_OPENSSL=ON -DENABLE_UNICODE=ON -DCURL_USE_LIBPSL=OFF

View File

@ -9,7 +9,7 @@ SPDX-License-Identifier: curl
[Rustls is a TLS backend written in Rust](https://docs.rs/rustls/). curl can
be built to use it as an alternative to OpenSSL or other TLS backends. We use
the [rustls-ffi C bindings](https://github.com/rustls/rustls-ffi/). This
version of curl is compatible with `rustls-ffi` v0.14.x.
version of curl depends on version v0.14.0 of rustls-ffi.
# Building with Rustls
@ -17,7 +17,7 @@ First, [install Rust](https://rustup.rs/).
Next, check out, build, and install the appropriate version of rustls-ffi:
% git clone https://github.com/rustls/rustls-ffi -b v0.14.1
% git clone https://github.com/rustls/rustls-ffi -b v0.14.0
% cd rustls-ffi
% make
% make DESTDIR=${HOME}/rustls-ffi-built/ install

View File

@ -157,4 +157,3 @@ s/edmcln\z/edmcln on github/
s/andrewkirillov-ibm/Andrew Kirillov/
s/\(.*\) via #[0-9]*//
s/jethrogb$/jethrogb on github/
s/on github/on github/i

View File

@ -247,11 +247,11 @@ local system or network, the bar is raised. If a local user wrongfully has
elevated rights on your system enough to attack curl, they can probably
already do much worse harm and the problem is not really in curl.
## Debug & Experiments
## Experiments
Vulnerabilities in features which are off by default (in the build) and
documented as experimental, or exist only in debug mode, are not eligible for a
reward and we do not consider them security problems.
documented as experimental, are not eligible for a reward and we do not
consider them security problems.
## URL inconsistencies

View File

@ -59,4 +59,4 @@ used.
Doing FTP over an HTTP proxy without --proxytunnel makes curl do HTTP with an
FTP URL over the proxy. For such transfers, common FTP specific options do not
work, including --ssl-reqd and --ftp-ssl-control.
work, including --ftp-ssl-reqd and --ftp-ssl-control.

View File

@ -2,19 +2,16 @@
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
SPDX-License-Identifier: curl
Long: url
Arg: <url/file>
Help: URL(s) to work with
Arg: <url>
Help: URL to work with
Category: curl
Added: 7.5
Multi: append
See-also:
- next
- config
- path-as-is
- disallow-username-in-url
Example:
- --url $URL
- --url @file
---
# `--url`
@ -35,15 +32,3 @@ destination option unless --remote-name-all is used.
On Windows, `file://` accesses can be converted to network accesses by the
operating system.
Starting in curl 8.13.0, curl can be told to download URLs provided in a text
file, one URL per line. It is done by with `--url @filename`: so instead of a
URL, you specify a filename prefixed with the `@` symbol. It can be told to
load the list of URLs from stdin by providing an argument like `@-`.
When downloading URLs given in a file, it implies using --remote-name for each
provided URL. The URLs are full, there is no globbing applied or done on
these. Features such as --skip-existing work fine in combination with this.
Lines in the URL file that start with `#` are treated as comments and are
skipped.

View File

@ -62,7 +62,7 @@ The variables available are:
## `certs`
Output the certificate chain with details. Supported only by the OpenSSL,
GnuTLS, Schannel, Rustls, and Secure Transport backends. (Added in 7.88.0)
GnuTLS, Schannel and Secure Transport backends. (Added in 7.88.0)
## `conn_id`
The connection identifier last used by the transfer. The connection id is
@ -128,7 +128,7 @@ The http method used in the most recent HTTP request. (Added in 7.72.0)
## `num_certs`
Number of server certificates received in the TLS handshake. Supported only by
the OpenSSL, GnuTLS, Schannel, Rustls and Secure Transport backends.
the OpenSSL, GnuTLS, Schannel and Secure Transport backends.
(Added in 7.88.0)
## `num_connects`

View File

@ -24,53 +24,53 @@ displays information about the curl and libcurl installation.
# OPTIONS
## `--ca`
## --ca
Displays the built-in path to the CA cert bundle this libcurl uses.
## `--cc`
## --cc
Displays the compiler used to build libcurl.
## `--cflags`
## --cflags
Set of compiler options (CFLAGS) to use when compiling files that use
libcurl. Currently that is only the include path to the curl include files.
## `--checkfor [version]`
## --checkfor [version]
Specify the oldest possible libcurl version string you want, and this script
returns 0 if the current installation is new enough or it returns 1 and
outputs a text saying that the current version is not new enough. (Added in
7.15.4)
## `--configure`
## --configure
Displays the arguments given to configure when building curl.
## `--feature`
## --feature
Lists what particular main features the installed libcurl was built with. At
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
any particular order. The keywords are separated by newlines. There may be
none, one, or several keywords in the list.
## `--help`
## --help
Displays the available options.
## `--libs`
## --libs
Shows the complete set of libs and other linker options you need in order to
link your application with libcurl.
## `--prefix`
## --prefix
This is the prefix used when libcurl was installed. libcurl is then installed
in $prefix/lib and its header files are installed in $prefix/include and so
on. The prefix is set with `configure --prefix`.
on. The prefix is set with "configure --prefix".
## `--protocols`
## --protocols
Lists what particular protocols the installed libcurl was built to support. At
the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
@ -78,22 +78,22 @@ TELNET, LDAP, DICT and many more. Do not assume any particular order. The
protocols are listed using uppercase and are separated by newlines. There may
be none, one, or several protocols in the list. (Added in 7.13.0)
## `--ssl-backends`
## --ssl-backends
Lists the SSL backends that were enabled when libcurl was built. It might be
no, one or several names. If more than one name, they appear comma-separated.
(Added in 7.58.0)
## `--static-libs`
## --static-libs
Shows the complete set of libs and other linker options you need in order to
link your application with libcurl statically. (Added in 7.17.1)
## `--version`
## --version
Outputs version information about the installed libcurl.
## `--vernum`
## --vernum
Outputs version information about the installed libcurl, in numerical mode.
This shows the version number, in hexadecimal, using 8 bits for each part:
@ -104,21 +104,22 @@ omitted. (This option was broken in the 7.15.0 release.)
# EXAMPLES
What linker options do I need when I link with libcurl?
~~~
$ curl-config --libs
~~~
What compiler options do I need when I compile using libcurl functions?
~~~
$ curl-config --cflags
~~~
How do I know if libcurl was built with SSL support?
~~~
$ curl-config --feature | grep SSL
~~~
What's the installed libcurl version?
~~~
$ curl-config --version
~~~
How do I build a single file with a one-line command?
~~~
$ `curl-config --cc --cflags` -o example source.c `curl-config --libs`
~~~

View File

@ -298,19 +298,14 @@ int main(void)
filter = (struct connection_filter *)calloc(1, sizeof(*filter));
if(!filter)
return 1;
exit(1);
if(curl_global_init(CURL_GLOBAL_DEFAULT)) {
free(filter);
return 1;
}
if(curl_global_init(CURL_GLOBAL_DEFAULT))
exit(1);
curl = curl_easy_init();
if(!curl) {
curl_global_cleanup();
free(filter);
return 1;
}
if(!curl)
exit(1);
/* Set the target URL */
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost");

View File

@ -79,12 +79,12 @@ int main(int argc, char *argv[])
fprintf(stderr,
"\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
appname);
return 1;
exit(1);
case 'v':
case 'V':
fprintf(stderr, "\r%s %s - %s\n",
appname, CHKSPEED_VERSION, curl_version());
return 1;
exit(1);
case 'a':
case 'A':
prtall = 1;

View File

@ -34,7 +34,8 @@
#include <curl/curl.h>
#include <curl/mprintf.h>
static int print_cookies(CURL *curl)
static void
print_cookies(CURL *curl)
{
CURLcode res;
struct curl_slist *cookies;
@ -46,7 +47,7 @@ static int print_cookies(CURL *curl)
if(res != CURLE_OK) {
fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n",
curl_easy_strerror(res));
return 1;
exit(1);
}
nc = cookies;
i = 1;
@ -59,8 +60,6 @@ static int print_cookies(CURL *curl)
printf("(none)\n");
}
curl_slist_free_all(cookies);
return 0;
}
int

View File

@ -418,22 +418,22 @@ static int init_fifo(GlobalInfo *g)
struct epoll_event epev;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
if(lstat(fifo, &st) == 0) {
if(lstat (fifo, &st) == 0) {
if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
return 1;
exit(1);
}
}
unlink(fifo);
if(mkfifo(fifo, 0600) == -1) {
if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
return 1;
exit(1);
}
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
if(sockfd == -1) {
perror("open");
return 1;
exit(1);
}
g->fifofd = sockfd;
@ -478,13 +478,13 @@ int main(int argc, char **argv)
g.epfd = epoll_create1(EPOLL_CLOEXEC);
if(g.epfd == -1) {
perror("epoll_create1 failed");
return 1;
exit(1);
}
g.tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
if(g.tfd == -1) {
perror("timerfd_create failed");
return 1;
exit(1);
}
memset(&its, 0, sizeof(struct itimerspec));
@ -496,8 +496,7 @@ int main(int argc, char **argv)
ev.data.fd = g.tfd;
epoll_ctl(g.epfd, EPOLL_CTL_ADD, g.tfd, &ev);
if(init_fifo(&g))
return 1;
init_fifo(&g);
g.multi = curl_multi_init();
/* setup the generic multi interface options we want */
@ -522,7 +521,7 @@ int main(int argc, char **argv)
}
else {
perror("epoll_wait");
return 1;
exit(1);
}
}

View File

@ -402,22 +402,22 @@ static int init_fifo(GlobalInfo *g)
curl_socket_t sockfd;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
if(lstat(fifo, &st) == 0) {
if(lstat (fifo, &st) == 0) {
if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
return 1;
exit(1);
}
}
unlink(fifo);
if(mkfifo(fifo, 0600) == -1) {
if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
return 1;
exit(1);
}
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
if(sockfd == -1) {
perror("open");
return 1;
exit(1);
}
g->input = fdopen(sockfd, "r");
@ -436,8 +436,7 @@ int main(int argc, char **argv)
memset(&g, 0, sizeof(GlobalInfo));
g.loop = ev_default_loop(0);
if(init_fifo(&g))
return 1;
init_fifo(&g);
g.multi = curl_multi_init();
ev_timer_init(&g.timer_event, timer_cb, 0., 0.);

View File

@ -392,21 +392,21 @@ int init_fifo(void)
if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
return CURL_SOCKET_BAD;
exit(1);
}
}
unlink(fifo);
if(mkfifo(fifo, 0600) == -1) {
if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
return CURL_SOCKET_BAD;
exit(1);
}
socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
if(socket == CURL_SOCKET_BAD) {
if(socket == -1) {
perror("open");
return socket;
exit(1);
}
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
@ -421,8 +421,6 @@ int main(void)
GIOChannel* ch;
fd = init_fifo();
if(fd == CURL_SOCKET_BAD)
return 1;
ch = g_io_channel_unix_new(fd);
g_io_add_watch(ch, G_IO_IN, fifo_cb, g);
gmain = g_main_loop_new(NULL, FALSE);

View File

@ -399,22 +399,22 @@ static int init_fifo(GlobalInfo *g)
curl_socket_t sockfd;
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
if(lstat(fifo, &st) == 0) {
if(lstat (fifo, &st) == 0) {
if((st.st_mode & S_IFMT) == S_IFREG) {
errno = EEXIST;
perror("lstat");
return 1;
exit(1);
}
}
unlink(fifo);
if(mkfifo (fifo, 0600) == -1) {
perror("mkfifo");
return 1;
exit(1);
}
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
if(sockfd == -1) {
perror("open");
return 1;
exit(1);
}
g->input = fdopen(sockfd, "r");
@ -440,8 +440,7 @@ int main(int argc, char **argv)
memset(&g, 0, sizeof(GlobalInfo));
g.evbase = event_base_new();
if(init_fifo(&g))
return 1;
init_fifo(&g);
g.multi = curl_multi_init();
evtimer_assign(&g.timer_event, g.evbase, timer_cb, &g);

View File

@ -94,7 +94,7 @@ static bool init(CURL *&conn, const char *url)
if(conn == NULL) {
fprintf(stderr, "Failed to create CURL connection\n");
return false;
exit(EXIT_FAILURE);
}
code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
@ -270,7 +270,7 @@ int main(int argc, char *argv[])
if(argc != 2) {
fprintf(stderr, "Usage: %s <url>\n", argv[0]);
return EXIT_FAILURE;
exit(EXIT_FAILURE);
}
curl_global_init(CURL_GLOBAL_DEFAULT);
@ -279,7 +279,7 @@ int main(int argc, char *argv[])
if(!init(conn, argv[1])) {
fprintf(stderr, "Connection initialization failed\n");
return EXIT_FAILURE;
exit(EXIT_FAILURE);
}
// Retrieve content for the URL
@ -289,7 +289,7 @@ int main(int argc, char *argv[])
if(code != CURLE_OK) {
fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
return EXIT_FAILURE;
exit(EXIT_FAILURE);
}
// Parse the (assumed) HTML code

View File

@ -142,7 +142,7 @@ int my_trace(CURL *handle, curl_infotype type,
return 0;
}
static int setup(struct transfer *t, int num)
static void setup(struct transfer *t, int num)
{
char filename[128];
CURL *hnd;
@ -155,7 +155,7 @@ static int setup(struct transfer *t, int num)
if(!t->out) {
fprintf(stderr, "error: could not open file %s for writing: %s\n",
filename, strerror(errno));
return 1;
exit(1);
}
/* write to this file */
@ -179,7 +179,6 @@ static int setup(struct transfer *t, int num)
/* wait for pipe connection to confirm */
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
#endif
return 0;
}
/*
@ -205,8 +204,7 @@ int main(int argc, char **argv)
multi_handle = curl_multi_init();
for(i = 0; i < num_transfers; i++) {
if(setup(&trans[i], i))
return 1;
setup(&trans[i], i);
/* add the individual transfer */
curl_multi_add_handle(multi_handle, trans[i].easy);

View File

@ -200,7 +200,7 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
return retcode;
}
static int setup(struct input *i, int num, const char *upload)
static void setup(struct input *i, int num, const char *upload)
{
FILE *out;
char url[256];
@ -209,15 +209,14 @@ static int setup(struct input *i, int num, const char *upload)
curl_off_t uploadsize;
CURL *hnd;
hnd = i->hnd = NULL;
hnd = i->hnd = curl_easy_init();
i->num = num;
curl_msnprintf(filename, 128, "dl-%d", num);
out = fopen(filename, "wb");
if(!out) {
fprintf(stderr, "error: could not open file %s for writing: %s\n", upload,
strerror(errno));
return 1;
exit(1);
}
curl_msnprintf(url, 256, "https://localhost:8443/upload-%d", num);
@ -226,8 +225,7 @@ static int setup(struct input *i, int num, const char *upload)
if(stat(upload, &file_info)) {
fprintf(stderr, "error: could not stat file %s: %s\n", upload,
strerror(errno));
fclose(out);
return 1;
exit(1);
}
uploadsize = file_info.st_size;
@ -236,12 +234,9 @@ static int setup(struct input *i, int num, const char *upload)
if(!i->in) {
fprintf(stderr, "error: could not open file %s for reading: %s\n", upload,
strerror(errno));
fclose(out);
return 1;
exit(1);
}
hnd = i->hnd = curl_easy_init();
/* write to this file */
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
@ -274,7 +269,6 @@ static int setup(struct input *i, int num, const char *upload)
/* wait for pipe connection to confirm */
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
#endif
return 0;
}
/*
@ -307,8 +301,7 @@ int main(int argc, char **argv)
multi_handle = curl_multi_init();
for(i = 0; i < num_transfers; i++) {
if(setup(&trans[i], i, filename))
return 1;
setup(&trans[i], i, filename);
/* add the individual transfer */
curl_multi_add_handle(multi_handle, trans[i].hnd);

View File

@ -28,10 +28,11 @@ const struct curl_easyoption *curl_easy_option_by_id(CURLoption id);
# DESCRIPTION
Given a *CURLoption* **id**, this function returns a pointer to the
*curl_easyoption* struct, holding information about the curl_easy_setopt(3)
option using that id. The option id is the `CURLOPT_` prefixed ones provided
in the standard curl/curl.h header file. This function returns the non-alias
version of the cases where there is an alias function as well.
*curl_easyoption* struct, holding information about the
curl_easy_setopt(3) option using that id. The option id is the CURLOPT_
prefix ones provided in the standard curl/curl.h header file. This function
returns the non-alias version of the cases where there is an alias function as
well.
If libcurl has no option with the given id, this function returns NULL.

View File

@ -27,10 +27,11 @@ const struct curl_easyoption *curl_easy_option_by_name(const char *name);
# DESCRIPTION
Given a **name**, this function returns a pointer to the *curl_easyoption*
struct, holding information about the curl_easy_setopt(3) option using that
name. The name should be specified without the `CURLOPT_` prefix and the name
comparison is made case insensitive.
Given a **name**, this function returns a pointer to the
*curl_easyoption* struct, holding information about the
curl_easy_setopt(3) option using that name. The name should be specified
without the "CURLOPT_" prefix and the name comparison is made case
insensitive.
If libcurl has no option with the given name, this function returns NULL.

View File

@ -316,4 +316,4 @@ filenames are now escaped before transmission.
# RETURN VALUE
0 means everything was OK, non-zero means an error occurred corresponding to a
`CURL_FORMADD_*` constant defined in *\<curl/curl.h\>*.
CURL_FORMADD_* constant defined in *\<curl/curl.h\>*.

View File

@ -38,9 +38,9 @@ first argument to the curl_formget_callback function.
size_t len);"
~~~
The *curl_formget_callback* is invoked for each part of the HTTP POST chain.
The character buffer passed to the callback must not be freed. The callback
should return the buffer length passed to it on success.
The curl_formget_callback is invoked for each part of the HTTP POST chain. The
character buffer passed to the callback must not be freed. The callback should
return the buffer length passed to it on success.
If the **CURLFORM_STREAM** option is used in the formpost, it prevents
curl_formget(3) from working until you have performed the actual HTTP request.

View File

@ -376,8 +376,9 @@ supports HTTP zstd content encoding using zstd library (Added in 7.72.0)
*features* mask bit: CURL_VERSION_CONV
libcurl was built with support for character conversions provided by
callbacks. Always 0 since 7.82.0. (Added in 7.15.4, deprecated.)
libcurl was built with support for character conversions, as provided by the
CURLOPT_CONV_* callbacks. Always 0 since 7.82.0. (Added in 7.15.4,
deprecated.)
## no name

View File

@ -23,16 +23,16 @@ These variables are intended for internal use only, subject to change and have
many effects on the behavior of libcurl. Refer to the source code to determine
how exactly they are being used.
## `CURL_ALTSVC_HTTP`
## CURL_ALTSVC_HTTP
Bypass the AltSvc HTTPS protocol restriction if this variable exists.
## `CURL_DBG_SOCK_RBLOCK`
## CURL_DBG_SOCK_RBLOCK
The percentage of recv() calls that should be answered with a EAGAIN at random.
For TCP/UNIX sockets.
## `CURL_DBG_SOCK_RMAX`
## CURL_DBG_SOCK_RMAX
The maximum data that shall be received from the network in one recv() call.
For TCP/UNIX sockets. This is applied to every recv.
@ -40,12 +40,12 @@ For TCP/UNIX sockets. This is applied to every recv.
Example: **CURL_DBG_SOCK_RMAX=400** means recv buffer size is limited to a
maximum of 400 bytes.
## `CURL_DBG_SOCK_WBLOCK`
## CURL_DBG_SOCK_WBLOCK
The percentage of send() calls that should be answered with a EAGAIN at random.
For TCP/UNIX sockets.
## `CURL_DBG_SOCK_WPARTIAL`
## CURL_DBG_SOCK_WPARTIAL
The percentage of data that shall be written to the network. For TCP/UNIX
sockets. This is applied to every send.
@ -53,12 +53,12 @@ sockets. This is applied to every send.
Example: **CURL_DBG_SOCK_WPARTIAL=80** means a send with 1000 bytes would
only send 800.
## `CURL_DBG_QUIC_WBLOCK`
## CURL_DBG_QUIC_WBLOCK
The percentage of send() calls that should be answered with EAGAIN at random.
QUIC only.
## `CURL_DEBUG`
## CURL_DEBUG
Trace logging behavior as an alternative to calling curl_global_trace(3).
@ -73,39 +73,39 @@ Example: **CURL_DEBUG=tcp,-http/2 curl -vv url** means trace protocol details,
triggered by `-vv`, add tracing of TCP in addition and remove tracing of
HTTP/2.
## `CURL_DEBUG_SIZE`
## CURL_DEBUG_SIZE
Fake the size returned by CURLINFO_HEADER_SIZE and CURLINFO_REQUEST_SIZE.
## `CURL_GETHOSTNAME`
## CURL_GETHOSTNAME
Fake the local machine's unqualified hostname for NTLM and SMTP.
## `CURL_HSTS_HTTP`
## CURL_HSTS_HTTP
Bypass the HSTS HTTPS protocol restriction if this variable exists.
## `CURL_FORCETIME`
## CURL_FORCETIME
A time of 0 is used for AWS signatures and NTLM if this variable exists.
## `CURL_ENTROPY`
## CURL_ENTROPY
A fixed faked value to use instead of a proper random number so that functions
in libcurl that are otherwise getting random outputs can be tested for what
they generate.
## `CURL_SMALLREQSEND`
## CURL_SMALLREQSEND
An alternative size of HTTP data to be sent at a time only if smaller than the
current.
## `CURL_SMALLSENDS`
## CURL_SMALLSENDS
An alternative size of socket data to be sent at a time only if smaller than
the current.
## `CURL_TIME`
## CURL_TIME
Fake Unix timestamp to use for AltSvc, HSTS and CURLINFO variables that are
time related.
@ -114,34 +114,34 @@ This variable can also be used to fake the data returned by some CURLINFO
variables that are not time-related (such as CURLINFO_LOCAL_PORT), and in that
case the value is not a timestamp.
## `CURL_TRACE`
## CURL_TRACE
LDAP tracing is enabled if this variable exists and its value is 1 or greater.
OpenLDAP tracing is separate. Refer to CURL_OPENLDAP_TRACE.
## `CURL_OPENLDAP_TRACE`
## CURL_OPENLDAP_TRACE
OpenLDAP tracing is enabled if this variable exists and its value is 1 or
greater. There is a number of debug levels, refer to *openldap.c* comments.
## `CURL_WS_CHUNK_SIZE`
## CURL_WS_CHUNK_SIZE
Used to influence the buffer chunk size used for WebSocket encoding and
decoding.
## `CURL_WS_CHUNK_EAGAIN`
## CURL_WS_CHUNK_EAGAIN
Used to simulate blocking sends after this chunk size for WebSocket
connections.
## `CURL_FORBID_REUSE`
## CURL_FORBID_REUSE
Used to set the CURLOPT_FORBID_REUSE flag on each transfer initiated
by the curl command line tool. The value of the environment variable
does not matter.
## `CURL_GRACEFUL_SHUTDOWN`
## CURL_GRACEFUL_SHUTDOWN
Make a blocking, graceful shutdown of all remaining connections when
a multi handle is destroyed. This implicitly triggers for easy handles

View File

@ -15,7 +15,6 @@ TLS-backend:
- GnuTLS
- Schannel
- Secure Transport
- rustls
Added-in: 7.19.1
---

View File

@ -32,7 +32,7 @@ CURLINFO_SCHEME(3) instead, because this option cannot return all
possible protocols.
Pass a pointer to a long to receive the version used in the last http
connection. The returned value is set to one of these values:
connection. The returned value is set to one of the CURLPROTO_* values:
~~~c
CURLPROTO_DICT, CURLPROTO_FILE, CURLPROTO_FTP, CURLPROTO_FTPS,

View File

@ -58,11 +58,12 @@ struct curl_tlssessioninfo {
};
~~~
The *backend* struct member is one of these defines: CURLSSLBACKEND_NONE (when
built without TLS support), CURLSSLBACKEND_WOLFSSL,
CURLSSLBACKEND_SECURETRANSPORT, CURLSSLBACKEND_GNUTLS, CURLSSLBACKEND_MBEDTLS,
CURLSSLBACKEND_NSS, CURLSSLBACKEND_OPENSSL or CURLSSLBACKEND_SCHANNEL. (Note
that the OpenSSL forks are all reported as just OpenSSL here.)
The *backend* struct member is one of the defines in the CURLSSLBACKEND_*
series: CURLSSLBACKEND_NONE (when built without TLS support),
CURLSSLBACKEND_WOLFSSL, CURLSSLBACKEND_SECURETRANSPORT, CURLSSLBACKEND_GNUTLS,
CURLSSLBACKEND_MBEDTLS, CURLSSLBACKEND_NSS, CURLSSLBACKEND_OPENSSL or
CURLSSLBACKEND_SCHANNEL. (Note that the OpenSSL
forks are all reported as just OpenSSL here.)
The *internals* struct member points to a TLS library specific pointer for
the active ("in use") SSL connection, with the following underlying types:

View File

@ -47,11 +47,6 @@ libcurl then expects the application to monitor the sockets for the specific
activities and tell libcurl again when something happens on one of them. Tell
libcurl by calling curl_multi_socket_action(3).
This callback may get invoked at any time when interacting with libcurl.
This may even happen after all transfers are done and is *likely* to
happen *during* a call to curl_multi_cleanup(3) when cached connections
are shut down.
# CALLBACK ARGUMENTS
*easy* identifies the specific transfer for which this update is related.

View File

@ -17,7 +17,6 @@ TLS-backend:
- GnuTLS
- Schannel
- Secure Transport
- rustls
Added-in: 7.19.1
---

View File

@ -42,24 +42,21 @@ header list establishes the document-level MIME headers to prepend to the
uploaded document described by CURLOPT_MIMEPOST(3). This does not affect raw
mail uploads.
When used with HTTP, this option can add new headers, replace internal headers
and remove internal headers.
The linked list should be a valid list of **struct curl_slist** entries
The linked list should be a fully valid list of **struct curl_slist** structs
properly filled in. Use curl_slist_append(3) to create the list and
curl_slist_free_all(3) to free it again after use.
curl_slist_free_all(3) to clean up an entire list. If you add a header that is
otherwise generated and used by libcurl internally, your added header is used
instead. If you add a header with no content as in 'Accept:' (no data on the
right side of the colon), the internally used header is disabled/removed. With
this option you can add new headers, replace internal headers and remove
internal headers. To add a header with no content (nothing to the right side
of the colon), use the form 'name;' (note the ending semicolon).
If you provide a header that is otherwise generated and used by libcurl
internally, your header alternative is used instead. If you provide a header
without content (no data on the right side of the colon) as in `Accept:`, the
internally used header is removed. To forcibly add a header without content
(nothing after the colon), use the form `name;` (using a trailing semicolon).
The headers included in the linked list **must not** be CRLF-terminated, since
libcurl adds CRLF after each header item itself. Failure to comply 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 headers included in the linked list **must not** be CRLF-terminated,
because libcurl adds CRLF after each header item itself. Failure to comply
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
@ -167,15 +164,9 @@ int main(void)
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* add this header */
list = curl_slist_append(list, "Shoesize: 10");
/* remove this header */
list = curl_slist_append(list, "Accept:");
/* change this header */
list = curl_slist_append(list, "Host: example.net");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_perform(curl);

View File

@ -28,8 +28,8 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_MIME_OPTIONS, long options);
# DESCRIPTION
Pass a long that holds a bitmask of options. Each bit is a boolean flag used
while encoding a MIME tree or multipart form data.
Pass a long that holds a bitmask of CURLMIMEOPT_* defines. Each bit is a
Boolean flag used while encoding a MIME tree or multipart form data.
Available bits are:

View File

@ -31,7 +31,7 @@ This option is deprecated. We strongly recommend using
CURLOPT_PROTOCOLS_STR(3) instead because this option cannot control all
available protocols.
Pass a long that holds a bitmask of protocol bits. If used, this bitmask
Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
limits what protocols libcurl may use in the transfer. This allows you to have
a libcurl built to support a wide range of protocols but still limit specific
transfers to only be allowed to use a subset of them. By default libcurl

View File

@ -32,10 +32,10 @@ This option is deprecated. We strongly recommend using
CURLOPT_REDIR_PROTOCOLS_STR(3) instead because this option cannot
control all available protocols.
Pass a long that holds a bitmask of protocol bits. If used, this bitmask
Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
limits what protocols libcurl may use in a transfer that it follows to in a
redirect when CURLOPT_FOLLOWLOCATION(3) is enabled. This allows you to limit
specific transfers to only be allowed to use a subset of protocols in
redirect when CURLOPT_FOLLOWLOCATION(3) is enabled. This allows you to
limit specific transfers to only be allowed to use a subset of protocols in
redirections.
Protocols denied by CURLOPT_PROTOCOLS(3) are not overridden by this

View File

@ -89,11 +89,11 @@ could be a privacy violation and unexpected.
## CURLSSLOPT_EARLYDATA
Tell libcurl to try sending application data as TLS1.3 early data. This option
is supported for GnuTLS and wolfSSL. This option works on a best effort basis,
is only supported for GnuTLS. This option works on a best effort basis,
in cases when it wasn't possible to send early data the request is resent
normally post-handshake.
This option does not work when using QUIC.
(Added in 8.11.0 for GnuTLS and 8.13.0 for wolfSSL)
(Added in 8.11.0)
# DEFAULT

View File

@ -71,7 +71,7 @@ int main(void)
~~~
If you are on Linux and somehow have a need for paths larger than 107 bytes,
you can use the *proc* filesystem to bypass the limitation:
you can use the proc filesystem to bypass the limitation:
~~~c
int dirfd = open(long_directory_path_to_socket, O_DIRECTORY | O_RDONLY);

View File

@ -81,8 +81,9 @@ int main(void)
# HISTORY
This option was known as CURLOPT_FTP_SSL up to 7.16.4. Supported by LDAP since
7.81.0. Fully supported by the OpenLDAP backend only.
This option was known as CURLOPT_FTP_SSL up to 7.16.4, and the constants were
known as CURLFTPSSL_* Handled by LDAP since 7.81.0. Fully supported by the
OpenLDAP backend only.
# %AVAILABILITY%

View File

@ -51,7 +51,7 @@ stdout
A common technique is to use the write callback to store the incoming data
into a dynamically growing allocated buffer, and then this
CURLOPT_WRITEDATA(3) is used to point to a struct or the buffer to store data
in. Like in the *getinmemory* example:
in. Like in the getinmemory example:
https://curl.se/libcurl/c/getinmemory.html
# HISTORY

View File

@ -45,7 +45,6 @@ CURL_GLOBAL_DEFAULT 7.8
CURL_GLOBAL_NOTHING 7.8
CURL_GLOBAL_SSL 7.8
CURL_GLOBAL_WIN32 7.8.1
CURL_HAS_DECLSPEC_ATTRIBUTE 8.13.0
CURL_HET_DEFAULT 7.59.0
CURL_HTTP_VERSION_1_0 7.9.1
CURL_HTTP_VERSION_1_1 7.9.1

View File

@ -102,6 +102,11 @@
#include <sys/time.h>
#endif
/* Compatibility for non-Clang compilers */
#ifndef __has_declspec_attribute
# define __has_declspec_attribute(x) 0
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -113,17 +118,11 @@ typedef void CURLSH;
* libcurl external API function linkage decorations.
*/
#ifdef __has_declspec_attribute
#define CURL_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x)
#else
#define CURL_HAS_DECLSPEC_ATTRIBUTE(x) 0
#endif
#ifdef CURL_STATICLIB
# define CURL_EXTERN
#elif defined(_WIN32) || \
(CURL_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
CURL_HAS_DECLSPEC_ATTRIBUTE(dllimport))
(__has_declspec_attribute(dllexport) && \
__has_declspec_attribute(dllimport))
# if defined(BUILDING_LIBCURL)
# define CURL_EXTERN __declspec(dllexport)
# else
@ -2303,33 +2302,32 @@ enum {
/*
* Public API enums for RTSP requests
*/
#define CURL_RTSPREQ_NONE 0L
#define CURL_RTSPREQ_OPTIONS 1L
#define CURL_RTSPREQ_DESCRIBE 2L
#define CURL_RTSPREQ_ANNOUNCE 3L
#define CURL_RTSPREQ_SETUP 4L
#define CURL_RTSPREQ_PLAY 5L
#define CURL_RTSPREQ_PAUSE 6L
#define CURL_RTSPREQ_TEARDOWN 7L
#define CURL_RTSPREQ_GET_PARAMETER 8L
#define CURL_RTSPREQ_SET_PARAMETER 9L
#define CURL_RTSPREQ_RECORD 10L
#define CURL_RTSPREQ_RECEIVE 11L
#define CURL_RTSPREQ_LAST 12L /* not used */
enum {
CURL_RTSPREQ_NONE, /* first in list */
CURL_RTSPREQ_OPTIONS,
CURL_RTSPREQ_DESCRIBE,
CURL_RTSPREQ_ANNOUNCE,
CURL_RTSPREQ_SETUP,
CURL_RTSPREQ_PLAY,
CURL_RTSPREQ_PAUSE,
CURL_RTSPREQ_TEARDOWN,
CURL_RTSPREQ_GET_PARAMETER,
CURL_RTSPREQ_SET_PARAMETER,
CURL_RTSPREQ_RECORD,
CURL_RTSPREQ_RECEIVE,
CURL_RTSPREQ_LAST /* last in list */
};
/* These enums are for use with the CURLOPT_NETRC option. */
#define CURL_NETRC_IGNORED 0L /* The .netrc will never be read.
This is the default. */
#define CURL_NETRC_OPTIONAL 1L /* A user:password in the URL will be preferred
to one in the .netrc. */
#define CURL_NETRC_REQUIRED 2L /* A user:password in the URL will be ignored.
Unless one is set programmatically, the
.netrc will be queried. */
enum CURL_NETRC_OPTION {
/* we set a single member here, just to make sure we still provide the enum,
but the values to use are defined above with L suffixes */
CURL_NETRC_LAST = 3
CURL_NETRC_IGNORED, /* The .netrc will never be read.
* This is the default. */
CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred
* to one in the .netrc. */
CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored.
* Unless one is set programmatically, the .netrc
* will be queried. */
CURL_NETRC_LAST
};
#define CURL_SSLVERSION_DEFAULT 0
@ -2353,13 +2351,10 @@ enum CURL_NETRC_OPTION {
/* never use, keep last */
#define CURL_SSLVERSION_MAX_LAST (CURL_SSLVERSION_LAST << 16)
#define CURL_TLSAUTH_NONE 0L
#define CURL_TLSAUTH_SRP 1L
enum CURL_TLSAUTH {
/* we set a single member here, just to make sure we still provide the enum,
but the values to use are defined above with L suffixes */
CURL_TLSAUTH_LAST = 2
CURL_TLSAUTH_NONE,
CURL_TLSAUTH_SRP,
CURL_TLSAUTH_LAST /* never use, keep last */
};
/* symbols to use with CURLOPT_POSTREDIR.
@ -2374,16 +2369,14 @@ enum CURL_TLSAUTH {
#define CURL_REDIR_POST_ALL \
(CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
#define CURL_TIMECOND_NONE 0L
#define CURL_TIMECOND_IFMODSINCE 1L
#define CURL_TIMECOND_IFUNMODSINCE 2L
#define CURL_TIMECOND_LASTMOD 3L
typedef enum {
/* we set a single member here, just to make sure we still provide
the enum typedef, but the values to use are defined above with L
suffixes */
CURL_TIMECOND_LAST = 4
CURL_TIMECOND_NONE,
CURL_TIMECOND_IFMODSINCE,
CURL_TIMECOND_IFUNMODSINCE,
CURL_TIMECOND_LASTMOD,
CURL_TIMECOND_LAST
} curl_TimeCond;
/* Special size_t value signaling a null-terminated string. */

View File

@ -162,8 +162,7 @@ endif
TIDY := clang-tidy
tidy:
(_csources=`echo ' $(CSOURCES)' | sed -e 's/ +/ /g' -e 's| | $(srcdir)/|g'`; \
$(TIDY) $$_csources $(TIDYFLAGS) $(CURL_CLANG_TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H)
$(TIDY) $(CSOURCES) $(TIDYFLAGS) $(CURL_CLANG_TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H
optiontable:
perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c

View File

@ -407,6 +407,26 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
return result;
}
static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
{
size_t len;
const char *protop;
const char *p = *ptr;
while(ISBLANK(*p))
p++;
protop = p;
while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '='))
p++;
len = p - protop;
*ptr = p;
if(!len || (len >= buflen))
return CURLE_BAD_FUNCTION_ARGUMENT;
memcpy(alpnbuf, protop, len);
alpnbuf[len] = 0;
return CURLE_OK;
}
/* hostcompare() returns true if 'host' matches 'check'. The first host
* argument may have a trailing dot present that will be ignored.
*/
@ -477,124 +497,144 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
unsigned short srcport)
{
const char *p = value;
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
struct altsvc *as;
unsigned short dstport = srcport; /* the same by default */
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
size_t entries = 0;
struct Curl_str alpn;
const char *sp;
time_t maxage = 24 * 3600; /* default is 24 hours */
bool persist = FALSE;
size_t alpnlen = strlen(alpnbuf);
size_t srchostlen = strlen(srchost);
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)data;
#endif
if(result) {
infof(data, "Excessive alt-svc header, ignoring.");
return CURLE_OK;
}
DEBUGASSERT(asi);
/* initial check for "clear" */
if(!Curl_str_until(&p, &alpn, MAX_ALTSVC_LINE, ';') &&
!Curl_str_single(&p, ';')) {
Curl_str_trimblanks(&alpn);
/* "clear" is a magic keyword */
if(Curl_str_casecompare(&alpn, "clear")) {
if(strcasecompare(alpnbuf, "clear")) {
/* Flush cached alternatives for this source origin */
altsvc_flush(asi, srcalpnid, srchost, srcport);
return CURLE_OK;
}
}
p = value;
if(Curl_str_until(&p, &alpn, MAX_ALTSVC_LINE, '='))
return CURLE_OK; /* strange line */
Curl_str_trimblanks(&alpn);
/* Handle the optional 'ma' and 'persist' flags once first, as they need to
be known for each alternative service. Unknown flags are skipped. */
sp = strchr(p, ';');
if(sp) {
sp++; /* pass the semicolon */
for(;;) {
struct Curl_str name;
struct Curl_str val;
const char *vp;
curl_off_t num;
bool quoted;
/* allow some extra whitespaces around name and value */
if(Curl_str_until(&sp, &name, 20, '=') ||
Curl_str_single(&sp, '=') ||
Curl_str_until(&sp, &val, 80, ';'))
break;
Curl_str_trimblanks(&name);
Curl_str_trimblanks(&val);
/* the value might be quoted */
vp = Curl_str(&val);
quoted = (*vp == '\"');
if(quoted)
vp++;
if(!Curl_str_number(&vp, &num, TIME_T_MAX)) {
if(Curl_str_casecompare(&name, "ma"))
maxage = (time_t)num;
else if(Curl_str_casecompare(&name, "persist") && (num == 1))
persist = TRUE;
}
if(quoted && Curl_str_single(&sp, '\"'))
break;
if(Curl_str_single(&sp, ';'))
break;
}
}
do {
if(!Curl_str_single(&p, '=')) {
/* [protocol]="[host][:port], [protocol]="[host][:port]" */
enum alpnid dstalpnid =
Curl_alpn2alpnid(Curl_str(&alpn), Curl_strlen(&alpn));
if(!Curl_str_single(&p, '\"')) {
struct Curl_str dsthost;
curl_off_t port = 0;
if(Curl_str_single(&p, ':')) {
if(*p == '=') {
/* [protocol]="[host][:port]" */
enum alpnid dstalpnid = Curl_alpn2alpnid(alpnbuf, alpnlen);
p++;
if(*p == '\"') {
const char *dsthost = "";
size_t dstlen = 0; /* destination hostname length */
const char *value_ptr;
char option[32];
curl_off_t num;
bool quoted = FALSE;
time_t maxage = 24 * 3600; /* default is 24 hours */
bool persist = FALSE;
bool valid = TRUE;
p++;
if(*p != ':') {
/* hostname starts here */
if(Curl_str_single(&p, '[')) {
if(Curl_str_until(&p, &dsthost, MAX_ALTSVC_HOSTLEN, ':')) {
infof(data, "Bad alt-svc hostname, ignoring.");
const char *hostp = p;
if(*p == '[') {
/* pass all valid IPv6 letters - does not handle zone id */
dstlen = strspn(++p, "0123456789abcdefABCDEF:.");
if(p[dstlen] != ']')
/* invalid host syntax, bail out */
break;
/* we store the IPv6 numerical address *with* brackets */
dstlen += 2;
p = &p[dstlen-1];
}
else {
while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
p++;
dstlen = p - hostp;
}
if(!dstlen || (dstlen >= MAX_ALTSVC_HOSTLEN)) {
infof(data, "Excessive alt-svc hostname, ignoring.");
valid = FALSE;
}
else {
dsthost = hostp;
}
}
else {
/* IPv6 host name */
if(Curl_str_until(&p, &dsthost, MAX_IPADR_LEN, ']') ||
Curl_str_single(&p, ']')) {
infof(data, "Bad alt-svc IPv6 hostname, ignoring.");
break;
/* no destination name, use source host */
dsthost = srchost;
dstlen = strlen(srchost);
}
}
if(Curl_str_single(&p, ':'))
break;
if(*p == ':') {
curl_off_t port = 0;
p++;
if(Curl_str_number(&p, &port, 0xffff) || (*p != '\"')) {
infof(data, "Unknown alt-svc port number, ignoring.");
valid = FALSE;
}
else
/* no destination name, use source host */
Curl_str_assign(&dsthost, srchost, strlen(srchost));
if(Curl_str_number(&p, &port, 0xffff)) {
infof(data, "Unknown alt-svc port number, ignoring.");
break;
}
dstport = (unsigned short)port;
if(Curl_str_single(&p, '\"'))
}
if(*p++ != '\"')
break;
if(dstalpnid) {
/* Handle the optional 'ma' and 'persist' flags. Unknown flags
are skipped. */
for(;;) {
while(ISBLANK(*p))
p++;
if(*p != ';')
break;
p++; /* pass the semicolon */
if(!*p || ISNEWLINE(*p))
break;
result = getalnum(&p, option, sizeof(option));
if(result) {
/* skip option if name is too long */
option[0] = '\0';
}
while(ISBLANK(*p))
p++;
if(*p != '=')
return CURLE_OK;
p++;
while(ISBLANK(*p))
p++;
if(!*p)
return CURLE_OK;
if(*p == '\"') {
/* quoted value */
p++;
quoted = TRUE;
}
value_ptr = p;
if(quoted) {
while(*p && *p != '\"')
p++;
if(!*p++)
return CURLE_OK;
}
else {
while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
p++;
}
if(!Curl_str_number(&value_ptr, &num, TIME_T_MAX)) {
if(strcasecompare("ma", option))
maxage = (time_t)num;
else if(strcasecompare("persist", option) && (num == 1))
persist = TRUE;
}
}
if(dstalpnid && valid) {
if(!entries++)
/* Flush cached alternatives for this source origin, if any - when
this is the first entry of the line. */
altsvc_flush(asi, srcalpnid, srchost, srcport);
as = altsvc_createid(srchost, strlen(srchost),
Curl_str(&dsthost),
Curl_strlen(&dsthost),
as = altsvc_createid(srchost, srchostlen,
dsthost, dstlen,
srcalpnid, dstalpnid,
srcport, dstport);
if(as) {
@ -607,28 +647,26 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
as->expires = maxage + secs;
as->persist = persist;
Curl_llist_append(&asi->list, as, &as->node);
infof(data, "Added alt-svc: %.*s:%d over %s",
(int)Curl_strlen(&dsthost), Curl_str(&dsthost),
dstport, Curl_alpnid2str(dstalpnid));
infof(data, "Added alt-svc: %s:%d over %s", dsthost, dstport,
Curl_alpnid2str(dstalpnid));
}
}
}
else
break;
/* after the double quote there can be a comma if there is another
string or a semicolon if no more */
if(Curl_str_single(&p, ','))
if(*p == ',') {
/* comma means another alternative is presented */
p++;
result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
if(result)
break;
/* comma means another alternative is present */
if(Curl_str_until(&p, &alpn, MAX_ALTSVC_LINE, '='))
break;
Curl_str_trimblanks(&alpn);
}
}
else
break;
} while(1);
} while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
return CURLE_OK;
}

View File

@ -592,7 +592,7 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
res->num_pending--;
if(CURL_ASYNC_SUCCESS == status) {
struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->conn->remote_port);
struct Curl_addrinfo *ai = Curl_he2ai(hostent, data->state.async.port);
if(ai) {
compound_results(res, ai);
}
@ -774,6 +774,8 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
if(!res->hostname)
return NULL;
data->state.async.hostname = res->hostname;
data->state.async.port = port;
data->state.async.done = FALSE; /* not done */
data->state.async.dns = NULL; /* clear */
@ -809,7 +811,6 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
service, &hints, addrinfo_cb, data);
}
#else
(void)port;
#ifdef HAVE_CARES_IPV6
if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {

View File

@ -400,7 +400,7 @@ static void destroy_async_data(struct Curl_easy *data)
td->init = FALSE;
}
Curl_safefree(async->hostname);
}
#ifdef USE_HTTPSRR_ARES
@ -414,7 +414,7 @@ static CURLcode resolve_httpsrr(struct Curl_easy *data,
memset(&async->thdata.hinfo, 0, sizeof(struct Curl_https_rrinfo));
async->thdata.hinfo.port = -1;
ares_query_dnsrec(async->thdata.channel,
data->conn->host.name, ARES_CLASS_IN,
async->hostname, ARES_CLASS_IN,
ARES_REC_TYPE_HTTPS,
Curl_dnsrec_done_cb, data, NULL);
@ -436,6 +436,7 @@ static bool init_resolve_thread(struct Curl_easy *data,
int err = ENOMEM;
struct Curl_async *async = &data->state.async;
async->port = port;
async->done = FALSE;
async->dns = NULL;
td->thread_hnd = curl_thread_t_null;
@ -446,6 +447,11 @@ static bool init_resolve_thread(struct Curl_easy *data,
goto errno_exit;
}
free(async->hostname);
async->hostname = strdup(hostname);
if(!async->hostname)
goto err_exit;
/* The thread will set this TRUE when complete. */
td->tsd.done = FALSE;

View File

@ -536,9 +536,9 @@ parse_cookie_header(struct Curl_easy *data,
* "the rest". Prefixes must start with '__' and end with a '-', so
* only test for names where that can possibly be true.
*/
if(!strncmp("__Secure-", Curl_str(&name), 9))
if(strncasecompare("__Secure-", Curl_str(&name), 9))
co->prefix_secure = TRUE;
else if(!strncmp("__Host-", Curl_str(&name), 7))
else if(strncasecompare("__Host-", Curl_str(&name), 7))
co->prefix_host = TRUE;
/*

View File

@ -34,9 +34,15 @@
#endif
#else /* HAVE_MEMRCHR */
#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \
defined(USE_OPENSSL) || \
defined(USE_SCHANNEL)
void *Curl_memrchr(const void *s, int c, size_t n);
#define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
#endif
#endif /* HAVE_MEMRCHR */
#endif /* HEADER_CURL_MEMRCHR_H */

View File

@ -120,14 +120,6 @@
# endif
#endif
/* Avoid bogus format check warnings with mingw32ce gcc 4.4.0 in
C99 (-std=gnu99) mode */
#if defined(__MINGW32CE__) && !defined(CURL_NO_FMT_CHECKS) && \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) && \
(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 4))
#define CURL_NO_FMT_CHECKS
#endif
/* Compatibility */
#ifdef ENABLE_IPV6
#define USE_IPV6 1

View File

@ -85,6 +85,7 @@ void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
void Curl_trc_multi(struct Curl_easy *data,
const char *fmt, ...) CURL_PRINTF(2, 3);
const char *Curl_trc_mstate_name(int state);
#define CURL_MSTATE_NAME(s) Curl_trc_mstate_name((int)(s))
void Curl_trc_write(struct Curl_easy *data,
const char *fmt, ...) CURL_PRINTF(2, 3);
void Curl_trc_read(struct Curl_easy *data,
@ -178,14 +179,13 @@ void Curl_trc_ws(struct Curl_easy *data,
#endif /* !CURL_HAVE_C99 */
#ifndef CURL_DISABLE_VERBOSE_STRINGS
/* informational messages enabled */
struct curl_trc_feat {
const char *name;
int log_level;
};
#ifndef CURL_DISABLE_VERBOSE_STRINGS
/* informational messages enabled */
extern struct curl_trc_feat Curl_trc_feat_multi;
extern struct curl_trc_feat Curl_trc_feat_read;
extern struct curl_trc_feat Curl_trc_feat_write;
@ -201,7 +201,6 @@ extern struct curl_trc_feat Curl_trc_feat_dns;
#define Curl_trc_ft_is_verbose(data, ft) \
(Curl_trc_is_verbose(data) && \
(ft)->log_level >= CURL_LOG_LVL_INFO)
#define CURL_MSTATE_NAME(s) Curl_trc_mstate_name((int)(s))
#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */
/* All informational messages are not compiled in for size savings */

View File

@ -1181,7 +1181,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
if(dohp->probe[DOH_SLOT_IPV4].easy_mid < 0 &&
dohp->probe[DOH_SLOT_IPV6].easy_mid < 0) {
failf(data, "Could not DoH-resolve: %s", dohp->host);
failf(data, "Could not DoH-resolve: %s", data->state.async.hostname);
return CONN_IS_PROXIED(data->conn) ? CURLE_COULDNT_RESOLVE_PROXY :
CURLE_COULDNT_RESOLVE_HOST;
}

View File

@ -76,8 +76,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->conn->host.dispname, 0,
data->conn->localport, FALSE);
data->state.async.hostname, 0,
data->state.async.port, FALSE);
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);

View File

@ -1480,7 +1480,7 @@ CURLcode Curl_resolver_error(struct Curl_easy *data)
}
failf(data, "Could not resolve %s: %s", host_or_proxy,
data->conn->host.dispname);
data->state.async.hostname);
return result;
}

View File

@ -273,28 +273,46 @@ char *Curl_checkProxyheaders(struct Curl_easy *data,
#endif
/*
* Strip off leading and trailing whitespace from the value in the given HTTP
* header line and return a strdup()ed copy. Returns NULL in case of
* allocation failure or bad input. Returns an empty string if the header
* value consists entirely of whitespace.
*
* If the header is provided as "name;", ending with a semicolon, it must
* return a blank string.
* Strip off leading and trailing whitespace from the value in the
* given HTTP header line and return a strdupped copy. Returns NULL in
* case of allocation failure. Returns an empty string if the header value
* consists entirely of whitespace.
*/
char *Curl_copy_header_value(const char *header)
{
struct Curl_str out;
const char *start;
const char *end;
size_t len;
/* find the end of the header name */
if(!Curl_str_cspn(&header, &out, ";:") &&
(!Curl_str_single(&header, ':') || !Curl_str_single(&header, ';'))) {
Curl_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE);
Curl_str_trimblanks(&out);
/* Find the end of the header name */
while(*header && (*header != ':'))
++header;
return Curl_memdup0(Curl_str(&out), Curl_strlen(&out));
}
/* bad input */
if(*header)
/* Skip over colon */
++header;
/* Find the first non-space letter */
start = header;
while(ISSPACE(*start))
start++;
end = strchr(start, '\r');
if(!end)
end = strchr(start, '\n');
if(!end)
end = strchr(start, '\0');
if(!end)
return NULL;
/* skip all trailing space letters */
while((end > start) && ISSPACE(*end))
end--;
/* get length of the type */
len = end - start + 1;
return Curl_memdup0(start, len);
}
#ifndef CURL_DISABLE_HTTP_AUTH
@ -1450,8 +1468,9 @@ Curl_compareheader(const char *headerline, /* line to check */
* The field value MAY be preceded by any amount of LWS, though a single SP
* is preferred." */
const char *p;
struct Curl_str val;
size_t len;
const char *start;
const char *end;
DEBUGASSERT(hlen);
DEBUGASSERT(clen);
DEBUGASSERT(header);
@ -1461,21 +1480,31 @@ Curl_compareheader(const char *headerline, /* line to check */
return FALSE; /* does not start with header */
/* pass the header */
p = &headerline[hlen];
start = &headerline[hlen];
if(Curl_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE))
return FALSE;
Curl_str_trimblanks(&val);
/* pass all whitespace */
while(ISSPACE(*start))
start++;
/* find the end of the header line */
end = strchr(start, '\r'); /* lines end with CRLF */
if(!end) {
/* in case there is a non-standard compliant line here */
end = strchr(start, '\n');
if(!end)
/* hm, there is no line ending here, use the zero byte! */
end = strchr(start, '\0');
}
len = end-start; /* length of the content part of the input line */
/* find the content string in the rest of the line */
if(Curl_strlen(&val) >= clen) {
size_t len;
p = Curl_str(&val);
for(len = Curl_strlen(&val); len >= Curl_strlen(&val); len--, p++) {
if(strncasecompare(p, content, clen))
for(; len >= clen; len--, start++) {
if(strncasecompare(start, content, clen))
return TRUE; /* match! */
}
}
return FALSE; /* no match */
}
@ -1594,6 +1623,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
bool is_connect, int httpversion,
struct dynbuf *req)
{
char *ptr;
struct curl_slist *h[2];
struct curl_slist *headers;
int numlists = 1; /* by default */
@ -1633,83 +1663,100 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
/* loop through one or two lists */
for(i = 0; i < numlists; i++) {
for(headers = h[i]; headers; headers = headers->next) {
CURLcode result = CURLE_OK;
bool blankheader = FALSE;
struct Curl_str name;
const char *p = headers->data;
const char *origp = p;
headers = h[i];
/* explicitly asked to send header without content is done by a header
that ends with a semicolon, but there must be no colon present in the
name */
if(!Curl_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ';') &&
!Curl_str_single(&p, ';') &&
!Curl_str_single(&p, '\0') &&
!memchr(Curl_str(&name), ':', Curl_strlen(&name)))
blankheader = TRUE;
while(headers) {
char *semicolonp = NULL;
ptr = strchr(headers->data, ':');
if(!ptr) {
char *optr;
/* no colon, semicolon? */
ptr = strchr(headers->data, ';');
if(ptr) {
optr = ptr;
ptr++; /* pass the semicolon */
while(ISSPACE(*ptr))
ptr++;
if(*ptr) {
/* this may be used for something else in the future */
optr = NULL;
}
else {
p = origp;
if(!Curl_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ':') &&
!Curl_str_single(&p, ':')) {
struct Curl_str val;
Curl_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE);
Curl_str_trimblanks(&val);
if(!Curl_strlen(&val))
/* no content, don't send this */
continue;
if(*(--ptr) == ';') {
/* copy the source */
semicolonp = strdup(headers->data);
if(!semicolonp) {
Curl_dyn_free(req);
return CURLE_OUT_OF_MEMORY;
}
else
/* no colon */
continue;
/* put a colon where the semicolon is */
semicolonp[ptr - headers->data] = ':';
/* point at the colon */
optr = &semicolonp [ptr - headers->data];
}
}
ptr = optr;
}
}
if(ptr && (ptr != headers->data)) {
/* we require a colon for this to be a true header */
ptr++; /* pass the colon */
while(ISSPACE(*ptr))
ptr++;
if(*ptr || semicolonp) {
/* only send this if the contents was non-blank or done special */
CURLcode result = CURLE_OK;
char *compare = semicolonp ? semicolonp : headers->data;
if(data->state.aptr.host &&
/* a Host: header was sent already, do not pass on any custom
Host: header as that will produce *two* in the same
request! */
Curl_str_casecompare(&name, "Host"))
checkprefix("Host:", compare))
;
else if(data->state.httpreq == HTTPREQ_POST_FORM &&
/* this header (extended by formdata.c) is sent later */
Curl_str_casecompare(&name, "Content-Type"))
checkprefix("Content-Type:", compare))
;
else if(data->state.httpreq == HTTPREQ_POST_MIME &&
/* this header is sent later */
Curl_str_casecompare(&name, "Content-Type"))
checkprefix("Content-Type:", compare))
;
else if(data->req.authneg &&
/* while doing auth neg, do not allow the custom length since
we will force length zero then */
Curl_str_casecompare(&name, "Content-Length"))
checkprefix("Content-Length:", compare))
;
else if(data->state.aptr.te &&
/* when asking for Transfer-Encoding, do not pass on a custom
Connection: */
Curl_str_casecompare(&name, "Connection"))
checkprefix("Connection:", compare))
;
else if((httpversion >= 20) &&
Curl_str_casecompare(&name, "Transfer-Encoding"))
checkprefix("Transfer-Encoding:", compare))
/* HTTP/2 does not support chunked requests */
;
else if((Curl_str_casecompare(&name, "Authorization") ||
Curl_str_casecompare(&name, "Cookie")) &&
else if((checkprefix("Authorization:", compare) ||
checkprefix("Cookie:", compare)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
!Curl_auth_allowed_to_host(data))
;
else if(blankheader)
result = Curl_dyn_addf(req, "%.*s:\r\n", (int)Curl_strlen(&name),
Curl_str(&name));
else
result = Curl_dyn_addf(req, "%s\r\n", origp);
else {
result = Curl_dyn_addf(req, "%s\r\n", compare);
}
if(semicolonp)
free(semicolonp);
if(result)
return result;
}
}
headers = headers->next;
}
}
return CURLE_OK;
}

View File

@ -438,7 +438,7 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
*/
if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST))
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.timecondition = (unsigned char)arg;
data->set.timecondition = (unsigned char)(curl_TimeCond)arg;
break;
case CURLOPT_TIMEVALUE:
/*

View File

@ -93,6 +93,12 @@
* newer symbols.
*/
#ifndef _WIN32_WINNT_NT4
#define _WIN32_WINNT_NT4 0x0400 /* Windows NT 4.0 */
#endif
#ifndef _WIN32_WINNT_WIN2K
#define _WIN32_WINNT_WIN2K 0x0500 /* Windows 2000 */
#endif
#ifndef _WIN32_WINNT_WINXP
#define _WIN32_WINNT_WINXP 0x0501 /* Windows XP */
#endif

View File

@ -114,10 +114,7 @@ void *Curl_memdup0(const char *src, size_t length)
char *buf = malloc(length + 1);
if(!buf)
return NULL;
if(length) {
DEBUGASSERT(src); /* must never be NULL */
memcpy(buf, src, length);
}
buf[length] = 0;
return buf;
}

View File

@ -31,12 +31,6 @@ void Curl_str_init(struct Curl_str *out)
out->len = 0;
}
void Curl_str_assign(struct Curl_str *out, const char *str, size_t len)
{
out->str = str;
out->len = len;
}
/* Get a word until the first DELIM or end of string. At least one byte long.
return non-zero on error */
int Curl_str_until(const char **linep, struct Curl_str *out,
@ -69,29 +63,6 @@ int Curl_str_word(const char **linep, struct Curl_str *out,
return Curl_str_until(linep, out, max, ' ');
}
/* Get a word until a newline byte or end of string. At least one byte long.
return non-zero on error */
int Curl_str_untilnl(const char **linep, struct Curl_str *out,
const size_t max)
{
const char *s = *linep;
size_t len = 0;
DEBUGASSERT(linep && *linep && out && max);
Curl_str_init(out);
while(*s && !ISNEWLINE(*s)) {
s++;
if(++len > max)
return STRE_BIG;
}
if(!len)
return STRE_SHORT;
out->str = *linep;
out->len = len;
*linep = s; /* point to the first byte after the word */
return STRE_OK;
}
/* Get a "quoted" word. No escaping possible.
return non-zero on error */

View File

@ -43,7 +43,6 @@ struct Curl_str {
};
void Curl_str_init(struct Curl_str *out);
void Curl_str_assign(struct Curl_str *out, const char *str, size_t len);
#define Curl_str(x) ((x)->str)
#define Curl_strlen(x) ((x)->len)
@ -57,11 +56,6 @@ int Curl_str_word(const char **linep, struct Curl_str *out, const size_t max);
int Curl_str_until(const char **linep, struct Curl_str *out, const size_t max,
char delim);
/* Get a word until a newline byte or end of string. At least one byte long.
return non-zero on error */
int Curl_str_untilnl(const char **linep, struct Curl_str *out,
const size_t max);
/* Get a "quoted" word. No escaping possible.
return non-zero on error */
int Curl_str_quotedword(const char **linep, struct Curl_str *out,

View File

@ -35,7 +35,6 @@
#include "strdup.h"
#include "idn.h"
#include "strparse.h"
#include "curl_memrchr.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@ -111,18 +110,26 @@ static void free_urlhandle(struct Curl_URL *u)
*/
static const char *find_host_sep(const char *url)
{
const char *sep;
const char *query;
/* Find the start of the hostname */
const char *sep = strstr(url, "//");
sep = strstr(url, "//");
if(!sep)
sep = url;
else
sep += 2;
/* Find first / or ? */
while(*sep && *sep != '/' && *sep != '?')
sep++;
query = strchr(sep, '?');
sep = strchr(sep, '/');
return sep;
if(!sep)
sep = url + strlen(url);
if(!query)
query = url + strlen(url);
return sep < query ? sep : query;
}
/* convert CURLcode to CURLUcode */
@ -148,40 +155,46 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url,
bool left = !query;
const unsigned char *iptr;
const unsigned char *host_sep = (const unsigned char *) url;
CURLcode result = CURLE_OK;
CURLcode result;
if(!relative) {
size_t n;
if(!relative)
host_sep = (const unsigned char *) find_host_sep(url);
/* output the first piece as-is */
n = (const char *)host_sep - url;
result = Curl_dyn_addn(o, url, n);
len -= n;
for(iptr = (unsigned char *)url; /* read from here */
len; iptr++, len--) {
if(iptr < host_sep) {
result = Curl_dyn_addn(o, iptr, 1);
if(result)
return cc2cu(result);
continue;
}
for(iptr = host_sep; len && !result; iptr++, len--) {
if(*iptr == ' ') {
if(left)
result = Curl_dyn_addn(o, "%20", 3);
else
result = Curl_dyn_addn(o, "+", 1);
if(result)
return cc2cu(result);
continue;
}
else if(urlchar_needs_escaping(*iptr)) {
if(*iptr == '?')
left = FALSE;
if(urlchar_needs_escaping(*iptr)) {
char out[3]={'%'};
out[1] = hexdigits[*iptr >> 4];
out[2] = hexdigits[*iptr & 0xf];
result = Curl_dyn_addn(o, out, 3);
}
else {
else
result = Curl_dyn_addn(o, iptr, 1);
if(*iptr == '?')
left = FALSE;
}
}
if(result)
return cc2cu(result);
}
return CURLUE_OK;
}
@ -234,76 +247,87 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
}
/*
* Concatenate a relative URL onto a base URL making it absolute.
* Concatenate a relative URL to a base URL making it absolute.
*
* Note that this function destroys the 'base' string.
*/
static CURLUcode redirect_url(const char *base, const char *relurl,
static CURLUcode redirect_url(char *base, const char *relurl,
CURLU *u, unsigned int flags)
{
struct dynbuf urlbuf;
bool host_changed = FALSE;
const char *useurl = relurl;
const char *cutoff = NULL;
size_t prelen;
CURLcode result = CURLE_OK;
CURLUcode uc;
/* protsep points to the start of the hostname */
char *protsep = strstr(base, "//");
DEBUGASSERT(protsep);
if(!protsep)
protsep = base;
else
protsep += 2; /* pass the slashes */
/* protsep points to the start of the hostname, after [scheme]:// */
const char *protsep = base + strlen(u->scheme) + 3;
DEBUGASSERT(base && relurl && u); /* all set here */
if(!base)
return CURLUE_MALFORMED_INPUT; /* should never happen */
if(('/' != relurl[0]) && ('#' != relurl[0])) {
/* First we need to find out if there is a ?-letter in the original URL,
and cut it and the right-side of that off */
char *pathsep = strchr(protsep, '?');
if(pathsep)
*pathsep = 0;
else {
/* if not, cut off the potential fragment */
pathsep = strchr(protsep, '#');
if(pathsep)
*pathsep = 0;
}
/* if the redirect-to piece is not just a query, cut the path after the
last slash */
if(useurl[0] != '?') {
pathsep = strrchr(protsep, '/');
if(pathsep)
pathsep[1] = 0; /* leave the slash */
}
}
else if('/' == relurl[0]) {
/* We got a new absolute path for this server */
/* handle different relative URL types */
switch(relurl[0]) {
case '/':
if(relurl[1] == '/') {
/* protocol-relative URL: //example.com/path */
cutoff = protsep;
useurl = &relurl[2];
/* the new URL starts with //, just keep the protocol part from the
original one */
*protsep = 0;
useurl = &relurl[2]; /* we keep the slashes from the original, so we
skip the new ones */
host_changed = TRUE;
}
else
/* absolute /path */
cutoff = strchr(protsep, '/');
break;
case '#':
/* fragment-only change */
if(u->fragment)
cutoff = strchr(protsep, '#');
break;
default:
/* path or query-only change */
if(u->query && u->query[0])
/* remove existing query */
cutoff = strchr(protsep, '?');
else if(u->fragment && u->fragment[0])
/* Remove existing fragment */
cutoff = strchr(protsep, '#');
if(relurl[0] != '?') {
/* append a relative path after the last slash */
cutoff = memrchr(protsep, '/',
cutoff ? (size_t)(cutoff - protsep) : strlen(protsep));
if(cutoff)
cutoff++; /* truncate after last slash */
else {
/* cut the original URL at first slash */
char *pathsep = strchr(protsep, '/');
if(pathsep)
*pathsep = 0;
}
break;
}
else {
/* the relative piece starts with '#' */
/* If there is a fragment in the original URL, cut it off */
char *pathsep = strchr(protsep, '#');
if(pathsep)
*pathsep = 0;
}
prelen = cutoff ? (size_t)(cutoff - base) : strlen(base);
/* build new URL */
Curl_dyn_init(&urlbuf, CURL_MAX_INPUT_LENGTH);
if(!Curl_dyn_addn(&urlbuf, base, prelen) &&
!urlencode_str(&urlbuf, useurl, strlen(useurl), !host_changed, FALSE)) {
uc = parseurl_and_replace(Curl_dyn_ptr(&urlbuf), u,
flags & ~CURLU_PATH_AS_IS);
}
else
uc = CURLUE_OUT_OF_MEMORY;
/* copy over the root URL part */
result = Curl_dyn_add(&urlbuf, base);
if(result)
return cc2cu(result);
/* then append the new piece on the right side */
uc = urlencode_str(&urlbuf, useurl, strlen(useurl), !host_changed,
FALSE);
if(!uc)
uc = parseurl_and_replace(Curl_dyn_ptr(&urlbuf), u,
flags&~CURLU_PATH_AS_IS);
Curl_dyn_free(&urlbuf);
return uc;
}
@ -1416,10 +1440,8 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
punycode = (flags & CURLU_PUNYCODE) ? 1 : 0;
depunyfy = (flags & CURLU_PUNY2IDN) ? 1 : 0;
if(u->scheme && strcasecompare("file", u->scheme)) {
url = aprintf("file://%s%s%s%s%s",
url = aprintf("file://%s%s%s",
u->path,
show_query ? "?": "",
u->query ? u->query : "",
show_fragment ? "#": "",
u->fragment ? u->fragment : "");
}
@ -1773,7 +1795,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|| curl_url_get(u, CURLUPART_URL, &oldurl, flags)) {
return parseurl_and_replace(part, u, flags);
}
DEBUGASSERT(oldurl); /* it is set here */
/* apply the relative part to create a new URL */
uc = redirect_url(oldurl, part, u, flags);
free(oldurl);

View File

@ -565,12 +565,14 @@ struct hostname {
#if defined(CURLRES_ASYNCH) || !defined(CURL_DISABLE_DOH)
#define USE_CURL_ASYNC
struct Curl_async {
char *hostname;
struct Curl_dns_entry *dns;
#ifdef CURLRES_ASYNCH
struct thread_data thdata;
#endif
void *resolver; /* resolver state, if it is used in the URL state -
ares_channel e.g. */
int port;
BIT(done); /* set TRUE when the lookup is complete */
};
@ -1688,9 +1690,6 @@ struct UserDefined {
struct curl_slist *mail_rcpt; /* linked list of mail recipients */
#endif
unsigned int maxconnects; /* Max idle connections in the connection cache */
#ifdef USE_ECH
int tls_ech; /* TLS ECH configuration */
#endif
unsigned short use_port; /* which port to use (when not using default) */
#ifndef CURL_DISABLE_BINDLOCAL
unsigned short localport; /* local port number to bind to */
@ -1828,6 +1827,9 @@ struct UserDefined {
#ifndef CURL_DISABLE_WEBSOCKETS
BIT(ws_raw_mode);
#endif
#ifdef USE_ECH
int tls_ech; /* TLS ECH configuration */
#endif
};
#ifndef CURL_DISABLE_MIME

View File

@ -113,12 +113,88 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
/* we are always running on PLATFORM_WINNT */
matched = FALSE;
}
#elif defined(UNDER_CE)
(void)majorVersion;
(void)minorVersion;
(void)buildVersion;
(void)platform;
(void)condition;
#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
OSVERSIONINFO osver;
memset(&osver, 0, sizeof(osver));
osver.dwOSVersionInfoSize = sizeof(osver);
/* Find out Windows version */
if(GetVersionEx(&osver)) {
/* Verify the Operating System version number */
switch(condition) {
case VERSION_LESS_THAN:
if(osver.dwMajorVersion < majorVersion ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion < minorVersion) ||
(buildVersion != 0 &&
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion == minorVersion &&
osver.dwBuildNumber < buildVersion)))
matched = TRUE;
break;
case VERSION_LESS_THAN_EQUAL:
if(osver.dwMajorVersion < majorVersion ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion < minorVersion) ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion == minorVersion &&
(buildVersion == 0 ||
osver.dwBuildNumber <= buildVersion)))
matched = TRUE;
break;
case VERSION_EQUAL:
if(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion == minorVersion &&
(buildVersion == 0 ||
osver.dwBuildNumber == buildVersion))
matched = TRUE;
break;
case VERSION_GREATER_THAN_EQUAL:
if(osver.dwMajorVersion > majorVersion ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion > minorVersion) ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion == minorVersion &&
(buildVersion == 0 ||
osver.dwBuildNumber >= buildVersion)))
matched = TRUE;
break;
case VERSION_GREATER_THAN:
if(osver.dwMajorVersion > majorVersion ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion > minorVersion) ||
(buildVersion != 0 &&
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion == minorVersion &&
osver.dwBuildNumber > buildVersion)))
matched = TRUE;
break;
}
/* Verify the platform identifier (if necessary) */
if(matched) {
switch(platform) {
case PLATFORM_WINDOWS:
if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
matched = FALSE;
break;
case PLATFORM_WINNT:
if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
matched = FALSE;
break;
default: /* like platform == PLATFORM_DONT_CARE */
break;
}
}
}
#else
ULONGLONG cm = 0;
struct OUR_OSVERSIONINFOEXW osver;

View File

@ -481,27 +481,17 @@ static int cf_ngtcp2_handshake_completed(ngtcp2_conn *tconn, void *user_data)
* the handshake time when we really did connect */
if(ctx->use_earlydata)
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, ctx->handshake_at);
if(ctx->use_earlydata) {
#ifdef USE_GNUTLS
if(ctx->use_earlydata) {
int flags = gnutls_session_get_flags(ctx->tls.gtls.session);
ctx->earlydata_accepted = !!(flags & GNUTLS_SFLAGS_EARLY_DATA);
#endif
#ifdef USE_WOLFSSL
#ifdef WOLFSSL_EARLY_DATA
ctx->earlydata_accepted =
(wolfSSL_get_early_data_status(ctx->tls.wssl.ssl) !=
WOLFSSL_EARLY_DATA_REJECTED);
#else
DEBUGASSERT(0); /* should not come here if ED is disabled. */
ctx->earlydata_accepted = FALSE;
#endif /* WOLFSSL_EARLY_DATA */
#endif
CURL_TRC_CF(data, cf, "server did%s accept %zu bytes of early data",
ctx->earlydata_accepted ? "" : " not", ctx->earlydata_skip);
Curl_pgrsEarlyData(data, ctx->earlydata_accepted ?
(curl_off_t)ctx->earlydata_skip :
-(curl_off_t)ctx->earlydata_skip);
}
#endif
return 0;
}
@ -2267,23 +2257,8 @@ static int wssl_quic_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session)
struct Curl_easy *data = CF_DATA_CURRENT(cf);
DEBUGASSERT(data);
if(data && ctx) {
ngtcp2_ssize tplen;
uint8_t tpbuf[256];
unsigned char *quic_tp = NULL;
size_t quic_tp_len = 0;
tplen = ngtcp2_conn_encode_0rtt_transport_params(ctx->qconn, tpbuf,
sizeof(tpbuf));
if(tplen < 0)
CURL_TRC_CF(data, cf, "error encoding 0RTT transport data: %s",
ngtcp2_strerror((int)tplen));
else {
quic_tp = (unsigned char *)tpbuf;
quic_tp_len = (size_t)tplen;
}
(void)Curl_wssl_cache_session(cf, data, ctx->peer.scache_key,
session, wolfSSL_version(ssl),
"h3", quic_tp, quic_tp_len);
session, wolfSSL_version(ssl), "h3");
}
}
return 0;
@ -2333,13 +2308,13 @@ static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf,
}
#elif defined(USE_WOLFSSL)
if(ngtcp2_crypto_wolfssl_configure_client_context(ctx->wssl.ssl_ctx) != 0) {
if(ngtcp2_crypto_wolfssl_configure_client_context(ctx->wssl.ctx) != 0) {
failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
return CURLE_FAILED_INIT;
}
if(ssl_config->primary.cache_session) {
/* Register to get notified when a new session is received */
wolfSSL_CTX_sess_set_new_cb(ctx->wssl.ssl_ctx, wssl_quic_new_session_cb);
wolfSSL_CTX_sess_set_new_cb(ctx->wssl.ctx, wssl_quic_new_session_cb);
}
#endif
return CURLE_OK;
@ -2347,7 +2322,6 @@ static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf,
static CURLcode cf_ngtcp2_on_session_reuse(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct alpn_spec *alpns,
struct Curl_ssl_session *scs,
bool *do_early_data)
{
@ -2358,19 +2332,10 @@ static CURLcode cf_ngtcp2_on_session_reuse(struct Curl_cfilter *cf,
#ifdef USE_GNUTLS
ctx->earlydata_max =
gnutls_record_get_max_early_data_size(ctx->tls.gtls.session);
#endif
#ifdef USE_WOLFSSL
#ifdef WOLFSSL_EARLY_DATA
ctx->earlydata_max = scs->earlydata_max;
#else
ctx->earlydata_max = 0;
#endif /* WOLFSSL_EARLY_DATA */
#endif
#if defined(USE_GNUTLS) || defined(USE_WOLFSSL)
if((!ctx->earlydata_max)) {
CURL_TRC_CF(data, cf, "SSL session does not allow earlydata");
}
else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) {
else if(strcmp("h3", scs->alpn)) {
CURL_TRC_CF(data, cf, "SSL session from different ALPN, no early data");
}
else if(!scs->quic_tp || !scs->quic_tp_len) {
@ -2398,7 +2363,6 @@ static CURLcode cf_ngtcp2_on_session_reuse(struct Curl_cfilter *cf,
(void)data;
(void)ctx;
(void)scs;
(void)alpns;
#endif
return result;
}
@ -2416,9 +2380,6 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
CURLcode result;
const struct Curl_sockaddr_ex *sockaddr = NULL;
int qfd;
static const struct alpn_spec ALPN_SPEC_H3 = {
{ "h3", "h3-29" }, 2
};
DEBUGASSERT(ctx->initialized);
ctx->dcid.datalen = NGTCP2_MAX_CIDLEN;
@ -2462,7 +2423,9 @@ static const struct alpn_spec ALPN_SPEC_H3 = {
if(rc)
return CURLE_QUIC_CONNECT_ERROR;
result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer, &ALPN_SPEC_H3,
#define H3_ALPN "\x2h3\x5h3-29"
result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,
H3_ALPN, sizeof(H3_ALPN) - 1,
cf_ngtcp2_tls_ctx_setup, &ctx->tls,
&ctx->conn_ref,
cf_ngtcp2_on_session_reuse);
@ -2475,7 +2438,7 @@ static const struct alpn_spec ALPN_SPEC_H3 = {
#elif defined(USE_GNUTLS)
ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.gtls.session);
#elif defined(USE_WOLFSSL)
ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.wssl.ssl);
ngtcp2_conn_set_tls_native_handle(ctx->qconn, ctx->tls.wssl.handle);
#else
#error "ngtcp2 TLS backend not defined"
#endif

View File

@ -1163,15 +1163,13 @@ static CURLcode cf_osslq_ctx_start(struct Curl_cfilter *cf,
const struct Curl_sockaddr_ex *peer_addr = NULL;
BIO *bio = NULL;
BIO_ADDR *baddr = NULL;
static const struct alpn_spec ALPN_SPEC_H3 = {
{ "h3" }, 1
};
DEBUGASSERT(ctx->initialized);
#define H3_ALPN "\x2h3"
result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,
&ALPN_SPEC_H3, NULL, NULL, NULL, NULL);
H3_ALPN, sizeof(H3_ALPN) - 1,
NULL, NULL, NULL, NULL);
if(result)
goto out;

View File

@ -1267,9 +1267,6 @@ static CURLcode cf_quiche_ctx_open(struct Curl_cfilter *cf,
int rv;
CURLcode result;
const struct Curl_sockaddr_ex *sockaddr;
static const struct alpn_spec ALPN_SPEC_H3 = {
{ "h3" }, 1
};
DEBUGASSERT(ctx->q.sockfd != CURL_SOCKET_BAD);
DEBUGASSERT(ctx->initialized);
@ -1307,7 +1304,9 @@ static const struct alpn_spec ALPN_SPEC_H3 = {
- 1);
result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,
&ALPN_SPEC_H3, NULL, NULL, cf, NULL);
QUICHE_H3_APPLICATION_PROTOCOL,
sizeof(QUICHE_H3_APPLICATION_PROTOCOL) - 1,
NULL, NULL, cf, NULL);
if(result)
return result;

View File

@ -58,11 +58,178 @@
#include "curl_memory.h"
#include "memdebug.h"
#if defined(USE_WOLFSSL)
#define QUIC_CIPHERS \
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
"POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
#define QUIC_GROUPS "P-256:P-384:P-521"
#if defined(HAVE_SECRET_CALLBACK)
static void keylog_callback(const WOLFSSL *ssl, const char *line)
{
(void)ssl;
Curl_tls_keylog_write_line(line);
}
#endif
static CURLcode wssl_init_ctx(struct curl_tls_ctx *ctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
Curl_vquic_tls_ctx_setup *cb_setup,
void *cb_user_data)
{
struct ssl_primary_config *conn_config;
CURLcode result = CURLE_FAILED_INIT;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config) {
result = CURLE_FAILED_INIT;
goto out;
}
ctx->wssl.ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
if(!ctx->wssl.ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
if(cb_setup) {
result = cb_setup(cf, data, cb_user_data);
if(result)
goto out;
}
wolfSSL_CTX_set_default_verify_paths(ctx->wssl.ctx);
if(wolfSSL_CTX_set_cipher_list(ctx->wssl.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));
failf(data, "wolfSSL failed to set ciphers: %s", error_buffer);
result = CURLE_BAD_FUNCTION_ARGUMENT;
goto out;
}
if(wolfSSL_CTX_set1_groups_list(ctx->wssl.ctx, conn_config->curves ?
conn_config->curves :
(char *)QUIC_GROUPS) != 1) {
failf(data, "wolfSSL failed to set curves");
result = CURLE_BAD_FUNCTION_ARGUMENT;
goto out;
}
/* Open the file if a TLS or QUIC backend has not done this before. */
Curl_tls_keylog_open();
if(Curl_tls_keylog_enabled()) {
#if defined(HAVE_SECRET_CALLBACK)
wolfSSL_CTX_set_keylog_callback(ctx->wssl.ctx, keylog_callback);
#else
failf(data, "wolfSSL was built without keylog callback");
result = CURLE_NOT_BUILT_IN;
goto out;
#endif
}
if(conn_config->verifypeer) {
const char * const ssl_cafile = conn_config->CAfile;
const char * const ssl_capath = conn_config->CApath;
wolfSSL_CTX_set_verify(ctx->wssl.ctx, SSL_VERIFY_PEER, NULL);
if(ssl_cafile || ssl_capath) {
/* tell wolfSSL where to find CA certificates that are used to verify
the server's certificate. */
int rc =
wolfSSL_CTX_load_verify_locations_ex(ctx->wssl.ctx, ssl_cafile,
ssl_capath,
WOLFSSL_LOAD_FLAG_IGNORE_ERR);
if(SSL_SUCCESS != rc) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:"
" CAfile: %s CApath: %s",
ssl_cafile ? ssl_cafile : "none",
ssl_capath ? ssl_capath : "none");
result = CURLE_SSL_CACERT_BADFILE;
goto out;
}
infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
}
#ifdef CURL_CA_FALLBACK
else {
/* verifying the peer without any CA certificates will not work so
use wolfSSL's built-in default as fallback */
wolfSSL_CTX_set_default_verify_paths(ctx->wssl.ctx);
}
#endif
}
else {
wolfSSL_CTX_set_verify(ctx->wssl.ctx, SSL_VERIFY_NONE, NULL);
}
/* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) {
Curl_set_in_callback(data, TRUE);
result = (*data->set.ssl.fsslctx)(data, ctx->wssl.ctx,
data->set.ssl.fsslctxp);
Curl_set_in_callback(data, FALSE);
if(result) {
failf(data, "error signaled by ssl ctx callback");
goto out;
}
}
result = CURLE_OK;
out:
if(result && ctx->wssl.ctx) {
SSL_CTX_free(ctx->wssl.ctx);
ctx->wssl.ctx = NULL;
}
return result;
}
/** SSL callbacks ***/
static CURLcode wssl_init_ssl(struct curl_tls_ctx *ctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const char *alpn, size_t alpn_len,
void *user_data)
{
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(!ctx->wssl.handle);
DEBUGASSERT(ctx->wssl.ctx);
ctx->wssl.handle = wolfSSL_new(ctx->wssl.ctx);
wolfSSL_set_app_data(ctx->wssl.handle, user_data);
wolfSSL_set_connect_state(ctx->wssl.handle);
wolfSSL_set_quic_use_legacy_codepoint(ctx->wssl.handle, 0);
if(alpn)
wolfSSL_set_alpn_protos(ctx->wssl.handle, (const unsigned char *)alpn,
(unsigned int)alpn_len);
if(peer->sni) {
wolfSSL_UseSNI(ctx->wssl.handle, WOLFSSL_SNI_HOST_NAME,
peer->sni, (unsigned short)strlen(peer->sni));
}
if(ssl_config->primary.cache_session) {
(void)Curl_wssl_setup_session(cf, data, &ctx->wssl, peer->scache_key);
}
return CURLE_OK;
}
#endif /* defined(USE_WOLFSSL) */
CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns,
const char *alpn, size_t alpn_len,
Curl_vquic_tls_ctx_setup *cb_setup,
void *cb_user_data, void *ssl_user_data,
Curl_vquic_session_reuse_cb *session_reuse_cb)
@ -87,16 +254,21 @@ CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
#ifdef USE_OPENSSL
(void)result;
return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer, alpns,
return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer,
(const unsigned char *)alpn, alpn_len,
cb_setup, cb_user_data, NULL, ssl_user_data);
#elif defined(USE_GNUTLS)
return Curl_gtls_ctx_init(&ctx->gtls, cf, data, peer, alpns,
return Curl_gtls_ctx_init(&ctx->gtls, cf, data, peer,
(const unsigned char *)alpn, alpn_len,
cb_setup, cb_user_data, ssl_user_data,
session_reuse_cb);
#elif defined(USE_WOLFSSL)
return Curl_wssl_ctx_init(&ctx->wssl, cf, data, peer, alpns,
cb_setup, cb_user_data,
ssl_user_data, session_reuse_cb);
result = wssl_init_ctx(ctx, cf, data, cb_setup, cb_user_data);
if(result)
return result;
(void)session_reuse_cb;
return wssl_init_ssl(ctx, cf, data, peer, alpn, alpn_len, ssl_user_data);
#else
#error "no TLS lib in used, should not happen"
return CURLE_FAILED_INIT;
@ -115,10 +287,10 @@ void Curl_vquic_tls_cleanup(struct curl_tls_ctx *ctx)
gnutls_deinit(ctx->gtls.session);
Curl_gtls_shared_creds_free(&ctx->gtls.shared_creds);
#elif defined(USE_WOLFSSL)
if(ctx->wssl.ssl)
wolfSSL_free(ctx->wssl.ssl);
if(ctx->wssl.ssl_ctx)
wolfSSL_CTX_free(ctx->wssl.ssl_ctx);
if(ctx->wssl.handle)
wolfSSL_free(ctx->wssl.handle);
if(ctx->wssl.ctx)
wolfSSL_CTX_free(ctx->wssl.ctx);
#endif
memset(ctx, 0, sizeof(*ctx));
}
@ -179,7 +351,7 @@ CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx,
(void)data;
if(conn_config->verifyhost) {
if(peer->sni) {
WOLFSSL_X509* cert = wolfSSL_get_peer_certificate(ctx->wssl.ssl);
WOLFSSL_X509* cert = wolfSSL_get_peer_certificate(ctx->wssl.handle);
if(wolfSSL_X509_check_host(cert, peer->sni, strlen(peer->sni), 0, NULL)
== WOLFSSL_FAILURE) {
result = CURLE_PEER_FAILED_VERIFICATION;

View File

@ -27,7 +27,6 @@
#include "curl_setup.h"
#include "bufq.h"
#include "vtls/vtls.h"
#include "vtls/vtls_int.h"
#include "vtls/openssl.h"
#if defined(USE_HTTP3) && \
@ -44,7 +43,7 @@ struct curl_tls_ctx {
#elif defined(USE_GNUTLS)
struct gtls_ctx gtls;
#elif defined(USE_WOLFSSL)
struct wssl_ctx wssl;
struct wolfssl_ctx wssl;
#endif
};
@ -61,7 +60,6 @@ typedef CURLcode Curl_vquic_tls_ctx_setup(struct Curl_cfilter *cf,
typedef CURLcode Curl_vquic_session_reuse_cb(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct alpn_spec *alpns,
struct Curl_ssl_session *scs,
bool *do_early_data);
@ -72,7 +70,9 @@ typedef CURLcode Curl_vquic_session_reuse_cb(struct Curl_cfilter *cf,
* @param cf the connection filter involved
* @param data the transfer involved
* @param peer the peer that will be connected to
* @param alpns the ALPN specifications to negotiate, may be NULL
* @param alpn the ALPN string in protocol format ((len+bytes+)+),
* may be NULL
* @param alpn_len the overall number of bytes in `alpn`
* @param cb_setup optional callback for early TLS config
* @param cb_user_data user_data param for callback
* @param ssl_user_data optional pointer to set in TLS application context
@ -82,7 +82,7 @@ CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns,
const char *alpn, size_t alpn_len,
Curl_vquic_tls_ctx_setup *cb_setup,
void *cb_user_data,
void *ssl_user_data,

View File

@ -959,7 +959,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
return CURLE_SSL_CONNECT_ERROR;
}
}
else {
else if(ssl_config->key_passwd) {
const unsigned int supported_key_encryption_algorithms =
GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
@ -974,12 +974,22 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
supported_key_encryption_algorithms);
if(rc != GNUTLS_E_SUCCESS) {
failf(data,
"error reading X.509 %skey file: %s",
ssl_config->key_passwd ? "potentially-encrypted " : "",
"error reading X.509 potentially-encrypted key file: %s",
gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
}
else {
if(gnutls_certificate_set_x509_key_file(
gtls->shared_creds->creds,
config->clientcert,
ssl_config->key ? ssl_config->key : config->clientcert,
gnutls_do_file_type(ssl_config->cert_type) ) !=
GNUTLS_E_SUCCESS) {
failf(data, "error reading X.509 key or certificate file");
return CURLE_SSL_CONNECT_ERROR;
}
}
}
#ifdef USE_GNUTLS_SRP
@ -1032,7 +1042,6 @@ static int keylog_callback(gnutls_session_t session, const char *label,
static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct alpn_spec *alpns,
struct Curl_ssl_session *scs,
bool *do_early_data)
{
@ -1048,13 +1057,13 @@ static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf,
/* Seems to be GnuTLS way to signal no EarlyData in session */
CURL_TRC_CF(data, cf, "SSL session does not allow earlydata");
}
else if(!Curl_alpn_contains_proto(alpns, scs->alpn)) {
else if(!Curl_alpn_contains_proto(connssl->alpn, scs->alpn)) {
CURL_TRC_CF(data, cf, "SSL session has different ALPN, no early data");
}
else {
infof(data, "SSL session allows %zu bytes of early data, "
"reusing ALPN '%s'", connssl->earlydata_max, scs->alpn);
connssl->earlydata_state = ssl_earlydata_await;
connssl->earlydata_state = ssl_earlydata_use;
connssl->state = ssl_connection_deferred;
result = Curl_alpn_set_negotiated(cf, data, connssl,
(const unsigned char *)scs->alpn,
@ -1068,7 +1077,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns_requested,
const unsigned char *alpn, size_t alpn_len,
Curl_gtls_ctx_setup_cb *cb_setup,
void *cb_user_data,
void *ssl_user_data,
@ -1077,16 +1086,13 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
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);
struct Curl_ssl_session *scs = NULL;
gnutls_datum_t gtls_alpns[ALPN_ENTRIES_MAX];
gnutls_datum_t gtls_alpns[5];
size_t gtls_alpns_count = 0;
bool gtls_session_setup = FALSE;
struct alpn_spec alpns;
CURLcode result;
int rc;
DEBUGASSERT(gctx);
Curl_alpn_copy(&alpns, alpns_requested);
/* This might be a reconnect, so we check for a session ID in the cache
to speed up things. We need to do this before constructing the gnutls
session since we need to set flags depending on the kind of reuse. */
@ -1095,8 +1101,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
if(result)
goto out;
if(scs && scs->sdata && scs->sdata_len &&
(!scs->alpn || Curl_alpn_contains_proto(&alpns, scs->alpn))) {
if(scs && scs->sdata && scs->sdata_len) {
/* we got a cached session, use it! */
result = gtls_client_init(cf, data, peer, scs->earlydata_max, gctx);
@ -1110,19 +1115,30 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
else {
infof(data, "SSL reusing session with ALPN '%s'",
scs->alpn ? scs->alpn : "-");
if(ssl_config->earlydata && scs->alpn &&
if(ssl_config->earlydata &&
!cf->conn->connect_only &&
(gnutls_protocol_get_version(gctx->session) == GNUTLS_TLS1_3)) {
bool do_early_data = FALSE;
if(sess_reuse_cb) {
result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data);
result = sess_reuse_cb(cf, data, scs, &do_early_data);
if(result)
goto out;
}
if(do_early_data) {
/* We only try the ALPN protocol the session used before,
* otherwise we might send early data for the wrong protocol */
Curl_alpn_restrict_to(&alpns, scs->alpn);
gtls_alpns[0].data = (unsigned char *)scs->alpn;
gtls_alpns[0].size = (unsigned)strlen(scs->alpn);
if(gnutls_alpn_set_protocols(gctx->session,
gtls_alpns, 1,
GNUTLS_ALPN_MANDATORY)) {
failf(data, "failed setting ALPN");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
/* don't set again below */
gtls_alpns_count = 0;
alpn = NULL;
}
}
}
@ -1152,14 +1168,24 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
/* convert the ALPN string from our arguments to a list of strings that
* gnutls wants and will convert internally back to this string for sending
* to the server. nice. */
if(!gtls_alpns_count && alpns.count) {
size_t i;
DEBUGASSERT(CURL_ARRAYSIZE(gtls_alpns) >= alpns.count);
for(i = 0; i < alpns.count; ++i) {
gtls_alpns[i].data = (unsigned char *)alpns.entries[i];
gtls_alpns[i].size = (unsigned int)strlen(alpns.entries[i]);
if(!gtls_alpns_count && alpn && alpn_len) {
size_t i, alen = alpn_len;
unsigned char *salpn = (unsigned char *)alpn;
unsigned char slen;
for(i = 0; (i < CURL_ARRAYSIZE(gtls_alpns)) && alen; ++i) {
slen = salpn[0];
if(slen >= alen)
return CURLE_FAILED_INIT;
gtls_alpns[i].data = salpn + 1;
gtls_alpns[i].size = slen;
salpn += slen + 1;
alen -= (size_t)slen + 1;
}
gtls_alpns_count = alpns.count;
if(alen) { /* not all alpn chars used, wrong format or too many */
result = CURLE_FAILED_INIT;
goto out;
}
gtls_alpns_count = i;
}
if(gtls_alpns_count &&
@ -1181,6 +1207,7 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
struct ssl_connect_data *connssl = cf->ctx;
struct gtls_ssl_backend_data *backend =
(struct gtls_ssl_backend_data *)connssl->backend;
struct alpn_proto_buf proto;
CURLcode result;
DEBUGASSERT(backend);
@ -1190,15 +1217,22 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
same connection */
return CURLE_OK;
memset(&proto, 0, sizeof(proto));
if(connssl->alpn) {
result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
if(result) {
failf(data, "Error determining ALPN");
return CURLE_SSL_CONNECT_ERROR;
}
}
result = Curl_gtls_ctx_init(&backend->gtls, cf, data, &connssl->peer,
connssl->alpn, NULL, NULL, cf,
gtls_on_session_reuse);
proto.data, proto.len,
NULL, NULL, cf, gtls_on_session_reuse);
if(result)
return result;
if(connssl->alpn && (connssl->state != ssl_connection_deferred)) {
struct alpn_proto_buf proto;
memset(&proto, 0, sizeof(proto));
Curl_alpn_to_proto_str(&proto, connssl->alpn);
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
}
@ -1746,6 +1780,30 @@ out:
return result;
}
static CURLcode gtls_set_earlydata(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf, size_t blen)
{
struct ssl_connect_data *connssl = cf->ctx;
ssize_t nwritten = 0;
CURLcode result = CURLE_OK;
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_use);
DEBUGASSERT(Curl_bufq_is_empty(&connssl->earlydata));
if(blen) {
if(blen > connssl->earlydata_max)
blen = connssl->earlydata_max;
nwritten = Curl_bufq_write(&connssl->earlydata, buf, blen, &result);
CURL_TRC_CF(data, cf, "gtls_set_earlydata(len=%zu) -> %zd",
blen, nwritten);
if(nwritten < 0)
return result;
}
connssl->earlydata_state = ssl_earlydata_sending;
connssl->earlydata_skip = Curl_bufq_len(&connssl->earlydata);
return CURLE_OK;
}
static CURLcode gtls_send_earlydata(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
@ -1821,7 +1879,7 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf,
}
if(connssl->connecting_state == ssl_connect_2) {
if(connssl->earlydata_state == ssl_earlydata_await) {
if(connssl->earlydata_state == ssl_earlydata_use) {
goto out;
}
else if(connssl->earlydata_state == ssl_earlydata_sending) {
@ -1829,6 +1887,8 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf,
if(result)
goto out;
connssl->earlydata_state = ssl_earlydata_sent;
if(!Curl_ssl_cf_is_proxy(cf))
Curl_pgrsEarlyData(data, (curl_off_t)connssl->earlydata_skip);
}
DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) ||
(connssl->earlydata_state == ssl_earlydata_sent));
@ -1860,19 +1920,31 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf,
if(result)
goto out;
if(connssl->earlydata_state > ssl_earlydata_none) {
/* We should be in this state by now */
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent);
connssl->earlydata_state =
(gnutls_session_get_flags(backend->gtls.session) &
GNUTLS_SFLAGS_EARLY_DATA) ?
ssl_earlydata_accepted : ssl_earlydata_rejected;
if(connssl->earlydata_state == ssl_earlydata_sent) {
/* report the true time the handshake was done */
connssl->handshake_done = Curl_now();
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, connssl->handshake_done);
if(gnutls_session_get_flags(backend->gtls.session) &
GNUTLS_SFLAGS_EARLY_DATA) {
connssl->earlydata_state = ssl_earlydata_accepted;
infof(data, "Server accepted %zu bytes of TLS early data.",
connssl->earlydata_skip);
}
else {
connssl->earlydata_state = ssl_earlydata_rejected;
if(!Curl_ssl_cf_is_proxy(cf))
Curl_pgrsEarlyData(data, -(curl_off_t)connssl->earlydata_skip);
infof(data, "Server rejected TLS early data.");
connssl->earlydata_skip = 0;
}
}
connssl->connecting_state = ssl_connect_done;
}
if(connssl->connecting_state == ssl_connect_done)
DEBUGASSERT(connssl->state == ssl_connection_complete);
if(ssl_connect_done == connssl->connecting_state) {
connssl->state = ssl_connection_complete;
*done = TRUE;
}
out:
if(result == CURLE_AGAIN) {
@ -1890,8 +1962,7 @@ static CURLcode gtls_connect(struct Curl_cfilter *cf,
bool *done)
{
struct ssl_connect_data *connssl = cf->ctx;
if((connssl->state == ssl_connection_deferred) &&
(connssl->earlydata_state == ssl_earlydata_await)) {
if(connssl->state == ssl_connection_deferred) {
/* We refuse to be pushed, we are waiting for someone to send/recv. */
*done = TRUE;
return CURLE_OK;
@ -1899,6 +1970,26 @@ static CURLcode gtls_connect(struct Curl_cfilter *cf,
return gtls_connect_common(cf, data, done);
}
static CURLcode gtls_connect_deferred(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf,
size_t blen,
bool *done)
{
struct ssl_connect_data *connssl = cf->ctx;
CURLcode result = CURLE_OK;
DEBUGASSERT(connssl->state == ssl_connection_deferred);
*done = FALSE;
if(connssl->earlydata_state == ssl_earlydata_use) {
result = gtls_set_earlydata(cf, data, buf, blen);
if(result)
return result;
}
return gtls_connect_common(cf, data, done);
}
static bool gtls_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
@ -1926,9 +2017,38 @@ static ssize_t gtls_send(struct Curl_cfilter *cf,
ssize_t rc;
size_t nwritten, total_written = 0;
(void)data;
DEBUGASSERT(backend);
if(connssl->state == ssl_connection_deferred) {
bool done = FALSE;
*curlcode = gtls_connect_deferred(cf, data, buf, blen, &done);
if(*curlcode) {
rc = -1;
goto out;
}
else if(!done) {
*curlcode = CURLE_AGAIN;
rc = -1;
goto out;
}
DEBUGASSERT(connssl->state == ssl_connection_complete);
}
if(connssl->earlydata_skip) {
if(connssl->earlydata_skip >= blen) {
connssl->earlydata_skip -= blen;
*curlcode = CURLE_OK;
rc = (ssize_t)blen;
goto out;
}
else {
total_written += connssl->earlydata_skip;
buf = ((const char *)buf) + connssl->earlydata_skip;
blen -= connssl->earlydata_skip;
connssl->earlydata_skip = 0;
}
}
while(blen) {
backend->gtls.io_result = CURLE_OK;
rc = gnutls_record_send(backend->gtls.session, buf, blen);
@ -2075,6 +2195,21 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf,
(void)data;
DEBUGASSERT(backend);
if(connssl->state == ssl_connection_deferred) {
bool done = FALSE;
*curlcode = gtls_connect_deferred(cf, data, NULL, 0, &done);
if(*curlcode) {
ret = -1;
goto out;
}
else if(!done) {
*curlcode = CURLE_AGAIN;
ret = -1;
goto out;
}
DEBUGASSERT(connssl->state == ssl_connection_complete);
}
ret = gnutls_record_recv(backend->gtls.session, buf, buffersize);
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
*curlcode = CURLE_AGAIN;

View File

@ -42,7 +42,6 @@
struct Curl_easy;
struct Curl_cfilter;
struct alpn_spec;
struct ssl_primary_config;
struct ssl_config_data;
struct ssl_peer;
@ -82,7 +81,6 @@ typedef CURLcode Curl_gtls_ctx_setup_cb(struct Curl_cfilter *cf,
typedef CURLcode Curl_gtls_init_session_reuse_cb(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct alpn_spec *alpns,
struct Curl_ssl_session *scs,
bool *do_early_data);
@ -90,7 +88,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns,
const unsigned char *alpn, size_t alpn_len,
Curl_gtls_ctx_setup_cb *cb_setup,
void *cb_user_data,
void *ssl_user_data,

View File

@ -3527,7 +3527,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns,
const unsigned char *alpn, size_t alpn_len,
Curl_ossl_ctx_setup_cb *cb_setup,
void *cb_user_data,
Curl_ossl_new_session_cb *cb_new_session,
@ -3722,21 +3722,14 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
SSL_CTX_set_mode(octx->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
if(alpn && alpn_len) {
#ifdef HAS_ALPN_OPENSSL
if(alpns && alpns->count) {
struct alpn_proto_buf proto;
memset(&proto, 0, sizeof(proto));
result = Curl_alpn_to_proto_buf(&proto, alpns);
if(result) {
failf(data, "Error determining ALPN");
return CURLE_SSL_CONNECT_ERROR;
}
if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, proto.data, (int)proto.len)) {
if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, alpn, (int)alpn_len)) {
failf(data, "Error setting ALPN");
return CURLE_SSL_CONNECT_ERROR;
}
}
#endif
}
if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
if(!result &&
@ -4060,14 +4053,25 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
{
struct ssl_connect_data *connssl = cf->ctx;
struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
struct alpn_proto_buf proto;
BIO *bio;
CURLcode result;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
DEBUGASSERT(octx);
memset(&proto, 0, sizeof(proto));
#ifdef HAS_ALPN_OPENSSL
if(connssl->alpn) {
result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
if(result) {
failf(data, "Error determining ALPN");
return CURLE_SSL_CONNECT_ERROR;
}
}
#endif
result = Curl_ossl_ctx_init(octx, cf, data, &connssl->peer,
connssl->alpn, NULL, NULL,
proto.data, proto.len, NULL, NULL,
ossl_new_session_cb, cf);
if(result)
return result;
@ -4095,8 +4099,6 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
#ifdef HAS_ALPN_OPENSSL
if(connssl->alpn) {
struct alpn_proto_buf proto;
memset(&proto, 0, sizeof(proto));
Curl_alpn_to_proto_str(&proto, connssl->alpn);
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
}
@ -4532,7 +4534,7 @@ static void infof_certstack(struct Curl_easy *data, const SSL *ssl)
sizeof(group_name), NULL);
msnprintf(group_name_final, sizeof(group_name_final), "/%s", group_name);
}
type_name = current_pkey ? EVP_PKEY_get0_type_name(current_pkey) : NULL;
type_name = EVP_PKEY_get0_type_name(current_pkey);
#else
get_group_name = 0;
type_name = NULL;

View File

@ -49,7 +49,6 @@
#define HAVE_KEYLOG_CALLBACK
#endif
struct alpn_spec;
struct ssl_peer;
/* Struct to hold a curl OpenSSL instance */
@ -81,7 +80,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns,
const unsigned char *alpn, size_t alpn_len,
Curl_ossl_ctx_setup_cb *cb_setup,
void *cb_user_data,
Curl_ossl_new_session_cb *cb_new_session,

View File

@ -43,7 +43,6 @@
#include "connect.h" /* for the connect timeout */
#include "cipher_suite.h"
#include "rand.h"
#include "x509asn1.h"
struct rustls_ssl_backend_data
{
@ -846,43 +845,6 @@ cr_connect(struct Curl_cfilter *cf,
infof(data, "rustls: handshake complete, %s, cipher: %s",
ver, buf);
}
if(data->set.ssl.certinfo) {
size_t num_certs = 0;
while(rustls_connection_get_peer_certificate(rconn, (int)num_certs)) {
num_certs++;
}
result = Curl_ssl_init_certinfo(data, (int)num_certs);
if(result)
return result;
for(size_t i = 0; i < num_certs; i++) {
const rustls_certificate *cert;
const unsigned char *der_data;
size_t der_len;
rustls_result rresult = RUSTLS_RESULT_OK;
cert = rustls_connection_get_peer_certificate(rconn, i);
DEBUGASSERT(cert); /* Should exist since we counted already */
rresult = rustls_certificate_get_der(cert, &der_data, &der_len);
if(rresult != RUSTLS_RESULT_OK) {
char errorbuf[255];
size_t errorlen;
rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen);
failf(data,
"Failed getting DER of server certificate #%ld: %.*s", i,
(int)errorlen, errorbuf);
return map_error(rresult);
}
{
const char *beg;
const char *end;
beg = (const char *)der_data;
end = (const char *)(der_data + der_len);
result = Curl_extract_certinfo(data, (int)i, beg, end);
if(result)
return result;
}
}
}
connssl->state = ssl_connection_complete;
*done = TRUE;
return CURLE_OK;
@ -1049,8 +1011,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
SSLSUPP_CAINFO_BLOB | /* supports */
SSLSUPP_HTTPS_PROXY |
SSLSUPP_CIPHER_LIST |
SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_CERTINFO,
SSLSUPP_TLS13_CIPHERSUITES,
sizeof(struct rustls_ssl_backend_data),
NULL, /* init */

View File

@ -898,6 +898,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
unsigned char alpn_buffer[128];
#endif
SECURITY_STATUS sspi_status = SEC_E_OK;
struct Curl_schannel_cred *old_cred = NULL;
CURLcode result;
DEBUGASSERT(backend);
@ -954,10 +955,9 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
/* check for an existing reusable credential handle */
if(ssl_config->primary.cache_session) {
struct Curl_schannel_cred *old_cred;
Curl_ssl_scache_lock(data);
old_cred = Curl_ssl_scache_get_obj(cf, data, connssl->peer.scache_key);
if(old_cred) {
if(Curl_ssl_scache_get_obj(cf, data, connssl->peer.scache_key,
(void **)&old_cred)) {
backend->cred = old_cred;
DEBUGF(infof(data, "schannel: reusing existing credential handle"));

View File

@ -1333,9 +1333,8 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
size_t ssl_sessionid_len;
Curl_ssl_scache_lock(data);
ssl_sessionid = Curl_ssl_scache_get_obj(cf, data,
connssl->peer.scache_key);
if(ssl_sessionid) {
if(Curl_ssl_scache_get_obj(cf, data, connssl->peer.scache_key,
(void **)&ssl_sessionid)) {
/* we got a session id, use it! */
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid,
strlen(ssl_sessionid));

View File

@ -485,6 +485,18 @@ static void cf_ctx_free(struct ssl_connect_data *ctx)
}
}
static CURLcode
ssl_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done)
{
struct ssl_connect_data *connssl = cf->ctx;
if(!ssl_prefs_check(data))
return CURLE_SSL_CONNECT_ERROR;
/* mark this is being ssl requested from here on. */
return connssl->ssl_impl->do_connect(cf, data, done);
}
CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex,
struct dynbuf *binding)
{
@ -1306,7 +1318,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
struct cf_call_data save;
CURLcode result;
if(cf->connected && (connssl->state != ssl_connection_deferred)) {
if(cf->connected) {
*done = TRUE;
return CURLE_OK;
}
@ -1324,6 +1336,8 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
CF_DATA_SAVE(save, cf, data);
CURL_TRC_CF(data, cf, "cf_connect()");
DEBUGASSERT(data->conn);
DEBUGASSERT(data->conn == cf->conn);
DEBUGASSERT(connssl);
*done = FALSE;
@ -1335,13 +1349,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
goto out;
}
if(!connssl->prefs_checked) {
if(!ssl_prefs_check(data))
return CURLE_SSL_CONNECT_ERROR;
connssl->prefs_checked = TRUE;
}
result = connssl->ssl_impl->do_connect(cf, data, done);
result = ssl_connect(cf, data, done);
if(!result && *done) {
cf->connected = TRUE;
@ -1350,8 +1358,6 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
/* Connection can be deferred when sending early data */
DEBUGASSERT(connssl->state == ssl_connection_complete ||
connssl->state == ssl_connection_deferred);
DEBUGASSERT(connssl->state != ssl_connection_deferred ||
connssl->earlydata_state > ssl_earlydata_none);
}
out:
CURL_TRC_CF(data, cf, "cf_connect() -> %d, done=%d", result, *done);
@ -1359,77 +1365,6 @@ out:
return result;
}
static CURLcode ssl_cf_set_earlydata(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf, size_t blen)
{
struct ssl_connect_data *connssl = cf->ctx;
ssize_t nwritten = 0;
CURLcode result = CURLE_OK;
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_await);
DEBUGASSERT(Curl_bufq_is_empty(&connssl->earlydata));
if(blen) {
if(blen > connssl->earlydata_max)
blen = connssl->earlydata_max;
nwritten = Curl_bufq_write(&connssl->earlydata, buf, blen, &result);
CURL_TRC_CF(data, cf, "ssl_cf_set_earlydata(len=%zu) -> %zd",
blen, nwritten);
if(nwritten < 0)
return result;
}
return CURLE_OK;
}
static CURLcode ssl_cf_connect_deferred(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf, size_t blen,
bool *done)
{
struct ssl_connect_data *connssl = cf->ctx;
CURLcode result = CURLE_OK;
DEBUGASSERT(connssl->state == ssl_connection_deferred);
*done = FALSE;
if(connssl->earlydata_state == ssl_earlydata_await) {
result = ssl_cf_set_earlydata(cf, data, buf, blen);
if(result)
return result;
/* we buffered any early data we'd like to send. Actually
* do the connect now which sends it and performs the handshake. */
connssl->earlydata_state = ssl_earlydata_sending;
connssl->earlydata_skip = Curl_bufq_len(&connssl->earlydata);
}
result = ssl_cf_connect(cf, data, done);
if(!result && *done) {
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, connssl->handshake_done);
switch(connssl->earlydata_state) {
case ssl_earlydata_none:
break;
case ssl_earlydata_accepted:
if(!Curl_ssl_cf_is_proxy(cf))
Curl_pgrsEarlyData(data, (curl_off_t)connssl->earlydata_skip);
infof(data, "Server accepted %zu bytes of TLS early data.",
connssl->earlydata_skip);
break;
case ssl_earlydata_rejected:
if(!Curl_ssl_cf_is_proxy(cf))
Curl_pgrsEarlyData(data, -(curl_off_t)connssl->earlydata_skip);
infof(data, "Server rejected TLS early data.");
connssl->earlydata_skip = 0;
break;
default:
/* This should not happen. Either we do not use early data or we
* should know if it was accepted or not. */
DEBUGASSERT(NULL);
break;
}
}
return result;
}
static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
@ -1448,57 +1383,21 @@ static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
}
static ssize_t ssl_cf_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf, size_t blen,
struct Curl_easy *data, const void *buf, size_t len,
bool eos, CURLcode *err)
{
struct ssl_connect_data *connssl = cf->ctx;
struct cf_call_data save;
ssize_t nwritten = 0, early_written = 0;
ssize_t nwritten = 0;
(void)eos;
*err = CURLE_OK;
CF_DATA_SAVE(save, cf, data);
if(connssl->state == ssl_connection_deferred) {
bool done = FALSE;
*err = ssl_cf_connect_deferred(cf, data, buf, blen, &done);
if(*err) {
nwritten = -1;
goto out;
}
else if(!done) {
*err = CURLE_AGAIN;
nwritten = -1;
goto out;
}
DEBUGASSERT(connssl->state == ssl_connection_complete);
}
if(connssl->earlydata_skip) {
if(connssl->earlydata_skip >= blen) {
connssl->earlydata_skip -= blen;
*err = CURLE_OK;
nwritten = (ssize_t)blen;
goto out;
}
else {
early_written = connssl->earlydata_skip;
buf = ((const char *)buf) + connssl->earlydata_skip;
blen -= connssl->earlydata_skip;
connssl->earlydata_skip = 0;
}
}
/* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */
if(blen > 0)
nwritten = connssl->ssl_impl->send_plain(cf, data, buf, blen, err);
if(nwritten >= 0)
nwritten += early_written;
out:
*err = CURLE_OK;
if(len > 0) {
CF_DATA_SAVE(save, cf, data);
nwritten = connssl->ssl_impl->send_plain(cf, data, buf, len, err);
CF_DATA_RESTORE(cf, save);
}
return nwritten;
}
@ -1512,21 +1411,6 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
CF_DATA_SAVE(save, cf, data);
*err = CURLE_OK;
if(connssl->state == ssl_connection_deferred) {
bool done = FALSE;
*err = ssl_cf_connect_deferred(cf, data, NULL, 0, &done);
if(*err) {
nread = -1;
goto out;
}
else if(!done) {
*err = CURLE_AGAIN;
nread = -1;
goto out;
}
DEBUGASSERT(connssl->state == ssl_connection_complete);
}
nread = connssl->ssl_impl->recv_plain(cf, data, buf, len, err);
if(nread > 0) {
DEBUGASSERT((size_t)nread <= len);
@ -1535,8 +1419,6 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
/* eof */
*err = CURLE_OK;
}
out:
CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len,
nread, *err);
CF_DATA_RESTORE(cf, save);
@ -1551,9 +1433,7 @@ static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf,
CURLcode result = CURLE_OK;
*done = TRUE;
/* If we have done the SSL handshake, shut down the connection cleanly */
if(cf->connected && (connssl->state == ssl_connection_complete) &&
!cf->shutdown && Curl_ssl->shut_down) {
if(!cf->shutdown && Curl_ssl->shut_down) {
struct cf_call_data save;
CF_DATA_SAVE(save, cf, data);
@ -1951,24 +1831,6 @@ bool Curl_alpn_contains_proto(const struct alpn_spec *spec,
return FALSE;
}
void Curl_alpn_restrict_to(struct alpn_spec *spec, const char *proto)
{
size_t plen = strlen(proto);
DEBUGASSERT(plen < sizeof(spec->entries[0]));
if(plen < sizeof(spec->entries[0])) {
memcpy(spec->entries[0], proto, plen + 1);
spec->count = 1;
}
}
void Curl_alpn_copy(struct alpn_spec *dest, const struct alpn_spec *src)
{
if(src)
memcpy(dest, src, sizeof(*dest));
else
memset(dest, 0, sizeof(*dest));
}
CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_connect_data *connssl,

View File

@ -49,7 +49,7 @@ struct ssl_connect_data;
#define ALPN_PROTO_BUF_MAX (ALPN_ENTRIES_MAX * (ALPN_NAME_MAX + 1))
struct alpn_spec {
char entries[ALPN_ENTRIES_MAX][ALPN_NAME_MAX];
const char entries[ALPN_ENTRIES_MAX][ALPN_NAME_MAX];
size_t count; /* number of entries */
};
@ -62,8 +62,6 @@ CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf,
const struct alpn_spec *spec);
CURLcode Curl_alpn_to_proto_str(struct alpn_proto_buf *buf,
const struct alpn_spec *spec);
void Curl_alpn_restrict_to(struct alpn_spec *spec, const char *proto);
void Curl_alpn_copy(struct alpn_spec *dest, const struct alpn_spec *src);
CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf,
struct Curl_easy *data,
@ -91,7 +89,7 @@ typedef enum {
typedef enum {
ssl_earlydata_none,
ssl_earlydata_await,
ssl_earlydata_use,
ssl_earlydata_sending,
ssl_earlydata_sent,
ssl_earlydata_accepted,
@ -126,7 +124,6 @@ struct ssl_connect_data {
int io_need; /* TLS signals special SEND/RECV needs */
BIT(use_alpn); /* if ALPN shall be used in handshake */
BIT(peer_closed); /* peer has closed connection */
BIT(prefs_checked); /* SSL preferences have been checked */
};

View File

@ -962,29 +962,31 @@ out:
return result;
}
void *Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
struct Curl_easy *data,
const char *ssl_peer_key)
const char *ssl_peer_key,
void **sobj)
{
struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_ssl_scache_peer *peer = NULL;
CURLcode result;
void *sobj;
*sobj = NULL;
if(!scache)
return NULL;
return FALSE;
result = cf_ssl_find_peer_by_key(data, scache, ssl_peer_key, conn_config,
&peer);
if(result)
return NULL;
return FALSE;
sobj = peer ? peer->sobj : NULL;
if(peer)
*sobj = peer->sobj;
CURL_TRC_SSLS(data, "%s cached session for '%s'",
sobj ? "Found" : "No", ssl_peer_key);
return sobj;
*sobj ? "Found" : "No", ssl_peer_key);
return !!*sobj;
}
void Curl_ssl_scache_remove_all(struct Curl_cfilter *cf,

View File

@ -85,11 +85,12 @@ void Curl_ssl_scache_unlock(struct Curl_easy *data);
* @param cf the connection filter wanting to use it
* @param data the transfer involved
* @param ssl_peer_key the key for lookup
* @retval sobj the object for the peer key or NULL
* @param sobj on return, the object for the peer key or NULL
*/
void *Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
struct Curl_easy *data,
const char *ssl_peer_key);
const char *ssl_peer_key,
void **sobj);
typedef void Curl_ssl_scache_obj_dtor(void *sobj);

File diff suppressed because it is too large Load Diff

View File

@ -29,21 +29,19 @@
#include "urldata.h"
struct alpn_spec;
struct ssl_peer;
struct Curl_ssl_session;
struct WOLFSSL;
typedef struct WOLFSSL WOLFSSL;
struct WOLFSSL_CTX;
typedef struct WOLFSSL_CTX WOLFSSL_CTX;
struct WOLFSSL_SESSION;
typedef struct WOLFSSL_SESSION WOLFSSL_SESSION;
extern const struct Curl_ssl Curl_ssl_wolfssl;
struct wssl_ctx {
struct WOLFSSL_CTX *ssl_ctx;
struct WOLFSSL *ssl;
struct wolfssl_ctx {
WOLFSSL_CTX *ctx;
WOLFSSL *handle;
CURLcode io_result; /* result of last BIO cfilter operation */
CURLcode hs_result; /* result of handshake */
int io_send_blocked_len; /* length of last BIO write that EAGAINed */
BIT(x509_store_setup); /* x509 store has been set up */
BIT(shutting_down); /* TLS is being shut down */
@ -51,43 +49,21 @@ struct wssl_ctx {
size_t Curl_wssl_version(char *buffer, size_t size);
typedef CURLcode Curl_wssl_ctx_setup_cb(struct Curl_cfilter *cf,
struct Curl_easy *data,
void *user_data);
typedef CURLcode Curl_wssl_init_session_reuse_cb(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct alpn_spec *alpns,
struct Curl_ssl_session *scs,
bool *do_early_data);
CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
struct Curl_cfilter *cf,
struct Curl_easy *data,
struct ssl_peer *peer,
const struct alpn_spec *alpns,
Curl_wssl_ctx_setup_cb *cb_setup,
void *cb_user_data,
void *ssl_user_data,
Curl_wssl_init_session_reuse_cb *sess_reuse_cb);
CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct wssl_ctx *wssl);
struct wolfssl_ctx *wssl);
CURLcode Curl_wssl_setup_session(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct wssl_ctx *wss,
struct wolfssl_ctx *wss,
const char *ssl_peer_key);
CURLcode Curl_wssl_cache_session(struct Curl_cfilter *cf,
struct Curl_easy *data,
const char *ssl_peer_key,
struct WOLFSSL_SESSION *session,
WOLFSSL_SESSION *session,
int ietf_tls_id,
const char *alpn,
unsigned char *quic_tp,
size_t quic_tp_len);
const char *alpn);
#endif /* USE_WOLFSSL */

View File

@ -26,15 +26,15 @@
#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
defined(USE_MBEDTLS) || defined(USE_RUSTLS)
defined(USE_MBEDTLS)
#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_RUSTLS)
defined(USE_MBEDTLS) || defined(USE_WOLFSSL)
#define WANT_PARSEX509 /* uses Curl_parseX509() */
#endif
#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
defined(USE_MBEDTLS) || defined(USE_RUSTLS)
defined(USE_MBEDTLS)
#define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */
#endif
@ -1277,5 +1277,4 @@ done:
#endif /* WANT_EXTRACT_CERTINFO */
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP
or USE_MBEDTLS or USE_RUSTLS */
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */

View File

@ -29,7 +29,7 @@
#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
defined(USE_MBEDTLS) || defined(USE_RUSTLS)
defined(USE_MBEDTLS)
#include "cfilters.h"
#include "urldata.h"
@ -80,7 +80,7 @@ CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data,
#ifdef UNITTESTS
#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
defined(USE_MBEDTLS) || defined(USE_RUSTLS)
defined(USE_MBEDTLS)
/* used by unit1656.c */
CURLcode Curl_x509_GTime2str(struct dynbuf *store,
@ -91,6 +91,5 @@ CURLcode Curl_x509_getASN1Element(struct Curl_asn1Element *elem,
#endif
#endif
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP
or USE_MBEDTLS or USE_RUSTLS */
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */
#endif /* HEADER_CURL_X509ASN1_H */

View File

@ -482,7 +482,7 @@ AC_DEFUN([CURL_COMPILER_WORKS_IFELSE], [
#endif
]],[[
int i = 0;
return i;
exit(i);
]])
],[
tmp_compiler_works="yes"

View File

@ -1270,12 +1270,11 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
int exitcode;
#ifdef _WIN32
WSADATA wsa;
if(WSAStartup(MAKEWORD(2, 2), &wsa))
return 2;
exit(2);
#endif
memset(&hints, 0, sizeof(hints));
@ -1284,15 +1283,9 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai)
exitcode = 1; /* fail */
else {
freeaddrinfo(ai);
exitcode = 0;
}
#ifdef _WIN32
WSACleanup();
#endif
return exitcode;
exit(1); /* fail */
else
exit(0);
]])
],[
AC_MSG_RESULT([yes])
@ -1890,11 +1883,9 @@ AC_DEFUN([CURL_CHECK_FUNC_GETIFADDRS], [
error = getifaddrs(&ifa);
if(error || !ifa)
return 1; /* fail */
else {
freeifaddrs(ifa);
return 0;
}
exit(1); /* fail */
else
exit(0);
]])
],[
AC_MSG_RESULT([yes])
@ -2012,9 +2003,9 @@ AC_DEFUN([CURL_CHECK_FUNC_GMTIME_R], [
gmt = gmtime_r(&local, &result);
(void)result;
if(gmt)
return 0;
exit(0);
else
return 1;
exit(1);
]])
],[
AC_MSG_RESULT([yes])
@ -2143,13 +2134,13 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_NTOP], [
/* - */
ipv4ptr = inet_ntop(AF_INET, ipv4a, ipv4res, sizeof(ipv4res));
if(!ipv4ptr)
return 1; /* fail */
exit(1); /* fail */
if(ipv4ptr != ipv4res)
return 1; /* fail */
exit(1); /* fail */
if(!ipv4ptr[0])
return 1; /* fail */
exit(1); /* fail */
if(memcmp(ipv4res, "192.168.100.1", 13) != 0)
return 1; /* fail */
exit(1); /* fail */
/* - */
ipv6res[0] = '\0';
memset(ipv6a, 0, sizeof(ipv6a));
@ -2167,15 +2158,15 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_NTOP], [
/* - */
ipv6ptr = inet_ntop(AF_INET6, ipv6a, ipv6res, sizeof(ipv6res));
if(!ipv6ptr)
return 1; /* fail */
exit(1); /* fail */
if(ipv6ptr != ipv6res)
return 1; /* fail */
exit(1); /* fail */
if(!ipv6ptr[0])
return 1; /* fail */
exit(1); /* fail */
if(memcmp(ipv6res, "fe80::214:4fff:fe0b:76c8", 24) != 0)
return 1; /* fail */
exit(1); /* fail */
/* - */
return 0;
exit(0);
]])
],[
AC_MSG_RESULT([yes])
@ -2295,18 +2286,18 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_PTON], [
/* - */
memset(ipv4a, 1, sizeof(ipv4a));
if(1 != inet_pton(AF_INET, ipv4src, ipv4a))
return 1; /* fail */
exit(1); /* fail */
/* - */
if( (ipv4a[0] != 0xc0) ||
(ipv4a[1] != 0xa8) ||
(ipv4a[2] != 0x64) ||
(ipv4a[3] != 0x01) ||
(ipv4a[4] != 0x01) )
return 1; /* fail */
exit(1); /* fail */
/* - */
memset(ipv6a, 1, sizeof(ipv6a));
if(1 != inet_pton(AF_INET6, ipv6src, ipv6a))
return 1; /* fail */
exit(1); /* fail */
/* - */
if( (ipv6a[0] != 0xfe) ||
(ipv6a[1] != 0x80) ||
@ -2319,7 +2310,7 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_PTON], [
(ipv6a[14] != 0x76) ||
(ipv6a[15] != 0xc8) ||
(ipv6a[16] != 0x01) )
return 1; /* fail */
exit(1); /* fail */
/* - */
if( (ipv6a[2] != 0x0) ||
(ipv6a[3] != 0x0) ||
@ -2327,9 +2318,9 @@ AC_DEFUN([CURL_CHECK_FUNC_INET_PTON], [
(ipv6a[5] != 0x0) ||
(ipv6a[6] != 0x0) ||
(ipv6a[7] != 0x0) )
return 1; /* fail */
exit(1); /* fail */
/* - */
return 0;
exit(0);
]])
],[
AC_MSG_RESULT([yes])
@ -3818,11 +3809,11 @@ AC_DEFUN([CURL_CHECK_FUNC_STRERROR_R], [
buffer[0] = '\0';
string = strerror_r(EACCES, buffer, sizeof(buffer));
if(!string)
return 1; /* fail */
exit(1); /* fail */
if(!string[0])
return 1; /* fail */
exit(1); /* fail */
else
return 0;
exit(0);
]])
],[
AC_MSG_RESULT([yes])
@ -3881,11 +3872,11 @@ AC_DEFUN([CURL_CHECK_FUNC_STRERROR_R], [
buffer[0] = '\0';
error = strerror_r(EACCES, buffer, sizeof(buffer));
if(error)
return 1; /* fail */
exit(1); /* fail */
if(buffer[0] == '\0')
return 1; /* fail */
exit(1); /* fail */
else
return 0;
exit(0);
]])
],[
AC_MSG_RESULT([yes])

Some files were not shown because too many files have changed in this diff Show More