Compare commits

..

69 Commits

Author SHA1 Message Date
Viktor Szakats
b4834a7d6d
examples: prefer return over exit() (cont.)
Some of these calls were not in callbacks. These examples may leak
handles.

Also fix some whitespace.

Follow-up to 08c7c937dc #16507
Closes #16524
2025-03-01 02:09:02 +01:00
Viktor Szakats
5693342ec2
winbuild: reduce command-line length by dropping whitespace
Keep the `@for %%i in [...]` lines within limits by stripping whitespace
from the input `.c` source lists read from `Makefile.inc`. To avoid this
error after adding a new `.c` source:
```
configuration name: libcurl-vc14-x64-release-dll-ssl-dll-ipv6-sspi
NMAKE : fatal error U1095: expanded command line 'for %i in (altsvc.obj            amigaos.obj
           asyn-ares.obj         asyn-thread.obj       base64.obj            bufq.obj
              bufref.obj            cf-h1-proxy.obj       cf-h2-proxy.obj       cf-haproxy.obj [...]
  vssh/wolfssh.obj) do @echo ..\builds\libcurl-vc14-x64-release-dll-ssl-dll-ipv6-sspi-obj-lib/%i \
                   ' too long
Stop.
Command exited with code 2
```
Ref: https://ci.appveyor.com/project/curlorg/curl/builds/51605338/job/dqg6qtebtscb279g#L44

Reported-by: Stefan Eissing
Bug: https://github.com/curl/curl/pull/16508#issuecomment-2690443409
Fixes #16521
Closes #16528
2025-03-01 02:04:42 +01:00
Dan Fandrich
c693cc02b0 docs: vulnerabilities in debug code are not eligible for a bounty
This is code that is off by default and is therefore treated as a
regular bug.

Ref: #16526
Closes #16527
2025-02-28 14:21:46 -08:00
Viktor Szakats
e7751571eb
GHA/macos: use quictls in some jobs, other small improvements
- enable quictls in autotools and cmake jobs. autotools requires
  a workaround due to wrong libpath in the quictls pkg-config.
  nghttp3 is offered by Homebrew, but not ngtcp2, to enable H3.

- install `libnghttp2` rather than `nghttp2`.
  `libnghttp2` is preinstalled and smaller. It also avoids detecting
  `nghttpx`, which confuses `pytest`.

- limit `brew unlink openssl` to libressl/quictls jobs.

Closes #16517
2025-02-28 16:58:12 +01:00
Zhaoming Luo
7211576442
tests: fix comment in lib533
Closes #16523
2025-02-28 16:12:20 +01:00
Stefan Eissing
794dfe7fc4
gnutls: fix use of pkcs11 urls for keys/certs
Fixes #16249
Forwarded-to-us-by: Carlos Henrique Lima Melara

Always use `gnutls_certificate_set_x509_key_file2()` for loading keys
and certificates, even without a password, since this function support
pkcs11 urls.

Thanks to @tatsuhiro-t for finding this out.
Help-by: Tatsuhiro Tsujikawa

Closes #16472
2025-02-28 16:08:10 +01:00
Viktor Szakats
049352dd80
cmake: allow CURL_STATIC_CRT with shared libcurl and no curl exe
Follow-up to edfa537100 #16456

Closes #16516
2025-02-28 13:11:41 +01:00
Viktor Szakats
08c7c937dc
tidy-up: prefer return over exit(), fix fallouts
To avoid breaking the control flow and align to majority of code
already using `return`.

`exit()` has the side-effect of suppressing leak detection in cases.
Fix fallouts detected after switching to `return`.

- configure:
  - fix `getaddrinfo` run test to call `freeaddrinfo()` to pacify ASAN,
    and call `WSACleanup()` to deinit winsock2.
  - fix `getifaddrs` run test to call `freeifaddrs()` to pacify ASAN.
- tests/server:
  - setup `atexit(win32_cleanup)` via `win32_init()`.
  - return 2 instead of 1 on winsock2 init failures.
  - sws: goto cleanup instead of `exit()` in `http_connect()`.
    Follow-up to 02dfe71937 #7235
- tests/client/http:
  - cleanup memory to pacify ASAN in `h2-upgrade-extreme`,
    `tls-session-reuse`.
- examples:
  - block_ip: fix memory leak reported by CI.
  - http2-upload: avoid handle leaks.

Untouched `exit()` calls, made from callbacks:
- docs/examples: ephiperfifo.c, ghiper.c, hiperfifo.c
- tests/libtest: lib582.c, lib655.c, lib670.c
- tests/server: tftpd.c

Closes #16507
2025-02-28 13:11:41 +01:00
Stefan Eissing
2e585f5640
test488: set --output-dir
Otherwise the downloaded files land in the `tests` directory and
show up in git status.

Closes #16519
2025-02-28 12:47:31 +01:00
Viktor Szakats
399cb7130a
cmake: drop HAVE_C_FLAG_Wno_long_double logic for ancient Apple gcc
The initial curl CMake commit introduced it in 2009-04-02 via
4c5307b456. Suppressing a stray
`-Wlong-double` warning in `mprintf.c`. This was before Apple switched
to clang, and likely affected the Apple distributed GCC, version 4.2.1
at the time. It applied the workaround to CMake builds only, though
the issue seems build-tool agnostic. Yet, it was not suppressed or
reported for autotools builds.

For these reasons this logic seems obsolete and this patch drops it with
no replacement. It saves a feature detection for GCC builds for macOS.

In PR sub-commits I added (and reverted) in-source suppression. In case
it becomes necessary, that should fix it for all build tools.

Closes #16513
2025-02-28 03:40:40 +01:00
Viktor Szakats
5a021aba41
cmake: improve httpd detection for pytest
Look for `httpd` in addition to `apache2`, like `./configure` does.
It fixes detection with macOS Homebrew for example.

Closes #16515
2025-02-28 03:40:40 +01:00
Viktor Szakats
6913c9b6ab
GHA/linux: improve 'test configs' step, don't set TFLAGS for pytest
- omit comments from th config dump, show filenames for each line.
- `TFLAGS` is not used by pytest, don't set it.

Closes #16514
2025-02-28 03:40:40 +01:00
Daniel Stenberg
953cd694dc
asyn-ares: use the correct port number
Only triggers with old c-ares versions.

Follow-up to 8ded8e5f3f

Closes #16511
2025-02-27 22:18:43 +01:00
Viktor Szakats
af6172c8f2
GHA/linux: merge two package install steps
Merge pytest prereq package install step into the main package install
step, to save install time.

Closes #16509
2025-02-27 20:32:50 +01:00
Daniel Stenberg
8ded8e5f3f
urldata: remove 'hostname' from struct Curl_async
It is unnecessary duplicated information, as the host name being
resolved is already present in conn->host.

Closes #16451
2025-02-27 17:18:43 +01:00
Daniel Stenberg
7007f59caa
GHA: spellcheck curl symbols better
This now makes sure to trim off exact matches for curl symbols and long
curl commanad line options instead of using pattern matching as before.
This should catch typoed names (that still follow the pattern) better.

The cleanspell.pl script is no longer used. cleancmd.pl is used for all
markdown files.

Closes #16504
2025-02-27 13:15:21 +01:00
Daniel Stenberg
a8ad9a5758
docs: minor edits to please the new spellchecker regime 2025-02-27 13:15:21 +01:00
Viktor Szakats
cba83bfb10
runtests: accept CURL_DIRSUFFIX without ending slash
Follow-up to 3585796049 #16452
Closes #16506
2025-02-27 12:11:23 +01:00
Viktor Szakats
59f4727480
appveyor: run VS2008 job with old CMake 3.12.2
Switch VS2008 job the oldest runner machine. It adds the oldest CMake to
the Windows mix, from 2018-11-30. Not a beauty, missing support for `-B`
and Unity, but it's a version curl supports. It's newer than Old Linux.
The previous oldest was 3.16.2. It remains used with VS2010-VS2017.

Also:
- fix VS2008 job to actually build examples.
- switch VS2019 job to OpenSSL 1.1.0 that wasn't tested before.
  Migrate OpenSSL 1.0.2 to the VS2008 job.
- measure run time of individual build steps.

Follow-up to 01c25e3b00 #16458
Closes #16505
2025-02-27 12:11:08 +01:00
Viktor Szakats
08a29e7f18
GHA: tidy up parallel options, improve performance for some jobs
- replace `--parallel <n>` and `-j<n>` for individual commands with
  `MAKEFLAGS`, for jobs not yet doing it.
  This enables parallel builds in distcheck / maketgz-and-verify-in-tree,
  where `-j` option was missing.
- add `--parallel` for iOS Xcode job for improved performance.
- drop redundant `-j5` for Android jobs.
- drop stray `cmake --config` options from single-target jobs (cygwin,
  msys/mingw, dl-mingw, non-native). Drop redundant
  `CMAKE_RUNTIME_OUTPUT_DIRECTORY_*` settings too.
- GHA/windows: add timeout for package install steps where missing.
- GHA/non-native: specify target type explicitly for iOS cmake jobs.
  Xcode default was already Debug, single-target default was generic,
  now it's Release, with unity batch to keep it fast.

`MAKEFLAGS` is necessary for autotools jobs and CMake jobs using
the default (GNU Make) generator. It's ignored by Ninja and other tools.
`cmake --parallel` is still necessary for jobs with Visual Studio or
Xcode generators. Parallelism is 5 for GHA Linux and Windows runners,
4 for macOS, 3 for VMs, 2 for AppVeyor.

Closes #16502
2025-02-27 12:11:07 +01:00
Daniel Stenberg
bc24c60512
urlapi: fix redirect from file:// with query, and simplify
- fix redirect from file:// URL with query part
- find_host_sep() simplify
- urlencode_str() simplify
- redirect_url() simplify
- made more const char *
- add more redirect URL test cases to test 1560

Closes #16498
2025-02-27 11:51:19 +01:00
Viktor Szakats
c028a243f2
build: set -O3 and tune WinCE in CI, fix getpart, vtls_scache fallouts
- GHA/windows/WinCE:
  - set `-O3 -DNDEBUG` C flags manually for the CMake mingw32ce build.
    CMake doesn't recognize the platform and fails to add them. To match
    autotools (using `-O2`), and hit similar compiler warnings.
  - enable parallel builds for cmake.
  - tune parallelism for cmake using unity batches.
  - tune parallelism for autotools.

  Follow-up to 2a292c3984 #15975

- tests: fix potentially uninitialized value in `readline()` in
  `getpart.c`. Detected by gcc 4.4.0 `-O2` (Windows CE) jobs:
  ```
  tests/server/getpart.c: In function 'getpart':
  tests/server/getpart.c:298: error: 'datalen' may be used uninitialized in this function
  ```
  Ref: https://github.com/curl/curl/actions/runs/13522595237/job/37785147505?pr=16476#step:11:25
  Follow-up to 592880a3ca

