Compare commits
1 Commits
master
...
bagder/cod
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cfd58457e |
142
.github/scripts/cleancmd.pl
vendored
142
.github/scripts/cleancmd.pl
vendored
@ -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";
|
||||
open(F, "<$f") or die;
|
||||
|
||||
my $ignore = $header;
|
||||
my $sepcount = 0;
|
||||
my @out;
|
||||
while(<F>) {
|
||||
if(/^---/ && $header) {
|
||||
if(++$sepcount == 2) {
|
||||
$ignore = 0;
|
||||
}
|
||||
elsif($o =~ /^--disable-(.*)/) {
|
||||
# for the --disable options, also make the special ones
|
||||
push @aopts, "--$1";
|
||||
push @aopts, "--no-$1";
|
||||
}
|
||||
}
|
||||
}
|
||||
close(O);
|
||||
|
||||
open(C, "<./.github/scripts/spellcheck.curl")
|
||||
|| die "can't find spellcheck.curl";
|
||||
while(<C>) {
|
||||
if(/^\#/) {
|
||||
next;
|
||||
}
|
||||
chomp;
|
||||
if(/^([^ ]+)/) {
|
||||
push @asyms, $1;
|
||||
}
|
||||
next if($ignore);
|
||||
|
||||
# strip out backticked words
|
||||
$_ =~ s/`[^`]+`//g;
|
||||
|
||||
# strip out all long command line options
|
||||
$_ =~ s/--[a-z0-9-]+//g;
|
||||
|
||||
# strip out https URLs, we don't want them spellchecked
|
||||
$_ =~ s!https://[a-z0-9\#_/.-]+!!gi;
|
||||
|
||||
push @out, $_;
|
||||
}
|
||||
close(C);
|
||||
close(F);
|
||||
|
||||
# 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) {
|
||||
$ignore = 0;
|
||||
next;
|
||||
}
|
||||
next if($ignore);
|
||||
|
||||
my $l = $_;
|
||||
|
||||
# strip out backticked words
|
||||
$l =~ s/`[^`]+`//g;
|
||||
|
||||
# **bold**
|
||||
$l =~ s/\*\*(\S.*?)\*\*//g;
|
||||
# *italics*
|
||||
$l =~ s/\*(\S.*?)\*//g;
|
||||
|
||||
# strip out https URLs, we don't want them spellchecked
|
||||
$l =~ s!https://[a-z0-9\#_/.-]+!!gi;
|
||||
|
||||
$out .= $l;
|
||||
}
|
||||
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) {
|
||||
open(O, ">$f") or die;
|
||||
print O $out;
|
||||
close(O);
|
||||
}
|
||||
}
|
||||
|
||||
for my $f (@ARGV) {
|
||||
process($f);
|
||||
if(!$ignore) {
|
||||
open(O, ">$f") or die;
|
||||
print O @out;
|
||||
close(O);
|
||||
}
|
||||
|
||||
86
.github/scripts/cleanspell.pl
vendored
Executable file
86
.github/scripts/cleanspell.pl
vendored
Executable 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);
|
||||
151
.github/scripts/spellcheck.curl
vendored
151
.github/scripts/spellcheck.curl
vendored
@ -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
|
||||
4
.github/scripts/spellcheck.words
vendored
4
.github/scripts/spellcheck.words
vendored
@ -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
|
||||
|
||||
16
.github/workflows/checkdocs.yml
vendored
16
.github/workflows/checkdocs.yml
vendored
@ -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
85
.github/workflows/codeql.yml
vendored
Normal 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
|
||||
21
.github/workflows/distcheck.yml
vendored
21
.github/workflows/distcheck.yml
vendored
@ -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
|
||||
|
||||
38
.github/workflows/http3-linux.yml
vendored
38
.github/workflows/http3-linux.yml
vendored
@ -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
|
||||
|
||||
55
.github/workflows/linux.yml
vendored
55
.github/workflows/linux.yml
vendored
@ -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
|
||||
|
||||
19
.github/workflows/macos.yml
vendored
19
.github/workflows/macos.yml
vendored
@ -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
|
||||
|
||||
82
.github/workflows/non-native.yml
vendored
82
.github/workflows/non-native.yml
vendored
@ -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
|
||||
|
||||
154
.github/workflows/windows.yml
vendored
154
.github/workflows/windows.yml
vendored
@ -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} \
|
||||
-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
|
||||
[ '${{ 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 }}
|
||||
|
||||
- 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
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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,9 +264,7 @@ 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()
|
||||
message(STATUS "Found MINGW64_VERSION=${MINGW64_VERSION}")
|
||||
endif()
|
||||
unset(MINGW64_VERSION CACHE) # Avoid storing in CMake cache
|
||||
endif()
|
||||
@ -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()
|
||||
|
||||
|
||||
116
RELEASE-NOTES
116
RELEASE-NOTES
@ -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
|
||||
|
||||
55
appveyor.sh
55
appveyor.sh
@ -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
|
||||
|
||||
45
appveyor.yml
45
appveyor.yml
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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
|
||||
|
||||
~~~
|
||||
$ curl-config --libs
|
||||
~~~
|
||||
What compiler options do I need when I compile using libcurl functions?
|
||||
|
||||
$ curl-config --cflags
|
||||
|
||||
~~~
|
||||
$ curl-config --cflags
|
||||
~~~
|
||||
How do I know if libcurl was built with SSL support?
|
||||
|
||||
$ curl-config --feature | grep SSL
|
||||
|
||||
~~~
|
||||
$ curl-config --feature | grep SSL
|
||||
~~~
|
||||
What's the installed libcurl version?
|
||||
|
||||
$ curl-config --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`
|
||||
~~~
|
||||
$ `curl-config --cc --cflags` -o example source.c `curl-config --libs`
|
||||
~~~
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
@ -449,9 +449,9 @@ static int init_fifo(GlobalInfo *g)
|
||||
|
||||
static void clean_fifo(GlobalInfo *g)
|
||||
{
|
||||
epoll_ctl(g->epfd, EPOLL_CTL_DEL, g->fifofd, NULL);
|
||||
fclose(g->input);
|
||||
unlink(fifo);
|
||||
epoll_ctl(g->epfd, EPOLL_CTL_DEL, g->fifofd, NULL);
|
||||
fclose(g->input);
|
||||
unlink(fifo);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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.);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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\>*.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -15,7 +15,6 @@ TLS-backend:
|
||||
- GnuTLS
|
||||
- Schannel
|
||||
- Secure Transport
|
||||
- rustls
|
||||
Added-in: 7.19.1
|
||||
---
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -17,7 +17,6 @@ TLS-backend:
|
||||
- GnuTLS
|
||||
- Schannel
|
||||
- Secure Transport
|
||||
- rustls
|
||||
Added-in: 7.19.1
|
||||
---
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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%
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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. */
|
||||
|
||||
@ -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
|
||||
|
||||
246
lib/altsvc.c
246
lib/altsvc.c
@ -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")) {
|
||||
/* 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;
|
||||
}
|
||||
/* "clear" is a magic keyword */
|
||||
if(strcasecompare(alpnbuf, "clear")) {
|
||||
/* Flush cached alternatives for this source origin */
|
||||
altsvc_flush(asi, srcalpnid, srchost, srcport);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
do {
|
||||
if(!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 {
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if(Curl_str_single(&p, ':'))
|
||||
break;
|
||||
}
|
||||
else
|
||||
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;
|
||||
dsthost = srchost;
|
||||
dstlen = strlen(srchost);
|
||||
}
|
||||
|
||||
dstport = (unsigned short)port;
|
||||
|
||||
if(Curl_str_single(&p, '\"'))
|
||||
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
|
||||
dstport = (unsigned short)port;
|
||||
}
|
||||
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, ','))
|
||||
break;
|
||||
|
||||
/* comma means another alternative is present */
|
||||
if(Curl_str_until(&p, &alpn, MAX_ALTSVC_LINE, '='))
|
||||
break;
|
||||
Curl_str_trimblanks(&alpn);
|
||||
if(*p == ',') {
|
||||
/* comma means another alternative is presented */
|
||||
p++;
|
||||
result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while(1);
|
||||
} while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
245
lib/http.c
245
lib/http.c
@ -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 */
|
||||
return NULL;
|
||||
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))
|
||||
return TRUE; /* match! */
|
||||
}
|
||||
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,81 +1663,98 @@ 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;
|
||||
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;
|
||||
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 {
|
||||
if(*(--ptr) == ';') {
|
||||
/* copy the source */
|
||||
semicolonp = strdup(headers->data);
|
||||
if(!semicolonp) {
|
||||
Curl_dyn_free(req);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
/* put a colon where the semicolon is */
|
||||
semicolonp[ptr - headers->data] = ':';
|
||||
/* point at the colon */
|
||||
optr = &semicolonp [ptr - headers->data];
|
||||
}
|
||||
}
|
||||
ptr = optr;
|
||||
}
|
||||
else
|
||||
/* no colon */
|
||||
continue;
|
||||
}
|
||||
if(ptr && (ptr != headers->data)) {
|
||||
/* we require a colon for this to be a true header */
|
||||
|
||||
/* only send this if the contents was non-blank or done special */
|
||||
ptr++; /* pass the colon */
|
||||
while(ISSPACE(*ptr))
|
||||
ptr++;
|
||||
|
||||
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"))
|
||||
;
|
||||
else if(data->state.httpreq == HTTPREQ_POST_FORM &&
|
||||
/* this header (extended by formdata.c) is sent later */
|
||||
Curl_str_casecompare(&name, "Content-Type"))
|
||||
;
|
||||
else if(data->state.httpreq == HTTPREQ_POST_MIME &&
|
||||
/* this header is sent later */
|
||||
Curl_str_casecompare(&name, "Content-Type"))
|
||||
;
|
||||
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"))
|
||||
;
|
||||
else if(data->state.aptr.te &&
|
||||
/* when asking for Transfer-Encoding, do not pass on a custom
|
||||
Connection: */
|
||||
Curl_str_casecompare(&name, "Connection"))
|
||||
;
|
||||
else if((httpversion >= 20) &&
|
||||
Curl_str_casecompare(&name, "Transfer-Encoding"))
|
||||
/* HTTP/2 does not support chunked requests */
|
||||
;
|
||||
else if((Curl_str_casecompare(&name, "Authorization") ||
|
||||
Curl_str_casecompare(&name, "Cookie")) &&
|
||||
/* 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);
|
||||
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(result)
|
||||
return result;
|
||||
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! */
|
||||
checkprefix("Host:", compare))
|
||||
;
|
||||
else if(data->state.httpreq == HTTPREQ_POST_FORM &&
|
||||
/* this header (extended by formdata.c) is sent later */
|
||||
checkprefix("Content-Type:", compare))
|
||||
;
|
||||
else if(data->state.httpreq == HTTPREQ_POST_MIME &&
|
||||
/* this header is sent later */
|
||||
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 */
|
||||
checkprefix("Content-Length:", compare))
|
||||
;
|
||||
else if(data->state.aptr.te &&
|
||||
/* when asking for Transfer-Encoding, do not pass on a custom
|
||||
Connection: */
|
||||
checkprefix("Connection:", compare))
|
||||
;
|
||||
else if((httpversion >= 20) &&
|
||||
checkprefix("Transfer-Encoding:", compare))
|
||||
/* HTTP/2 does not support chunked requests */
|
||||
;
|
||||
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 {
|
||||
result = Curl_dyn_addf(req, "%s\r\n", compare);
|
||||
}
|
||||
if(semicolonp)
|
||||
free(semicolonp);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
headers = headers->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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:
|
||||
/*
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
memcpy(buf, src, length);
|
||||
buf[length] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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,
|
||||
|
||||
178
lib/urlapi.c
178
lib/urlapi.c
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
215
lib/vtls/gtls.c
215
lib/vtls/gtls.c
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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"));
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
188
lib/vtls/vtls.c
188
lib/vtls/vtls.c
@ -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:
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
*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,
|
||||
|
||||
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -962,29 +962,31 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
void *Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const char *ssl_peer_key)
|
||||
bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
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,
|
||||
|
||||
@ -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,
|
||||
struct Curl_easy *data,
|
||||
const char *ssl_peer_key);
|
||||
bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const char *ssl_peer_key,
|
||||
void **sobj);
|
||||
|
||||
typedef void Curl_ssl_scache_obj_dtor(void *sobj);
|
||||
|
||||
|
||||
1358
lib/vtls/wolfssl.c
1358
lib/vtls/wolfssl.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -482,7 +482,7 @@ AC_DEFUN([CURL_COMPILER_WORKS_IFELSE], [
|
||||
#endif
|
||||
]],[[
|
||||
int i = 0;
|
||||
return i;
|
||||
exit(i);
|
||||
]])
|
||||
],[
|
||||
tmp_compiler_works="yes"
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user