- vtls_scache: rework returning pointer to avoid compiler warning seen
  with `-O3` gcc 4.4.0 builds (Windows CE/schannel):
  ```
  lib/vtls/schannel.c: In function 'schannel_connect_step1':
  lib/vtls/vtls_scache.c:975: error: dereferencing pointer 'old_cred.4474' does break strict-aliasing rules
  lib/vtls/vtls_scache.c:985: error: dereferencing pointer 'old_cred.4474' does break strict-aliasing rules
  lib/vtls/schannel.c:959: note: initialized from here
  ```
  Ref: https://github.com/curl/curl/actions/runs/13523868335/job/37789610845#step:9:25
  Follow-up to fa0ccd9f1f #15774

Closes #16476
2025-02-26 21:23:11 +01:00
Viktor Szakats
4f98f354b1
GHA/windows: move UWP vcpkg job up top
To bring it closer to WinCE and make the vcpkg jobs with tests form
a continuous group.

Closes #16499
2025-02-26 16:21:01 +01:00
Stefan Eissing
4ed9db9eef
vtls: move common early data code into vtls.c
With now 2 backends implementing early data, it makes sense to have the
common handling in a single place.

Closes #16450
2025-02-26 16:00:37 +01:00
Viktor Szakats
a1d00da81e
test1167: catch #defines with extra whitespace
Before this patch, it missed this in `curl/curl.h`:
```c
#  define __has_declspec_attribute(x) 0
```
After this patch:
```
test 1167...[Verify curl prefix of public symbols in header files]
/usr/bin/perl -I. -I.  returned 1, when expecting 0
 1167: exit FAILED
== Contents of files in the log/14/ dir after test 1167
=== Start of file server.cmd
 Testnum 1167
=== End of file server.cmd
=== Start of file stdout1167
 Bad symbols in public header files:
   __has_declspec_attribute(x)
=== End of file stdout1167
FAIL 1167: 'Verify curl prefix of public symbols in header files' source analysis
TESTFAIL: These test cases failed: 1167
```

Ref: #16491
Closes #16496
2025-02-26 14:01:40 +01:00
Daniel Stenberg
f5527e57f8
tests: make sure gdb gets the right path for -x
Regression from #16452

Closes #16495
2025-02-26 13:12:04 +01:00
Viktor Szakats
dbbbf717f3
curl.h: stop defining non-curl __has_declspec_attribute
Public curl headers are best not to define 3rd-party or system macros.
Introduce `CURL_HAS_DECLSPEC_ATTRIBUTE` to cover this system macro and
use it.

Detected by test1167 after dropping the indentation:
```
test 1167...[Verify curl prefix of public symbols in header files]

/usr/bin/perl -I. -I.  returned 1, when expecting 0
 1167: exit FAILED
== Contents of files in the log/10/ dir after test 1167
=== Start of file server.cmd
 Testnum 1167
=== End of file server.cmd
=== Start of file stdout1167
 Bad symbols in public header files:
   __has_declspec_attribute(x)
=== End of file stdout1167
```
Ref: https://github.com/curl/curl/actions/runs/13533200900/job/37819784405?pr=16490#step:42:2087

Ref: https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute
Follow-up to 50482b8c0a #3616
Ref: #16496 (fixing test1167)
Closes #16491
2025-02-26 13:10:31 +01:00
Viktor Szakats
3efc53f5e9
build: silence mingw32ce C99 format warnings, simplify CI
`./configure` mingw32ce builds enable C99 mode automatically, that
triggers compiler warnings in gcc 4.4.0. We initially worked it around
in CI by suppressing the detection of C99 with `ac_cv_prog_cc_c99=no`.

Replace it with automatically silencing the bogus warnings in C99 mode,
for all build systems:
```
lib/ftp.c: In function 'Curl_GetFTPResponse':
lib/ftp.c:726: error: format '%zd' expects type 'signed size_t', but argument 4 has type 'ssize_t'
lib/ws.c: In function 'ws_dec_pass_payload':
lib/ws.c:304: error: format '%zd' expects type 'signed size_t', but argument 3 has type 'ssize_t'
lib/ws.c: In function 'ws_enc_write_head':
lib/ws.c:581: error: format '%zd' expects type 'signed size_t', but argument 3 has type 'long int'
lib/vtls/schannel.c: In function 'schannel_connect_step1':
lib/vtls/schannel.c:1122: error: format '%zd' expects type 'signed size_t', but argument 3 has type 'ssize_t'
lib/vtls/schannel.c: In function 'schannel_connect_step2':
lib/vtls/schannel.c:1311: error: format '%zd' expects type 'signed size_t', but argument 3 has type 'ssize_t'
lib/vtls/schannel.c: In function 'schannel_send':
lib/vtls/schannel.c:1793: error: format '%zd' expects type 'signed size_t', but argument 3 has type 'ssize_t'
lib/vtls/schannel.c:1810: error: format '%zd' expects type 'signed size_t', but argument 3 has type 'ssize_t'
lib/vtls/schannel.c: In function 'schannel_shutdown':
lib/vtls/schannel.c:2286: error: format '%zd' expects type 'signed size_t', but argument 4 has type 'ssize_t'
lib/vtls/vtls.c: In function 'ssl_cf_recv':
lib/vtls/vtls.c:1422: error: format '%zd' expects type 'signed size_t', but argument 5 has type 'ssize_t'
```
Ref: https://github.com/curl/curl/actions/runs/13533841306/job/37821720902?pr=16492#step:9:20

Also: simplify Windows CE job configuration in GHA/windows.

Follow-up to 2a292c3984 #15975
Closes #16492
2025-02-26 12:35:03 +01:00
Viktor Szakats
518543dec8
cmake: warn for OpenSSL versions missing TLS 1.3 support (revert)
We decided not to show warnings for this issue.

Also this:
```
CMake Warning at CMakeLists.txt:783 (message):
  OpenSSL does not support TLS 1.3.
```
as seen in #16483 with CMake 3.12.4, `OPENSSL_VERSION` is empty.
Perhaps detection isn't reliable? I haven't seen this so far with
mainline OpenSSL. An `if(OPENSSL_VERSION AND ...)` can fix it, if we
opt for this warning in the future.

Follow-up to #16122
This reverts commit 34c1c653fc #16120
Closes #16485
2025-02-26 12:35:03 +01:00
Viktor Szakats
bc42010f66
GHA/http3-linux: build out-of-tree, make test2502 support it
To sync with the rest of core workflows.

Also fixup test2502 failing for out-of-tree builds due to:
```
== Info: error reading ca cert file ./certs/EdelCurlRoot-ca.cacert (Error while reading file.)
```
Ref: https://github.com/curl/curl/actions/runs/13525575035/job/37795171282?pr=16480#step:23:3608

Cherry-picked from #16480
Closes #16481
2025-02-26 12:35:03 +01:00
Viktor Szakats
37523c91bc
GHA/linux: build out-of-tree, make autotools tidy target support it
To sync with the rest of core workflows.

Also fix the `tidy` (clang-tidy) target in autotools to support
out-of-tree builds:
```
clang-tidy slist_wc.c terminal.c tool_bname.c [...] var.c tool_hugehelp.c tool_ca_embed.c
  -quiet --warnings-as-errors=* -checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-clang-analyzer-valist.Uninitialized --
  -I../../include -I../lib -I../src -I../../lib -I../../src
  -DBUILDING_CURL -DUSE_MANUAL -D_GNU_SOURCE -DHAVE_CONFIG_H
[1/45] Processing file /home/runner/work/curl/curl/bld/src/slist_wc.c.
Error while processing /home/runner/work/curl/curl/bld/src/slist_wc.c.
[2/45] Processing file /home/runner/work/curl/curl/bld/src/terminal.c.
Error while processing /home/runner/work/curl/curl/bld/src/terminal.c.
[3/45] Processing file /home/runner/work/curl/curl/bld/src/tool_bname.c.
Error while processing /home/runner/work/curl/curl/bld/src/tool_bname.c.
[...]
```
Ref: https://github.com/curl/curl/actions/runs/13525337357/job/37794388404?pr=16480#step:36:561

Closes #16480
2025-02-26 12:35:03 +01:00
Daniel Stenberg
200993fccd
RELEASE-NOTES: synced 2025-02-26 10:31:16 +01:00
Jay Satiro
2fce176bf6 wolfssl: warn if CA native import option is ignored
- Show verbose message if the CA native import option is set but
  the wolfSSL build does not support it.

wolfSSL has to be built with WOLFSSL_SYS_CA_CERTS to import native
CA certificates and that may not be common.

Closes https://github.com/curl/curl/pull/16417
2025-02-26 03:05:36 -05:00
Daniel Stenberg
d485177151
altsvc: rewrite parser using strparse
Extend test 1654.

Closes #16454
2025-02-26 08:36:08 +01:00
Daniel Stenberg
5b5e2f7318
cookie: do prefix matching case-sensitively
According to section 4.1.3.1 and 4.1.3.2 of
draft-ietf-httpbis-rfc6265bis-19

Ref: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-19#section-4.1.3.1

Closes #16494
2025-02-26 08:33:49 +01:00
Daniel Stenberg
ac4a65f8d2
urldata: move the ech struct field to the "right place"
We keep the struct field ordered in a rough size order, big to small.

Closes #16489
2025-02-26 08:18:35 +01:00
Daniel Stenberg
71f190cbbc
GHA: enable the RTSP tests on macOS gcc-12 2025-02-26 07:58:54 +01:00
Daniel Stenberg
2ec00372a1
curl.h: change some enums to defines with L suffix
To help applications do the right thing easier, change some enum values
into defines with L suffixes so that they get the corect type (long)
easier when used with curl_easy_setopt(). This also fixes a few of our
own libtests.

To reduce the risk that this change breaks the compile for any existing
users, the previously provided enums are still provided, but the values
to use are not defined by the enums.

This change "magically" fixes a few RTSP test failures we have had on
64-bit platforms because those options were not see using longs
properly.

Closes #16482
2025-02-26 07:58:15 +01:00
Daniel Stenberg
7826927d9b
libtest/libprereq.c: set CURLOPT_FOLLOWLOCATION with a long
Previously this used '1', which as an int. The option needs a long.

Closes #16487
2025-02-26 00:06:24 +01:00
Daniel Stenberg
6c81f2a35c
CURLOPT_HTTPHEADER.md: add comments to the example
Ref: https://mastodon.social/@jpmens/114065709635360064
Closes #16488
2025-02-25 23:56:05 +01:00
Viktor Szakats
baa9c647d3
cmake: sync cutoff version with autotools for picky option -ftree-vrp
Sync cutoff version for `-ftree-vrp` with autotools, which enables it
for gcc 4.3+ (cmake builds enabled it for 5.0+, before this patch).

Cherry-picked from #16476
Closes #16478
2025-02-25 16:57:45 +01:00
Viktor Szakats
29978df61f
cmake: pre-fill known type sizes for Windows OSes
To save configuration time.

After this patch, for mingw-w64 and MSVC curl's CMake builds pre-fill
almost all type sizes without auto-detection. In most cases this leaves
3 type size auto-detections. Those depend on 64/32-bitness, and `time_t`
also depends on CRT and custom options. Old mingw-w64 versions require
some extra detections. We recommend v3.0 or newer to avoid them.

For Windows CE, this patch pre-fills all type sizes.

If this is causing any issue, please report it and disable pre-filling
with `-D_CURL_PREFILL=OFF` in the meantime.

Cherry-picked from #16394
Closes #16464
2025-02-25 16:57:13 +01:00
Derek Huang
af0100fc17
INSTALL-CMAKE.md: CMake usage updates
This PR updates the CMake build/install docs in `docs/INSTALL-CMAKE.md`,
in particular focusing on the use of libcurl from CMake using
`find_package` as well as the newly added features/protocols support via
using `COMPONENTS` or `OPTIONAL_COMPONENTS` with `find_package`.
See #15854 for initial discussion and the corresponding PR #15858 that
was merged.

Some additional best-practices notes are added, for example:

* Encouraging building out-of-source
* Using `--config` with `cmake --build` for multi-config CMake
  generators, not `CMAKE_BUILD_TYPE`

We also add a CURL CMake-specific tip on using `CMAKE_INSTALL_PREFIX`
during configure time to set the install prefix, not using `--prefix`
when running `cmake --install` so `curl-config` output is consistent.

Closes #16329
2025-02-25 13:02:51 +01:00
Viktor Szakats
84332d49fb
runtests: drop recognizing 'winssl' as Schannel
Follow-up to 180501cb02 #3504
Closes #16467
2025-02-25 12:59:10 +01:00
Viktor Szakats
31fd77fb3b
runtests: recognize AWS-LC as OpenSSL
Fixes (GHA/linux, AWS-LC jobs):
```
test 0307 SKIPPED: curl lacks OpenSSL support
test 0308 SKIPPED: curl lacks OpenSSL support
[...]
```
Ref: https://github.com/curl/curl/actions/runs/13511134270/job/37751473424#step:42:104

Follow-up to 34ef4fab22 #10320
Closes #16466
2025-02-25 12:59:09 +01:00
Daniel Stenberg
6306476fc3
tool_getparam: make --url support a file with URLs
It implies -O used for each URL.

Mention in the --url documentation.

Test 488 and 489 verify.

Closes #16099
2025-02-25 09:16:54 +01:00
Tianyi Song
5addb3e1cc
openssl: check return value of X509_get0_pubkey
Fixes #16468
Closes #16469
2025-02-25 08:10:18 +01:00
Yedaya Katsman
a55b5b7c62
rustls: add support for CERTINFO
This allows you to use the `certs` and `num_certs` writeout variables in
the curl tool, and getting information about the server certificates
using CURLINFO_CERTINFO.

Closes #16459
2025-02-25 07:59:39 +01:00
Viktor Szakats
3175984ab2
build: drop unused getpart tool
Drop the `getpart` test tool from standard builds. This tool was not
used by tests.

Also:
- make it easier to build it standalone for testing `getpart.c` on
  the command-line.
- reduce local var scopes in source.

Closes #16460
2025-02-25 01:52:13 +01:00
Daniel Stenberg
b930142d12
CURLOPT_HTTPHEADER.md: rephrases
An attempt to use better language

Closes #16461
2025-02-24 23:15:26 +01:00
Daniel Stenberg
413b2a44a8
curl_trc: fix build with CURL_DISABLE_VERBOSE_STRINGS
Fixes #16462
Closes #16463
2025-02-24 23:14:54 +01:00
Viktor Szakats
a7bcf25c83
runtests: drop ref to unused external function [ci skip]
Follow-up to 3585796049 #16452
2025-02-24 23:07:51 +01:00
Viktor Szakats
01c25e3b00
CI: misc improvements, restore VS2008 job
- appveyor: restore VS2008 job, after fixing its issues.
  Enable OpenSSL in it. It takes 1 minute.
  Follow-up to 9b0467b169 #16453
  Follow-up to edfa537100 #16456
- appveyor: make a copy of OpenSSL DLLs to have them picked up as an
  artifact (disabled by default) to aid local tests.
- appveyor: dump CMake configuration logs on failure.
- appveyor: tidy up job parameter defaults.
- GHA/windows: add pre-fill check option for dl-mingw jobs.
- GHA/windows: fix pre-fill check option for MSYS jobs by installing
  `diffutils`.
  Follow-up to e7adf3e837 #15841
- GHA/windows: de-duplicate to `PATH` commands for Cygwin.
- GHA/windows: drop `$SYSTEMROOT/System32` from `PATH` for Cygwin
  configure. It's not needed.
  Follow-up to 36fd2dd6ee #13599
- list `.pdb` files in curl version step for MSVC.
  Ref: #16439

Cherry-picked from #16394
Closes #16458
2025-02-24 22:47:37 +01:00
Laurențiu Nicola
46f17ef010
docs: bump rustls to 0.14.1
Closes #16446
2025-02-24 22:41:30 +01:00
Viktor Szakats
5070b6ac45
INSTALL-CMAKE.md: mention ZLIB_USE_STATIC_LIBS
Cherry-picked from #16394
Closes #16457
2025-02-24 21:00:31 +01:00
Viktor Szakats
edfa537100
cmake: restrict static CRT builds to static curl exe, test in CI
Static CRT crashes MSVCR* MSVC builds (in VS2008, VS2010, VS2012,
VS2013) according to CI and local tests. The reproducible crash happens
in `curl_mfprintf() -> fputc(s, stderr)` when trying to display the
warning message in `curl -V`. `stderr` is non-NULL and resolves to `2`.
This reproducer needs a debug-enabled build, but it's unrelated to debug
features or curl's memory tracker. It happens regardless of unity build,
CPU architecture or `DllMain()` use. Example from VS2013:

```
+ _bld/src/Debug/curl.exe --disable --version
./appveyor.sh: line 124:   203 Segmentation fault      "${curl}" --disable --version
```
Ref: https://ci.appveyor.com/project/curlorg/curl/builds/51570451/job/ojpdqrsm1hmpmq6a#L210

Another crash happened in an UCRT build (VS2017) with a couple of
`printf()`s added to curl's `main()` function:

```
Microsoft Visual C++ Runtime Library
Debug Assertion Failed!
Program: C:/projects/curl/bld/src/Debug/curl.exe
File: minkernel/crts/ucrt/src/appcrt/heap/debug_heap.cpp
Line: 996
Expression: _act_first_block == header
```
(it hangs the job in CI due to the GUI popup)
Ref: https://github.com/curl/curl/pull/16394#issuecomment-2677181716

To avoid actual and potential issues, this patch issues a warning on
the shared-libcurl + static-CRT combination and falls back to the
default, shared CRT. IOW a static CRT build now requires a static curl
exe when using the `CURL_STATIC_CRT=ON` option.

Follow-up to 4fc6ebe18a #1621
Cherry-picked from #16394 (with more details there)

Closes #16456
2025-02-24 21:00:31 +01:00
Viktor Szakats
7b8b9b9c2b
cmake: hide empty MINGW64_VERSION output for mingw32ce
Follow-up to e49797abc2 #16022
Follow-up to 2a292c3984 #15975
Cherry-picked from #16394

Closes #16455
2025-02-24 21:00:31 +01:00
Viktor Szakats
9b0467b169
windows: drop code and curl manifest targeting W2K and older
curl requires Windows XP since 2023. Drop version detection code using
`GetVersionEx()` aimed to support earlier Windows versions. With that
call deleted, the embedded manifest in `curl.rc` becomes unnecessary.
Delete it too, along with the enabler logic in build systems.

This allows to stop forcing `/MANIFEST:NO` for MSVC builds. Dropping it
fixes VS2008 shared builds, that require an auto-generated SxS
(side-by-side assembly) manifest to find their CRT DLLs. This was the
issue that prevented VS2008 `curl.exe` launching on AppVeyor CI:
```
src/curl.exe: error while loading shared libraries: ?: cannot open shared object file: No such file or directory
```
Ref: https://ci.appveyor.com/project/curlorg/curl/builds/51577006/job/eitypvwlb1rxr11d#L261

FWIW the `curl.rc` embedded manifest wasn't ever enabled for VS2008 CI
builds either, because CMake did not pass our custom macro via
`CMAKE_RC_FLAGS` to `rc.exe`. For reasons I could not figure out.

After this patch the curl build no longer inject its own manifest, and
lets the default be applied by linkers and toolchains. It fixes VS2008
shared builds. curl continues to detect the real Windows version via
`RtlVerifyVersionInfo()` from `ntdll`.

Follow-up to 960d601481 #12225
Follow-up to 5044909ca2 #7810
Follow-up to ebd213270a #1221
Ref: #15972
Cherry-picked from #16394

Closes #16453
2025-02-24 21:00:31 +01:00
Viktor Szakats
3585796049
runtests: support multi-target cmake, drop workarounds from CI
Support multi-target cmake builds via `CURL_DIRSUFFIX` env. For example:
`export CURL_DIRSUFFIX=Debug/`.

Multi-target generators place their output to `src/<subdir>/`,
`lib/<subdir>/`, `tests/server/<subdir>`, `tests/libtest/<subdir>` and
`tests/unit/<subdir>/` by default. Before this patch, `runtests.pl`
couldn't run on such builds because it expected the binaries under the
their `<subdir>`-less directories. This patch allows to set such subdir
and make `runtests.pl` find the binaries. In CI we use multi-target
builds with tests for MSVC. It also helps Xcode-generator builds, though
in CI we don't have such job running tests.

There may be better solutions to configure this, but passing a custom
value to `runtests.pl` including its subprocesses is somewhat tricky.
The reason the configuration value expects the slash at the end is
because MSYS is automagically expanding the env to a (wrong) absolute
path if the slash is in the front.

Also:
- drop the `-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_*=` workaround from CI.
- replace `resolve` references in tests with a new `%RESOLVE` variable.
  It didn't use a filename extension before. After this patch it uses
  `exe_ext('TOOL')`. I'm not sure if this is the correct choice vs.
  `exe_ext('SRV')`.
- fix `-c` option format in manual.
- fix some whitespace.

Note, in CI we still tweak `CMAKE_RUNTIME_OUTPUT_DIRECTORY_*` in jobs
which share steps between `./configure` and cmake. It's easier that way.

Ref: #15000
Cherry-picked from #16394

Closes #16452
2025-02-24 21:00:30 +01:00
Daniel Stenberg
db2fd7c3de
delta: get contributors without changing THANKS
Give contrithanks.sh the option to send the list of names to stdout so
that delta can use it appropriately for counting.

Closes #16449
2025-02-24 13:26:48 +01:00
Laurențiu Nicola
dfdd380844
ci: use stable rust toolchain for rustls and skip installing the docs
Closes #16447
2025-02-24 13:08:27 +01:00
Daniel Stenberg
8f79b3e696
contrithanks.sh: update docs/THANKS in place
Now using 'sort' for sorting the names. This has the small side-effect
that it sorts slightly different than the previously used sort function
(emacs).

I think this is a better sort and over all it makes it more convenient
to use the script as it removes a manual step.

Closes #16448
2025-02-24 13:04:11 +01:00
Daniel Stenberg
7694fc8256
RELEASE-NOTES: synced 2025-02-24 10:13:06 +01:00
Daniel Stenberg
04289c62de
http: convert parsers to strparse
Closes #16436
2025-02-24 10:02:40 +01:00
Stefan Eissing
edd573d980
wolfssl: tls early data support
Enable TLS Early Data for wolfSSL:

- merge WOLFSSL_CTX and WOLFSSL setup from ngtcp2 with the general
  implemenation in wolfssl.c
- enable for QUIC via ngtcp2
- give Curl_vquic_tls_init() a `struct alpn_spec` like used for the TCP
  case. Adapt gnutls and other users.
- enable pytest test cases for early data with wolfSSL

and while this messes up wolfssl.c anyway, do

- rename all struct/functions with prefix 'wolfssl_' to 'wssl_' to not
  pollute that name prefix
- rename `ctx/handle` to `ssl_ctx/ssl`, as used in openssl case

Closes #16167
2025-02-24 10:01:51 +01:00
Daniel Stenberg
efec626ebb
contributors.sh: lowercase 'github' for consistency
also fix contrithanks and THANKS-filter

Ref: #16438
Closes #16443
2025-02-24 08:05:06 +01:00
Timo Tijhof
9391fc151f
RELEASE-NOTES: fix github casing
Follows-up b22f9066a5, which added a new contributor with a different
casing for "github" than the others.

Closes #16438
2025-02-24 00:10:18 +01:00
Stefan Eissing
51f8aa79a9
CURLMOPT_SOCKETFUNCTION.md: add advice for socket callback invocation times
Explain when a registered socket callback may get invoked to make user
better aware on how to handle it.

Closes #16441
2025-02-24 00:05:56 +01:00
Daniel Stenberg
e1b3d46944
tool_operate: fail SSH transfers without server auth
This now insists on using a server auth option unless --insecure is
provided. As an added bonus, it now also only checks for the knownhosts
file once (if found).

Ref: #16197
Closes #16205
2025-02-23 17:54:21 +01:00
166 changed files with 3270 additions and 2564 deletions

View File

@ -3,55 +3,117 @@
# #
# SPDX-License-Identifier: curl # SPDX-License-Identifier: curl
# #
# Input: a cmdline docs markdown, it gets modified *in place* # 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.
# #
# 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.
my $header = 1; open(S, "<./docs/libcurl/symbols-in-versions")
while(1) { || die "can't find symbols-in-versions";
# set this if the markdown has no meta-data header to skip while(<S>) {
if($ARGV[0] eq "--no-header") { if(/^([^ ]*) /) {
shift @ARGV; push @asyms, $1;
$header = 0;
}
else {
last;
} }
} }
close(S);
my $f = $ARGV[0]; # init the opts table with "special" options not easy to figure out
my @aopts = (
'--ftp-ssl-reqd', # old alias
);
open(F, "<$f") or die; open(O, "<./docs/options-in-versions")
|| die "can't find options-in-versions";
my $ignore = $header; while(<O>) {
my $sepcount = 0; chomp;
my @out; if(/^([^ ]+)/) {
while(<F>) { my $o = $1;
if(/^---/ && $header) { push @aopts, $o;
if(++$sepcount == 2) { if($o =~ /^--no-(.*)/) {
$ignore = 0; # for the --no options, also make one without it
push @aopts, "--$1";
} }
elsif($o =~ /^--disable-(.*)/) {
# for the --disable options, also make the special ones
push @aopts, "--$1";
push @aopts, "--no-$1";
}
}
}
close(O);
open(C, "<./.github/scripts/spellcheck.curl")
|| die "can't find spellcheck.curl";
while(<C>) {
if(/^\#/) {
next; next;
} }
next if($ignore); chomp;
if(/^([^ ]+)/) {
# strip out backticked words push @asyms, $1;
$_ =~ 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(F); close(C);
if(!$ignore) { # longest symbols first
open(O, ">$f") or die; my @syms = sort { length($b) <=> length($a) } @asyms;
print O @out;
close(O); # 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);
} }

View File

@ -1,86 +0,0 @@
#!/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 Normal file
View File

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

View File

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

View File

@ -107,20 +107,8 @@ jobs:
persist-credentials: false persist-credentials: false
name: checkout name: checkout
- name: trim all man page *.md files - name: trim all *.md files in docs/
run: find docs -name "*.md" ! -name "_*" -print0 | xargs -0 -n1 .github/scripts/cleancmd.pl run: .github/scripts/cleancmd.pl $(find docs -name "*.md")
- 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 - name: setup the custom wordlist
run: grep -v '^#' .github/scripts/spellcheck.words > wordlist.txt run: grep -v '^#' .github/scripts/spellcheck.words > wordlist.txt

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -44,10 +44,6 @@ if(MINGW)
set(HAVE_UTIME_H 1) # wrapper to sys/utime.h set(HAVE_UTIME_H 1) # wrapper to sys/utime.h
set(HAVE_DIRENT_H 1) set(HAVE_DIRENT_H 1)
set(HAVE_OPENDIR 1) set(HAVE_OPENDIR 1)
if(MINGW32CE)
set(HAVE_STRTOK_R 0)
set(HAVE_FILE_OFFSET_BITS 0)
endif()
else() else()
set(HAVE_LIBGEN_H 0) set(HAVE_LIBGEN_H 0)
set(HAVE_FTRUNCATE 0) set(HAVE_FTRUNCATE 0)
@ -78,7 +74,6 @@ else()
set(HAVE_SNPRINTF 0) set(HAVE_SNPRINTF 0)
endif() endif()
set(HAVE_BASENAME 0) set(HAVE_BASENAME 0)
set(HAVE_FILE_OFFSET_BITS 0)
endif() endif()
endif() endif()
@ -196,6 +191,37 @@ set(STDC_HEADERS 1)
set(HAVE_SIZEOF_SUSECONDS_T 0) set(HAVE_SIZEOF_SUSECONDS_T 0)
set(HAVE_SIZEOF_SA_FAMILY_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 if(WINCE) # Windows CE exceptions
set(HAVE_LOCALE_H 0) set(HAVE_LOCALE_H 0)
set(HAVE_GETADDRINFO 0) set(HAVE_GETADDRINFO 0)
@ -204,7 +230,15 @@ if(WINCE) # Windows CE exceptions
set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 0) set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 0)
set(HAVE_SIGNAL 0) set(HAVE_SIGNAL 0)
set(HAVE_SETMODE 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) if(MINGW32CE)
set(HAVE_STRTOK_R 0)
set(HAVE__SETMODE 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()
endif() endif()

View File

@ -217,13 +217,6 @@ option(ENABLE_ARES "Enable c-ares support" OFF)
option(CURL_DISABLE_INSTALL "Disable installation targets" OFF) option(CURL_DISABLE_INSTALL "Disable installation targets" OFF)
if(WIN32) 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) option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF)
if(WINDOWS_STORE OR WINCE) if(WINDOWS_STORE OR WINCE)
set(ENABLE_UNICODE ON) set(ENABLE_UNICODE ON)
@ -264,7 +257,9 @@ if(WIN32)
if(MINGW64_VERSION) if(MINGW64_VERSION)
string(REGEX MATCH "MINGW64_VERSION=[0-9]+\.[0-9]+" CURL_TEST_OUTPUT "${CURL_TEST_OUTPUT}") 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}") string(REGEX REPLACE "MINGW64_VERSION=" "" MINGW64_VERSION "${CURL_TEST_OUTPUT}")
message(STATUS "Found MINGW64_VERSION=${MINGW64_VERSION}") if(MINGW64_VERSION)
message(STATUS "Found MINGW64_VERSION=${MINGW64_VERSION}")
endif()
endif() endif()
unset(MINGW64_VERSION CACHE) # Avoid storing in CMake cache unset(MINGW64_VERSION CACHE) # Avoid storing in CMake cache
endif() endif()
@ -354,6 +349,19 @@ else()
set(LIB_SELECTED ${LIB_STATIC}) set(LIB_SELECTED ${LIB_STATIC})
endif() 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. # 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 if((UNIX AND NOT ANDROID AND (NOT APPLE OR CMAKE_SYSTEM_NAME MATCHES "Darwin")) OR
VCPKG_TOOLCHAIN OR VCPKG_TOOLCHAIN OR
@ -819,9 +827,6 @@ if(CURL_USE_OPENSSL)
set(_openssl "AmiSSL") set(_openssl "AmiSSL")
else() else()
set(_openssl "OpenSSL") 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()
endif() endif()
@ -1948,22 +1953,6 @@ endif()
# Some other minor tests # 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) if(_cmake_try_compile_target_type_save)
set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_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) unset(_cmake_try_compile_target_type_save)
@ -1983,9 +1972,6 @@ if(WIN32)
set(USE_WIN32_LARGE_FILES ON) set(USE_WIN32_LARGE_FILES ON)
endif() 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 # We use crypto functions that are not available for UWP apps
if(NOT WINDOWS_STORE) if(NOT WINDOWS_STORE)
set(USE_WIN32_CRYPTO ON) set(USE_WIN32_CRYPTO ON)
@ -2001,9 +1987,6 @@ if(WIN32)
endif() endif()
if(MSVC) if(MSVC)
# Disable default manifest added by CMake
string(APPEND CMAKE_EXE_LINKER_FLAGS " -MANIFEST:NO")
string(APPEND CMAKE_C_FLAGS " -MP") # Parallel compilation string(APPEND CMAKE_C_FLAGS " -MP") # Parallel compilation
endif() endif()

View File

@ -4,10 +4,15 @@ curl and libcurl 8.13.0
Command line options: 267 Command line options: 267
curl_easy_setopt() options: 306 curl_easy_setopt() options: 306
Public functions in libcurl: 96 Public functions in libcurl: 96
Contributors: 3349 Contributors: 3354
This release includes the following changes: 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: This release includes the following bugfixes:
@ -16,67 +21,111 @@ This release includes the following bugfixes:
o asyn-thread: avoid the separate curl_mutex_t alloc [6] o asyn-thread: avoid the separate curl_mutex_t alloc [6]
o asyn-thread: do not allocate thread_data separately [21] o asyn-thread: do not allocate thread_data separately [21]
o asyn-thread: remove 'status' from struct Curl_async [36] 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: enable -Wjump-misses-init for GCC 4.5+ [62]
o build: fix compiler warnings in feature detections [39] o build: fix compiler warnings in feature detections [39]
o build: set `HAVE_WRITABLE_ARGV` for Apple cross-builds [8] 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 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 ca-native.md: sync with CURLSSLOPT_NATIVE_CA [72]
o cf-socket: deduplicate Windows Vista detection [11] o cf-socket: deduplicate Windows Vista detection [11]
o client writer: handle pause before deocding [61] o client writer: handle pause before deocding [61]
o cmake: `SHARE_LIB_OBJECT=ON` requires CMake 3.12 or newer [46] 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: add pre-fill for Unix, enable in GHA/macos, verify pre-fills [42]
o cmake: allow empty custom `IMPORT_LIB_SUFFIX`, add suffix collision detection [41] 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: drop `HAVE_IN_ADDR_T` from pre-fill too o cmake: drop `HAVE_IN_ADDR_T` from pre-fill too
o cmake: drop two stray TLS feature checks for wolfSSL [9] 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 `HAVE_ATOMIC`/`HAVE_STDATOMIC` pre-fill for clang-cl [28]
o cmake: fix ECH detection in custom-patched OpenSSL [32] 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: mention 'insecure' in the debug build warning [15]
o cmake: misc tidy-ups [38] 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 cmake: sync OpenSSL(-fork) feature checks with `./configure` [49]
o CODE_STYLE: readability and banned functions [35] 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 configure: use `curl_cv_apple` variable [40]
o conn: fix connection reuse when SSL is optional [54] 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: minor parser simplification [58]
o cookie: simplify invalid_octets() [24] 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_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: 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 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 hash: use single linked list for entries [57]
o hostip: make CURLOPT_RESOLVE support replacing IPv6 addresses [47] o hostip: make CURLOPT_RESOLVE support replacing IPv6 addresses [47]
o HTTP3.md: only speak about minimal versions [18] 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 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: negotiation and room for alt-svc/https rr to navigate [64]
o http: version negotiation [45] o http: version negotiation [45]
o http_aws_sigv4: use strparse more for parsing [55] o http_aws_sigv4: use strparse more for parsing [55]
o https-rr: implementation improvements [44] o https-rr: implementation improvements [44]
o httpsrr: fix port detection [51] o httpsrr: fix port detection [51]
o httpsrr: fix the HTTPS-RR threaded-resolver build combo [67] 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: better optimized casecompare() and ncasecompare() [3]
o lib: simplify more white space loops [60] o lib: simplify more white space loops [60]
o lib: strtoofft.h header cleanup [17] o lib: strtoofft.h header cleanup [17]
o lib: use Curl_str_* instead of strtok_r() [59] o lib: use Curl_str_* instead of strtok_r() [59]
o lib: use Curl_str_number() for parsing decimal numbers [13] 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 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 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: 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 option 'single' [31]
o scripts/managen: fix parsing of markdown code sections [30] 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 ssh: consider sftp quote commands case sensitive [33]
o ssl session cache: add exportable flag [56] o ssl session cache: add exportable flag [56]
o strparse: make Curl_str_number() return error for no digits [14] 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 the API to work on 'const char *' [2]
o strparse: switch to curl_off_t as base data type [7] o strparse: switch to curl_off_t as base data type [7]
o tests: fix enum/int confusion (Intel C), fix autotools `CFLAGS` for `servers` [27] 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 tidy-up: delete, comment or scope C macros reported unused [16] 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: drop unused `CURL_INADDR_NONE` macro and `in_addr_t` type [26]
o tidy-up: use `CURL_ARRAYSIZE()` [37] o tidy-up: use `CURL_ARRAYSIZE()` [37]
o timediff: fix comment for curlx_mstotv() [25] o timediff: fix comment for curlx_mstotv() [25]
o timediff: remove unnecessary double typecast [53] o timediff: remove unnecessary double typecast [53]
o tool_getparam: clear sensitive arguments better [66] o tool_getparam: clear sensitive arguments better [66]
o tool_operate: fail SSH transfers without server auth [70]
o urlapi: simplify junkscan [23] o urlapi: simplify junkscan [23]
o variable.md: clarify 'trim' example [12] 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 wolfssh: retrieve the error using wolfSSH_get_error [5]
o wolfssl: fix CA certificate multiple location import [34] 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] o wolfssl: when using PQ KEM, use ML-KEM, not Kyber [10]
This release includes the following known bugs: This release includes the following known bugs:
@ -98,12 +147,13 @@ Planned upcoming removals include:
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Anthony Hu, Daniel Stenberg, dependabot[bot], Dexter Gerig, Harry Sintonen, Anthony Hu, Dan Fandrich, Daniel Stenberg, dependabot[bot], Derek Huang,
John Bampton, Joseph Chen, kayrus on github, kriztalz, lf- on github, Dexter Gerig, Harry Sintonen, Jeremy Drake, John Bampton, Joseph Chen,
Marcel Raad, Mark Phillips, Ray Satiro, rmg-x on github, kayrus on github, kriztalz, Laurențiu Nicola, lf- on github, Marcel Raad,
RubisetCie on Github, Sergey, Stefan Eissing, Viktor Szakats, Mark Phillips, qhill on github, Ray Satiro, renovate[bot], rmg-x on github,
Zenju on github RubisetCie on github, Sergey, Stefan Eissing, Tianyi Song, Timo Tijhof,
(19 contributors) Viktor Szakats, Yedaya Katsman, Zenju on github
(28 contributors)
References to bug reports and discussions on issues: References to bug reports and discussions on issues:
@ -154,8 +204,11 @@ References to bug reports and discussions on issues:
[45] = https://curl.se/bug/?i=16100 [45] = https://curl.se/bug/?i=16100
[46] = https://curl.se/bug/?i=16375 [46] = https://curl.se/bug/?i=16375
[47] = https://curl.se/bug/?i=16357 [47] = https://curl.se/bug/?i=16357
[48] = https://curl.se/bug/?i=16436
[49] = https://curl.se/bug/?i=16352 [49] = https://curl.se/bug/?i=16352
[50] = https://curl.se/bug/?i=16167
[51] = https://curl.se/bug/?i=16409 [51] = https://curl.se/bug/?i=16409
[52] = https://curl.se/bug/?i=16443
[53] = https://curl.se/bug/?i=16367 [53] = https://curl.se/bug/?i=16367
[54] = https://curl.se/bug/?i=16384 [54] = https://curl.se/bug/?i=16384
[55] = https://curl.se/bug/?i=16366 [55] = https://curl.se/bug/?i=16366
@ -168,8 +221,53 @@ References to bug reports and discussions on issues:
[62] = https://curl.se/bug/?i=16252 [62] = https://curl.se/bug/?i=16252
[63] = https://curl.se/bug/?i=16356 [63] = https://curl.se/bug/?i=16356
[64] = https://curl.se/bug/?i=16117 [64] = https://curl.se/bug/?i=16117
[65] = https://curl.se/bug/?i=16417
[66] = https://curl.se/bug/?i=16396 [66] = https://curl.se/bug/?i=16396
[67] = https://curl.se/bug/?i=16399 [67] = https://curl.se/bug/?i=16399
[68] = https://curl.se/bug/?i=16398 [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 [71] = https://curl.se/bug/?i=16385
[72] = https://curl.se/bug/?i=16373 [72] = https://curl.se/bug/?i=16373
[73] = https://curl.se/bug/?i=16435
[74] = https://curl.se/bug/?i=16308
[76] = https://curl.se/bug/?i=16426
[77] = https://curl.se/bug/?i=16434
[78] = https://curl.se/bug/?i=16330
[79] = https://curl.se/bug/?i=15956
[80] = https://curl.se/bug/?i=16423
[81] = https://curl.se/bug/?i=16427
[82] = https://curl.se/bug/?i=16494
[84] = https://curl.se/bug/?i=16482
[85] = https://curl.se/bug/?i=16407
[86] = https://curl.se/bug/?i=16377
[87] = https://curl.se/bug/?i=15975
[88] = https://curl.se/bug/?i=16419
[89] = https://curl.se/bug/?i=16487
[90] = https://curl.se/bug/?i=16488
[91] = https://curl.se/bug/?i=16420
[92] = https://curl.se/bug/?i=16393
[93] = https://curl.se/bug/?i=16277
[94] = https://curl.se/bug/?i=16134
[95] = https://curl.se/bug/?i=16104
[96] = https://curl.se/bug/?i=16004
[97] = https://curl.se/bug/?i=16217
[98] = https://curl.se/bug/?i=16408
[99] = https://curl.se/bug/?i=16478
[100] = https://curl.se/bug/?i=16464
[101] = https://curl.se/bug/?i=16329
[102] = https://curl.se/bug/?i=16467
[103] = https://curl.se/bug/?i=16466
[104] = https://curl.se/bug/?i=16099
[105] = https://curl.se/bug/?i=16468
[106] = https://curl.se/bug/?i=16459
[107] = https://curl.se/bug/?i=16460
[108] = https://curl.se/bug/?i=16461
[109] = https://curl.se/bug/?i=16462
[111] = https://curl.se/bug/?i=16446
[112] = https://curl.se/bug/?i=16457
[113] = https://curl.se/bug/?i=16456
[114] = https://curl.se/bug/?i=16455
[115] = https://curl.se/bug/?i=16453
[116] = https://curl.se/bug/?i=16452
[119] = https://curl.se/bug/?i=16448

View File

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

View File

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

View File

@ -21,6 +21,12 @@ CMake's GUIs.
A CMake configuration of curl is similar to the autotools build of curl. 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. 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` ## Using `cmake`
You can configure for in source tree builds or for a build tree You can configure for in source tree builds or for a build tree
@ -31,10 +37,14 @@ that is apart from the source tree.
$ cmake -B . $ cmake -B .
- Build in a separate directory (parallel to the curl source tree in this - Build in a separate directory (parallel to the curl source tree in this
example). The build directory is created for you. example). The build directory is created for you. This is recommended over
building in the source tree to separate source and build artifacts.
$ cmake -B ../curl-build $ 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 ### Fallback for CMake before version 3.13
CMake before version 3.13 does not support the `-B` option. In that case, CMake before version 3.13 does not support the `-B` option. In that case,
@ -129,6 +139,12 @@ Install to default location (you have to specify the build directory).
$ cmake --install ../curl-build $ 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 ### Fallback for CMake before version 3.15
CMake before version 3.15 does not support the `--install` option. In that CMake before version 3.15 does not support the `--install` option. In that
@ -139,6 +155,68 @@ assumes that CMake generates `Makefile`:
$ cd ../curl-build $ cd ../curl-build
$ make install $ 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 # CMake build options
- `BUILD_CURL_EXE`: Build curl executable. Default: `ON` - `BUILD_CURL_EXE`: Build curl executable. Default: `ON`
@ -160,7 +238,7 @@ assumes that CMake generates `Makefile`:
- `CURL_LIBCURL_VERSIONED_SYMBOLS`: Enable libcurl versioned symbols. Default: `OFF` - `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_LIBCURL_VERSIONED_SYMBOLS_PREFIX`: Override default versioned symbol prefix. Default: `<TLS-BACKEND>_` or `MULTISSL_`
- `CURL_LTO`: Enable compiler Link Time Optimizations. Default: `OFF` - `CURL_LTO`: Enable compiler Link Time Optimizations. Default: `OFF`
- `CURL_STATIC_CRT`: Build libcurl with static CRT with MSVC (`/MT`). Default: `OFF` - `CURL_STATIC_CRT`: Build libcurl with static CRT with MSVC (`/MT`) (requires static or no curl executable). Default: `OFF`
- `CURL_TARGET_WINDOWS_VERSION`: Minimum target Windows version as hex string. - `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_TEST_BUNDLES`: Bundle `libtest` and `unittest` tests into single binaries. Default: `OFF`
- `CURL_WERROR`: Turn compiler warnings into errors. Default: `OFF` - `CURL_WERROR`: Turn compiler warnings into errors. Default: `OFF`
@ -306,6 +384,7 @@ Details via CMake
- `OPENSSL_USE_STATIC_LIBS`: Look for static OpenSSL libraries. - `OPENSSL_USE_STATIC_LIBS`: Look for static OpenSSL libraries.
- `ZLIB_INCLUDE_DIR`: The zlib include directory. - `ZLIB_INCLUDE_DIR`: The zlib include directory.
- `ZLIB_LIBRARY`: Path to `zlib` library. - `ZLIB_LIBRARY`: Path to `zlib` library.
- `ZLIB_USE_STATIC_LIBS`: Look for static ZLIB library (requires CMake v3.24).
## Dependency options ## Dependency options
@ -379,7 +458,7 @@ Details via CMake
# Migrating from Visual Studio IDE Project Files # Migrating from Visual Studio IDE Project Files
We recommend CMake to build curl with MSVC. We recommend using CMake to build curl with MSVC.
The project build files reside in project/Windows/VC\* for VS2010, VS2010 and The project build files reside in project/Windows/VC\* for VS2010, VS2010 and
VS2013 respectively. VS2013 respectively.
@ -399,8 +478,8 @@ Configuration element | Equivalent CMake options
`Win32` | `-A Win32` `Win32` | `-A Win32`
`DLL` | `BUILD_SHARED_LIBS=ON`, `BUILD_STATIC_LIBS=OFF`, (default) `DLL` | `BUILD_SHARED_LIBS=ON`, `BUILD_STATIC_LIBS=OFF`, (default)
`LIB` | `BUILD_SHARED_LIBS=OFF`, `BUILD_STATIC_LIBS=ON` `LIB` | `BUILD_SHARED_LIBS=OFF`, `BUILD_STATIC_LIBS=ON`
`Debug` | `CMAKE_BUILD_TYPE=Debug` `Debug` | `CMAKE_BUILD_TYPE=Debug` (`-G "NMake Makefiles"` only)
`Release` | `CMAKE_BUILD_TYPE=Release` `Release` | `CMAKE_BUILD_TYPE=Release` (`-G "NMake Makefiles"` only)
`DLL Windows SSPI` | `CURL_USE_SCHANNEL=ON` (with SSPI enabled by default) `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 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` `DLL libssh2` | `CURL_USE_LIBSSH2=ON`, optional: `LIBSSH2_INCLUDE_DIR`, `LIBSSH2_LIBRARY`
@ -414,7 +493,13 @@ For example these commands:
translate to: translate to:
> cmake . -G "Visual Studio 12 2013" -A x64 -DCMAKE_BUILD_TYPE=Debug -DCURL_USE_SCHANNEL=ON -DUSE_WIN32_IDN=ON -DCURL_USE_LIBPSL=OFF > 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`.
# Migrating from winbuild builds # Migrating from winbuild builds
@ -437,7 +522,7 @@ winbuild options | Equivalent CMake options
`DEBUG` | `CMAKE_BUILD_TYPE=Debug` `DEBUG` | `CMAKE_BUILD_TYPE=Debug`
`GEN_PDB` | `CMAKE_EXE_LINKER_FLAGS=/Fd<path>`, `CMAKE_SHARED_LINKER_FLAGS=/Fd<path>` `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` `LIB_NAME_DLL`, `LIB_NAME_STATIC` | `IMPORT_LIB_SUFFIX`, `LIBCURL_OUTPUT_NAME`, `STATIC_LIB_SUFFIX`
`VC` | see CMake `-G` [options](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) `VC`: `<N>` | see the CMake [Visual Studio generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators)
`MACHINE`: `x64`, `x86` | `-A x64`, `-A Win32` `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) `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` `RTLIBCFG`: `static` | `CURL_STATIC_CRT=ON`
@ -467,4 +552,8 @@ For example this command-line:
translates to: translates to:
> 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 > 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`.

View File

@ -9,7 +9,7 @@ SPDX-License-Identifier: curl
[Rustls is a TLS backend written in Rust](https://docs.rs/rustls/). curl can [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 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 the [rustls-ffi C bindings](https://github.com/rustls/rustls-ffi/). This
version of curl depends on version v0.14.0 of rustls-ffi. version of curl is compatible with `rustls-ffi` v0.14.x.
# Building with Rustls # 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: Next, check out, build, and install the appropriate version of rustls-ffi:
% git clone https://github.com/rustls/rustls-ffi -b v0.14.0 % git clone https://github.com/rustls/rustls-ffi -b v0.14.1
% cd rustls-ffi % cd rustls-ffi
% make % make
% make DESTDIR=${HOME}/rustls-ffi-built/ install % make DESTDIR=${HOME}/rustls-ffi-built/ install

View File

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

View File

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

View File

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

View File

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

View File

@ -62,7 +62,7 @@ The variables available are:
## `certs` ## `certs`
Output the certificate chain with details. Supported only by the OpenSSL, Output the certificate chain with details. Supported only by the OpenSSL,
GnuTLS, Schannel and Secure Transport backends. (Added in 7.88.0) GnuTLS, Schannel, Rustls, and Secure Transport backends. (Added in 7.88.0)
## `conn_id` ## `conn_id`
The connection identifier last used by the transfer. The connection id is 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` ## `num_certs`
Number of server certificates received in the TLS handshake. Supported only by Number of server certificates received in the TLS handshake. Supported only by
the OpenSSL, GnuTLS, Schannel and Secure Transport backends. the OpenSSL, GnuTLS, Schannel, Rustls and Secure Transport backends.
(Added in 7.88.0) (Added in 7.88.0)
## `num_connects` ## `num_connects`

View File

@ -24,53 +24,53 @@ displays information about the curl and libcurl installation.
# OPTIONS # OPTIONS
## --ca ## `--ca`
Displays the built-in path to the CA cert bundle this libcurl uses. Displays the built-in path to the CA cert bundle this libcurl uses.
## --cc ## `--cc`
Displays the compiler used to build libcurl. Displays the compiler used to build libcurl.
## --cflags ## `--cflags`
Set of compiler options (CFLAGS) to use when compiling files that use 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. 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 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 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 outputs a text saying that the current version is not new enough. (Added in
7.15.4) 7.15.4)
## --configure ## `--configure`
Displays the arguments given to configure when building curl. Displays the arguments given to configure when building curl.
## --feature ## `--feature`
Lists what particular main features the installed libcurl was built with. At 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 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 any particular order. The keywords are separated by newlines. There may be
none, one, or several keywords in the list. none, one, or several keywords in the list.
## --help ## `--help`
Displays the available options. Displays the available options.
## --libs ## `--libs`
Shows the complete set of libs and other linker options you need in order to Shows the complete set of libs and other linker options you need in order to
link your application with libcurl. link your application with libcurl.
## --prefix ## `--prefix`
This is the prefix used when libcurl was installed. libcurl is then installed 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 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 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, 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 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) 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 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. no, one or several names. If more than one name, they appear comma-separated.
(Added in 7.58.0) (Added in 7.58.0)
## --static-libs ## `--static-libs`
Shows the complete set of libs and other linker options you need in order to 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) link your application with libcurl statically. (Added in 7.17.1)
## --version ## `--version`
Outputs version information about the installed libcurl. Outputs version information about the installed libcurl.
## --vernum ## `--vernum`
Outputs version information about the installed libcurl, in numerical mode. Outputs version information about the installed libcurl, in numerical mode.
This shows the version number, in hexadecimal, using 8 bits for each part: This shows the version number, in hexadecimal, using 8 bits for each part:
@ -104,22 +104,21 @@ omitted. (This option was broken in the 7.15.0 release.)
# EXAMPLES # EXAMPLES
What linker options do I need when I link with libcurl? 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? 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? 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? What's the installed libcurl version?
~~~
$ curl-config --version $ curl-config --version
~~~
How do I build a single file with a one-line command? 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`
~~~

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,16 +23,16 @@ These variables are intended for internal use only, subject to change and have
many effects on the behavior of libcurl. Refer to the source code to determine many effects on the behavior of libcurl. Refer to the source code to determine
how exactly they are being used. how exactly they are being used.
## CURL_ALTSVC_HTTP ## `CURL_ALTSVC_HTTP`
Bypass the AltSvc HTTPS protocol restriction if this variable exists. 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. The percentage of recv() calls that should be answered with a EAGAIN at random.
For TCP/UNIX sockets. 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. The maximum data that shall be received from the network in one recv() call.
For TCP/UNIX sockets. This is applied to every recv. 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 Example: **CURL_DBG_SOCK_RMAX=400** means recv buffer size is limited to a
maximum of 400 bytes. 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. The percentage of send() calls that should be answered with a EAGAIN at random.
For TCP/UNIX sockets. 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 The percentage of data that shall be written to the network. For TCP/UNIX
sockets. This is applied to every send. 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 Example: **CURL_DBG_SOCK_WPARTIAL=80** means a send with 1000 bytes would
only send 800. only send 800.
## CURL_DBG_QUIC_WBLOCK ## `CURL_DBG_QUIC_WBLOCK`
The percentage of send() calls that should be answered with EAGAIN at random. The percentage of send() calls that should be answered with EAGAIN at random.
QUIC only. QUIC only.
## CURL_DEBUG ## `CURL_DEBUG`
Trace logging behavior as an alternative to calling curl_global_trace(3). 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 triggered by `-vv`, add tracing of TCP in addition and remove tracing of
HTTP/2. HTTP/2.
## CURL_DEBUG_SIZE ## `CURL_DEBUG_SIZE`
Fake the size returned by CURLINFO_HEADER_SIZE and CURLINFO_REQUEST_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. 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. 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. 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 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 in libcurl that are otherwise getting random outputs can be tested for what
they generate. they generate.
## CURL_SMALLREQSEND ## `CURL_SMALLREQSEND`
An alternative size of HTTP data to be sent at a time only if smaller than the An alternative size of HTTP data to be sent at a time only if smaller than the
current. current.
## CURL_SMALLSENDS ## `CURL_SMALLSENDS`
An alternative size of socket data to be sent at a time only if smaller than An alternative size of socket data to be sent at a time only if smaller than
the current. the current.
## CURL_TIME ## `CURL_TIME`
Fake Unix timestamp to use for AltSvc, HSTS and CURLINFO variables that are Fake Unix timestamp to use for AltSvc, HSTS and CURLINFO variables that are
time related. 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 variables that are not time-related (such as CURLINFO_LOCAL_PORT), and in that
case the value is not a timestamp. 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. LDAP tracing is enabled if this variable exists and its value is 1 or greater.
OpenLDAP tracing is separate. Refer to CURL_OPENLDAP_TRACE. 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 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. 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 Used to influence the buffer chunk size used for WebSocket encoding and
decoding. decoding.
## CURL_WS_CHUNK_EAGAIN ## `CURL_WS_CHUNK_EAGAIN`
Used to simulate blocking sends after this chunk size for WebSocket Used to simulate blocking sends after this chunk size for WebSocket
connections. connections.
## CURL_FORBID_REUSE ## `CURL_FORBID_REUSE`
Used to set the CURLOPT_FORBID_REUSE flag on each transfer initiated Used to set the CURLOPT_FORBID_REUSE flag on each transfer initiated
by the curl command line tool. The value of the environment variable by the curl command line tool. The value of the environment variable
does not matter. does not matter.
## CURL_GRACEFUL_SHUTDOWN ## `CURL_GRACEFUL_SHUTDOWN`
Make a blocking, graceful shutdown of all remaining connections when Make a blocking, graceful shutdown of all remaining connections when
a multi handle is destroyed. This implicitly triggers for easy handles a multi handle is destroyed. This implicitly triggers for easy handles

View File

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

View File

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

View File

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

View File

@ -47,6 +47,11 @@ 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 activities and tell libcurl again when something happens on one of them. Tell
libcurl by calling curl_multi_socket_action(3). 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 # CALLBACK ARGUMENTS
*easy* identifies the specific transfer for which this update is related. *easy* identifies the specific transfer for which this update is related.

View File

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

View File

@ -42,21 +42,24 @@ header list establishes the document-level MIME headers to prepend to the
uploaded document described by CURLOPT_MIMEPOST(3). This does not affect raw uploaded document described by CURLOPT_MIMEPOST(3). This does not affect raw
mail uploads. mail uploads.
The linked list should be a fully valid list of **struct curl_slist** structs When used with HTTP, this option can add new headers, replace internal headers
properly filled in. Use curl_slist_append(3) to create the list and and remove internal headers.
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).
The headers included in the linked list **must not** be CRLF-terminated, The linked list should be a valid list of **struct curl_slist** entries
because libcurl adds CRLF after each header item itself. Failure to comply properly filled in. Use curl_slist_append(3) to create the list and
with this might result in strange behavior. libcurl passes on the verbatim curl_slist_free_all(3) to free it again after use.
strings you give it, without any filter or other safe guards. That includes
white space and control characters. 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 first line in an HTTP request (containing the method, usually a GET or 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 POST) is not a header and cannot be replaced using this option. Only the lines
@ -164,9 +167,15 @@ int main(void)
if(curl) { if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* add this header */
list = curl_slist_append(list, "Shoesize: 10"); list = curl_slist_append(list, "Shoesize: 10");
/* remove this header */
list = curl_slist_append(list, "Accept:"); 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_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_perform(curl); curl_easy_perform(curl);

View File

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

View File

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

View File

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

View File

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

View File

@ -71,7 +71,7 @@ int main(void)
~~~ ~~~
If you are on Linux and somehow have a need for paths larger than 107 bytes, 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 ~~~c
int dirfd = open(long_directory_path_to_socket, O_DIRECTORY | O_RDONLY); int dirfd = open(long_directory_path_to_socket, O_DIRECTORY | O_RDONLY);

View File

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

View File

@ -51,7 +51,7 @@ stdout
A common technique is to use the write callback to store the incoming data A common technique is to use the write callback to store the incoming data
into a dynamically growing allocated buffer, and then this 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 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 https://curl.se/libcurl/c/getinmemory.html
# HISTORY # HISTORY

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,15 +34,9 @@
#endif #endif
#else /* HAVE_MEMRCHR */ #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); void *Curl_memrchr(const void *s, int c, size_t n);
#define memrchr(x,y,z) Curl_memrchr((x),(y),(z)) #define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
#endif
#endif /* HAVE_MEMRCHR */ #endif /* HAVE_MEMRCHR */
#endif /* HEADER_CURL_MEMRCHR_H */ #endif /* HEADER_CURL_MEMRCHR_H */

View File

@ -120,6 +120,14 @@
# endif # endif
#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 */ /* Compatibility */
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
#define USE_IPV6 1 #define USE_IPV6 1

View File

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

View File

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

View File

@ -76,8 +76,8 @@ CURLcode Curl_addrinfo_callback(struct Curl_easy *data,
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
dns = Curl_cache_addr(data, ai, dns = Curl_cache_addr(data, ai,
data->state.async.hostname, 0, data->conn->host.dispname, 0,
data->state.async.port, FALSE); data->conn->localport, FALSE);
if(data->share) if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS); Curl_share_unlock(data, CURL_LOCK_DATA_DNS);

View File

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

View File

@ -273,46 +273,28 @@ char *Curl_checkProxyheaders(struct Curl_easy *data,
#endif #endif
/* /*
* Strip off leading and trailing whitespace from the value in the * Strip off leading and trailing whitespace from the value in the given HTTP
* given HTTP header line and return a strdupped copy. Returns NULL in * header line and return a strdup()ed copy. Returns NULL in case of
* case of allocation failure. Returns an empty string if the header value * allocation failure or bad input. Returns an empty string if the header
* consists entirely of whitespace. * value consists entirely of whitespace.
*
* If the header is provided as "name;", ending with a semicolon, it must
* return a blank string.
*/ */
char *Curl_copy_header_value(const char *header) char *Curl_copy_header_value(const char *header)
{ {
const char *start; struct Curl_str out;
const char *end;
size_t len;
/* Find the end of the header name */ /* find the end of the header name */
while(*header && (*header != ':')) if(!Curl_str_cspn(&header, &out, ";:") &&
++header; (!Curl_str_single(&header, ':') || !Curl_str_single(&header, ';'))) {
Curl_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE);
Curl_str_trimblanks(&out);
if(*header) return Curl_memdup0(Curl_str(&out), Curl_strlen(&out));
/* Skip over colon */ }
++header; /* bad input */
return NULL;
/* 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 #ifndef CURL_DISABLE_HTTP_AUTH
@ -1468,9 +1450,8 @@ Curl_compareheader(const char *headerline, /* line to check */
* The field value MAY be preceded by any amount of LWS, though a single SP * The field value MAY be preceded by any amount of LWS, though a single SP
* is preferred." */ * is preferred." */
size_t len; const char *p;
const char *start; struct Curl_str val;
const char *end;
DEBUGASSERT(hlen); DEBUGASSERT(hlen);
DEBUGASSERT(clen); DEBUGASSERT(clen);
DEBUGASSERT(header); DEBUGASSERT(header);
@ -1480,31 +1461,21 @@ Curl_compareheader(const char *headerline, /* line to check */
return FALSE; /* does not start with header */ return FALSE; /* does not start with header */
/* pass the header */ /* pass the header */
start = &headerline[hlen]; p = &headerline[hlen];
/* pass all whitespace */ if(Curl_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE))
while(ISSPACE(*start)) return FALSE;
start++; Curl_str_trimblanks(&val);
/* 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 */ /* find the content string in the rest of the line */
for(; len >= clen; len--, start++) { if(Curl_strlen(&val) >= clen) {
if(strncasecompare(start, content, clen)) size_t len;
return TRUE; /* match! */ p = Curl_str(&val);
for(len = Curl_strlen(&val); len >= Curl_strlen(&val); len--, p++) {
if(strncasecompare(p, content, clen))
return TRUE; /* match! */
}
} }
return FALSE; /* no match */ return FALSE; /* no match */
} }
@ -1623,7 +1594,6 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
bool is_connect, int httpversion, bool is_connect, int httpversion,
struct dynbuf *req) struct dynbuf *req)
{ {
char *ptr;
struct curl_slist *h[2]; struct curl_slist *h[2];
struct curl_slist *headers; struct curl_slist *headers;
int numlists = 1; /* by default */ int numlists = 1; /* by default */
@ -1663,98 +1633,81 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
/* loop through one or two lists */ /* loop through one or two lists */
for(i = 0; i < numlists; i++) { for(i = 0; i < numlists; i++) {
headers = h[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;
while(headers) { /* explicitly asked to send header without content is done by a header
char *semicolonp = NULL; that ends with a semicolon, but there must be no colon present in the
ptr = strchr(headers->data, ':'); name */
if(!ptr) { if(!Curl_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ';') &&
char *optr; !Curl_str_single(&p, ';') &&
/* no colon, semicolon? */ !Curl_str_single(&p, '\0') &&
ptr = strchr(headers->data, ';'); !memchr(Curl_str(&name), ':', Curl_strlen(&name)))
if(ptr) { blankheader = TRUE;
optr = ptr; else {
ptr++; /* pass the semicolon */ p = origp;
while(ISSPACE(*ptr)) if(!Curl_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ':') &&
ptr++; !Curl_str_single(&p, ':')) {
struct Curl_str val;
if(*ptr) { Curl_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE);
/* this may be used for something else in the future */ Curl_str_trimblanks(&val);
optr = NULL; if(!Curl_strlen(&val))
} /* no content, don't send this */
else { continue;
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 */
ptr++; /* pass the colon */ /* only send this if the contents was non-blank or done special */
while(ISSPACE(*ptr))
ptr++;
if(*ptr || semicolonp) { if(data->state.aptr.host &&
/* only send this if the contents was non-blank or done special */ /* a Host: header was sent already, do not pass on any custom
CURLcode result = CURLE_OK; Host: header as that will produce *two* in the same
char *compare = semicolonp ? semicolonp : headers->data; 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(data->state.aptr.host && if(result)
/* a Host: header was sent already, do not pass on any custom return result;
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;
} }
} }

View File

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

View File

@ -93,12 +93,6 @@
* newer symbols. * 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 #ifndef _WIN32_WINNT_WINXP
#define _WIN32_WINNT_WINXP 0x0501 /* Windows XP */ #define _WIN32_WINNT_WINXP 0x0501 /* Windows XP */
#endif #endif

View File

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

View File

@ -31,6 +31,12 @@ void Curl_str_init(struct Curl_str *out)
out->len = 0; 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. /* Get a word until the first DELIM or end of string. At least one byte long.
return non-zero on error */ return non-zero on error */
int Curl_str_until(const char **linep, struct Curl_str *out, int Curl_str_until(const char **linep, struct Curl_str *out,
@ -63,6 +69,29 @@ int Curl_str_word(const char **linep, struct Curl_str *out,
return Curl_str_until(linep, out, max, ' '); 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. /* Get a "quoted" word. No escaping possible.
return non-zero on error */ return non-zero on error */

View File

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

View File

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

View File

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

View File

@ -113,88 +113,12 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
/* we are always running on PLATFORM_WINNT */ /* we are always running on PLATFORM_WINNT */
matched = FALSE; matched = FALSE;
} }
#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \ #elif defined(UNDER_CE)
(_WIN32_WINNT < _WIN32_WINNT_WIN2K) (void)majorVersion;
OSVERSIONINFO osver; (void)minorVersion;
(void)buildVersion;
memset(&osver, 0, sizeof(osver)); (void)platform;
osver.dwOSVersionInfoSize = sizeof(osver); (void)condition;
/* 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 #else
ULONGLONG cm = 0; ULONGLONG cm = 0;
struct OUR_OSVERSIONINFOEXW osver; struct OUR_OSVERSIONINFOEXW osver;

View File

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

View File

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

View File

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

View File

@ -58,178 +58,11 @@
#include "curl_memory.h" #include "curl_memory.h"
#include "memdebug.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, CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
struct Curl_cfilter *cf, struct Curl_cfilter *cf,
struct Curl_easy *data, struct Curl_easy *data,
struct ssl_peer *peer, struct ssl_peer *peer,
const char *alpn, size_t alpn_len, const struct alpn_spec *alpns,
Curl_vquic_tls_ctx_setup *cb_setup, Curl_vquic_tls_ctx_setup *cb_setup,
void *cb_user_data, void *ssl_user_data, void *cb_user_data, void *ssl_user_data,
Curl_vquic_session_reuse_cb *session_reuse_cb) Curl_vquic_session_reuse_cb *session_reuse_cb)
@ -254,21 +87,16 @@ CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
(void)result; (void)result;
return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer, return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer, alpns,
(const unsigned char *)alpn, alpn_len,
cb_setup, cb_user_data, NULL, ssl_user_data); cb_setup, cb_user_data, NULL, ssl_user_data);
#elif defined(USE_GNUTLS) #elif defined(USE_GNUTLS)
return Curl_gtls_ctx_init(&ctx->gtls, cf, data, peer, return Curl_gtls_ctx_init(&ctx->gtls, cf, data, peer, alpns,
(const unsigned char *)alpn, alpn_len,
cb_setup, cb_user_data, ssl_user_data, cb_setup, cb_user_data, ssl_user_data,
session_reuse_cb); session_reuse_cb);
#elif defined(USE_WOLFSSL) #elif defined(USE_WOLFSSL)
result = wssl_init_ctx(ctx, cf, data, cb_setup, cb_user_data); return Curl_wssl_ctx_init(&ctx->wssl, cf, data, peer, alpns,
if(result) cb_setup, cb_user_data,
return result; ssl_user_data, session_reuse_cb);
(void)session_reuse_cb;
return wssl_init_ssl(ctx, cf, data, peer, alpn, alpn_len, ssl_user_data);
#else #else
#error "no TLS lib in used, should not happen" #error "no TLS lib in used, should not happen"
return CURLE_FAILED_INIT; return CURLE_FAILED_INIT;
@ -287,10 +115,10 @@ void Curl_vquic_tls_cleanup(struct curl_tls_ctx *ctx)
gnutls_deinit(ctx->gtls.session); gnutls_deinit(ctx->gtls.session);
Curl_gtls_shared_creds_free(&ctx->gtls.shared_creds); Curl_gtls_shared_creds_free(&ctx->gtls.shared_creds);
#elif defined(USE_WOLFSSL) #elif defined(USE_WOLFSSL)
if(ctx->wssl.handle) if(ctx->wssl.ssl)
wolfSSL_free(ctx->wssl.handle); wolfSSL_free(ctx->wssl.ssl);
if(ctx->wssl.ctx) if(ctx->wssl.ssl_ctx)
wolfSSL_CTX_free(ctx->wssl.ctx); wolfSSL_CTX_free(ctx->wssl.ssl_ctx);
#endif #endif
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
} }
@ -351,7 +179,7 @@ CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx,
(void)data; (void)data;
if(conn_config->verifyhost) { if(conn_config->verifyhost) {
if(peer->sni) { if(peer->sni) {
WOLFSSL_X509* cert = wolfSSL_get_peer_certificate(ctx->wssl.handle); WOLFSSL_X509* cert = wolfSSL_get_peer_certificate(ctx->wssl.ssl);
if(wolfSSL_X509_check_host(cert, peer->sni, strlen(peer->sni), 0, NULL) if(wolfSSL_X509_check_host(cert, peer->sni, strlen(peer->sni), 0, NULL)
== WOLFSSL_FAILURE) { == WOLFSSL_FAILURE) {
result = CURLE_PEER_FAILED_VERIFICATION; result = CURLE_PEER_FAILED_VERIFICATION;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,6 +43,7 @@
#include "connect.h" /* for the connect timeout */ #include "connect.h" /* for the connect timeout */
#include "cipher_suite.h" #include "cipher_suite.h"
#include "rand.h" #include "rand.h"
#include "x509asn1.h"
struct rustls_ssl_backend_data struct rustls_ssl_backend_data
{ {
@ -845,6 +846,43 @@ cr_connect(struct Curl_cfilter *cf,
infof(data, "rustls: handshake complete, %s, cipher: %s", infof(data, "rustls: handshake complete, %s, cipher: %s",
ver, buf); 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; connssl->state = ssl_connection_complete;
*done = TRUE; *done = TRUE;
return CURLE_OK; return CURLE_OK;
@ -1011,7 +1049,8 @@ const struct Curl_ssl Curl_ssl_rustls = {
SSLSUPP_CAINFO_BLOB | /* supports */ SSLSUPP_CAINFO_BLOB | /* supports */
SSLSUPP_HTTPS_PROXY | SSLSUPP_HTTPS_PROXY |
SSLSUPP_CIPHER_LIST | SSLSUPP_CIPHER_LIST |
SSLSUPP_TLS13_CIPHERSUITES, SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_CERTINFO,
sizeof(struct rustls_ssl_backend_data), sizeof(struct rustls_ssl_backend_data),
NULL, /* init */ NULL, /* init */

View File

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

View File

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

View File

@ -485,18 +485,6 @@ 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, CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex,
struct dynbuf *binding) struct dynbuf *binding)
{ {
@ -1318,7 +1306,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
struct cf_call_data save; struct cf_call_data save;
CURLcode result; CURLcode result;
if(cf->connected) { if(cf->connected && (connssl->state != ssl_connection_deferred)) {
*done = TRUE; *done = TRUE;
return CURLE_OK; return CURLE_OK;
} }
@ -1336,8 +1324,6 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
CF_DATA_SAVE(save, cf, data); CF_DATA_SAVE(save, cf, data);
CURL_TRC_CF(data, cf, "cf_connect()"); CURL_TRC_CF(data, cf, "cf_connect()");
DEBUGASSERT(data->conn);
DEBUGASSERT(data->conn == cf->conn);
DEBUGASSERT(connssl); DEBUGASSERT(connssl);
*done = FALSE; *done = FALSE;
@ -1349,7 +1335,13 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
goto out; goto out;
} }
result = ssl_connect(cf, data, done); 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);
if(!result && *done) { if(!result && *done) {
cf->connected = TRUE; cf->connected = TRUE;
@ -1358,6 +1350,8 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
/* Connection can be deferred when sending early data */ /* Connection can be deferred when sending early data */
DEBUGASSERT(connssl->state == ssl_connection_complete || DEBUGASSERT(connssl->state == ssl_connection_complete ||
connssl->state == ssl_connection_deferred); connssl->state == ssl_connection_deferred);
DEBUGASSERT(connssl->state != ssl_connection_deferred ||
connssl->earlydata_state > ssl_earlydata_none);
} }
out: out:
CURL_TRC_CF(data, cf, "cf_connect() -> %d, done=%d", result, *done); CURL_TRC_CF(data, cf, "cf_connect() -> %d, done=%d", result, *done);
@ -1365,6 +1359,77 @@ out:
return result; 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, static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data) const struct Curl_easy *data)
{ {
@ -1383,21 +1448,57 @@ static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
} }
static ssize_t ssl_cf_send(struct Curl_cfilter *cf, static ssize_t ssl_cf_send(struct Curl_cfilter *cf,
struct Curl_easy *data, const void *buf, size_t len, struct Curl_easy *data,
const void *buf, size_t blen,
bool eos, CURLcode *err) bool eos, CURLcode *err)
{ {
struct ssl_connect_data *connssl = cf->ctx; struct ssl_connect_data *connssl = cf->ctx;
struct cf_call_data save; struct cf_call_data save;
ssize_t nwritten = 0; ssize_t nwritten = 0, early_written = 0;
(void)eos; (void)eos;
/* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */
*err = CURLE_OK; *err = CURLE_OK;
if(len > 0) { CF_DATA_SAVE(save, cf, data);
CF_DATA_SAVE(save, cf, data);
nwritten = connssl->ssl_impl->send_plain(cf, data, buf, len, err); if(connssl->state == ssl_connection_deferred) {
CF_DATA_RESTORE(cf, save); 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);
return nwritten; return nwritten;
} }
@ -1411,6 +1512,21 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
CF_DATA_SAVE(save, cf, data); CF_DATA_SAVE(save, cf, data);
*err = CURLE_OK; *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); nread = connssl->ssl_impl->recv_plain(cf, data, buf, len, err);
if(nread > 0) { if(nread > 0) {
DEBUGASSERT((size_t)nread <= len); DEBUGASSERT((size_t)nread <= len);
@ -1419,6 +1535,8 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
/* eof */ /* eof */
*err = CURLE_OK; *err = CURLE_OK;
} }
out:
CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len, CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len,
nread, *err); nread, *err);
CF_DATA_RESTORE(cf, save); CF_DATA_RESTORE(cf, save);
@ -1433,7 +1551,9 @@ static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf,
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
*done = TRUE; *done = TRUE;
if(!cf->shutdown && Curl_ssl->shut_down) { /* 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) {
struct cf_call_data save; struct cf_call_data save;
CF_DATA_SAVE(save, cf, data); CF_DATA_SAVE(save, cf, data);
@ -1831,6 +1951,24 @@ bool Curl_alpn_contains_proto(const struct alpn_spec *spec,
return FALSE; 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, CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf,
struct Curl_easy *data, struct Curl_easy *data,
struct ssl_connect_data *connssl, struct ssl_connect_data *connssl,

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

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