Stefan Eissing [Fri, 10 Apr 2026 09:17:36 +0000 (11:17 +0200)]
pytest: switch off h3 for pytest_07_22
Run test_07_22 only on http/1.1 and h2. For h3, we get unreliable tests
results in CI due to (probably) nghttpx not always reporting the RESET
from the backend and the test timing out.
Viktor Szakats [Wed, 8 Apr 2026 18:46:06 +0000 (20:46 +0200)]
build: skip detecting `pipe2()` for Apple targets
To avoid (mis-)detecting it via the internal Apple library
`/usr/lib/system/libsystem_sim_kernel.dylib` when targeting iPhone
Simulator (seen with iPhoneSimulator26.4.sdk).
Stefan Eissing [Wed, 8 Apr 2026 09:45:30 +0000 (11:45 +0200)]
dns: https-eyeballing async
Make cf-https-connect work async correctly:
- only start first baller when at least one A/AAAA address
is available
- select first connect attempt after that with HTTPS-RR info
there or not.
- select second connect attempt only when HTTPS-RR is resolved
(may have resolved to "not known") and select possible ALPN
from things known by then. May not select any second attempt
when first already covers everything.
This means when the HTTPS-RR is known at/before the first address
is resolved, everything behaves as before. When the HTTPS-RR is
late, a first connection attempt will have been started. Any
ALPN preference from the HTTPS-RR that is not already ongoing will
then start the second attempt.
For HTTPS-RRs that recommend 2 or more ALPNs, the first will always
be attempted: either it is already ongong or it will be the ALPN
for the second attempt. The 2nd ALPN recommendation from HTTPS-RR
*may* be honored or not, depending on what is already selected.
The difference in behaviour between early/late HTTPS-RR resolve
cannot be helped - unless we do not perform any attempts before
it arrives. Trade offs.
Dan Fandrich [Sun, 5 Apr 2026 16:00:55 +0000 (09:00 -0700)]
tests: make whitespace between functions and classes consistent
Mostly, this means two blank lines between classes and functions and one
line between methods. Since these checks are currently in preview, they
are done in a separate ruff invocation to avoid turning ALL the preview
checks on at the same time.
Dan Fandrich [Fri, 3 Apr 2026 00:49:37 +0000 (17:49 -0700)]
tests: enable more ruff checks
- Checks for missing explicit `return` statements at the end of functions
that can return non-`None` values.
- Checks for classes that inherit from `object`.
- Checks for useless expressions.
- Within an `except*` clause, raise exceptions with `raise ... from err`
or `raise ... from None` to distinguish them from errors in exception
handling
- Checks for variable assignments that immediately precede a `return` of the
assigned variable.
- Checks for `else` statements with a `return` statement in the preceding
`if` block.
- Checks for unnecessary parentheses on raised exceptions.
docs: use the correct CURLOPT_WRITEFUNCTION signature
In order to not encourage users to use incompatible function pointers,
change the callback function definitions to use `char *` instead of
`void *` for the first argument.
Triggered by https://stackoverflow.com/questions/79921871/curl-c-c-library-based-application-produces-erronious-response-for-http-post-r#comment141032037_79921871 :
"The code was mostly modified from
[this example code](https://curl.se/libcurl/c/postinmemory.html),
honestly I never knew this is wrong. Thanks for pointing it out."
Viktor Szakats [Tue, 7 Apr 2026 23:35:37 +0000 (01:35 +0200)]
GHA/linux: bump mbedTLS 3 to 3.6.5 (from 3.6.4), also verify hash
Also:
- fix incorrect version in cache id.
Follow-up to 3a305831d1a9d10b2bfd4fa3939ed41275fee7f7 #19077
- latest version 3.6.6 fails pytests. Seems similar to the v4.1.0
regression.
https://github.com/curl/curl/pull/21178
https://github.com/Mbed-TLS/mbedtls/issues/10668
Stefan Eissing [Tue, 7 Apr 2026 09:57:37 +0000 (11:57 +0200)]
cf-ip-happy: limit concurrent attempts
Introduce a limit on the concurrent connect attempts of 6:
- document this in CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS
- close the oldest attempt before opening a new one that would
exceed the limit
- closing failed attempts early to avoid sockets use beyong their
usefulness
- add tests for limits in unit2600
These changes are externally visible as file descriptors will be
reassigned where we previously kept the old one around and started a
new socket, allocating always a new descriptor.
Daniel Stenberg [Sun, 5 Apr 2026 16:23:35 +0000 (18:23 +0200)]
protocol: disable connection reuse for SMB(S)
Connections should only be reused when using the same "share" (and
perhaps some additional conditions), but instead of fixing this flaw,
this change completely disables connection reuse for SMB. This protocol
is about to get dropped soon anyway.
Viktor Szakats [Mon, 6 Apr 2026 15:09:10 +0000 (17:09 +0200)]
GHA/curl-for-win: drop certdata dependency and `GITHUB_TOKEN` with it
`certdata` dependency requires accessing api.github.com for
a reproducible timestamp, which in turn requires a GitHub token to avoid
errors due to rate limiting. Avoid all this by omitting this dependency,
which isn't necessary for these build tests anyway.
The `zero` job already did not use `certdata`, but disable explicitly
anyway just in case.
Viktor Szakats [Sun, 5 Apr 2026 13:31:35 +0000 (15:31 +0200)]
libssh: fix 64-bit printf mask for mingw-w64 <=6.0.0
Fixing (dl-mingw, CM 6.4.0-i686 (mingw-w64 5.0.0) schannel !unity):
```
lib/vssh/libssh.c: In function 'myssh_in_SFTP_QUOTE_STATVFS':
lib/vssh/libssh.c:573:31: error: ISO C does not support the 'I' printf flag [-Werror=format=]
char *tmp = curl_maprintf("statvfs:\n"
^~~~~~~~~~~~
lib/vssh/libssh.c:573:31: error: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'uint64_t {aka long long unsigned int}' [-Werror=format=]
lib/vssh/libssh.c:573:31: error: ISO C does not support the 'I' printf flag [-Werror=format=]
[...]
```
Ref: https://github.com/curl/curl/actions/runs/24002480364/job/70000685821
Daniel Stenberg [Sat, 4 Apr 2026 16:10:31 +0000 (18:10 +0200)]
sendf: fix CR detection if no LF is in the chunk
When doing line ending conversions, and a chunk contains no '\n', the
function returned early without updating prev_cr to reflect the last
byte. It could then lead to CRLFs sequences not get converted when
occuring right on the boundary border.
Viktor Szakats [Thu, 2 Apr 2026 15:03:16 +0000 (17:03 +0200)]
GHA/windows: restore libssh, fix to pass tests with 0.12.0
libssh 0.12.0 on Windows 64-bit Intel fails to connect to sshd (with SSH
state 30) when using the mlkem768x25519-sha256 KEX. (32-bit Intel, ARM64
and tested non-Windows platforms work fine.) Fix by disabling this KEX
for the libssh job.
I do not recommend libssh on Windows due to bugs an insecure behavior.
Also:
- fix libssh TFLAGS condition for mingw-w64.
Viktor Szakats [Sat, 4 Apr 2026 00:14:30 +0000 (02:14 +0200)]
libssh: fix `-Wsign-compare` in 32-bit builds
Seen with mingw-w64 i686 gcc 15.2.0 (mingw32):
```
D:/a/curl/curl/lib/vssh/libssh.c: In function 'myssh_in_SFTP_QUOTE_STAT':
D:/a/curl/curl/lib/vssh/libssh.c:1664:13: error: comparison of integer expressions
of different signedness: 'time_t' {aka 'long int'} and 'unsigned int' [-Werror=sign-compare]
1664 | if(date > UINT_MAX)
| ^
cc1.exe: all warnings being treated as errors
```
Ref: https://github.com/curl/curl/actions/runs/23966805891/job/69908216152
Samuel Henrique [Mon, 30 Mar 2026 05:18:52 +0000 (22:18 -0700)]
test 766: flag as timing-dependent
We have noticed this test as failing when run in parallel in Fedora and
Amazon Linux:
https://src.fedoraproject.org/rpms/curl/c/389f1409549178f639afa49f478c544fdaa87be2?branch=rawhide
Debian did not have issues but given there are other FTP tests flagged
as timing-dependent, it makes sense to flag this one too if we notice
failures in other OSes.
Daniel Stenberg [Thu, 2 Apr 2026 07:16:17 +0000 (09:16 +0200)]
hsts: make the HSTS read callback handle name dupes
Now the logic for handling name duplicates and picking the longest
expiry and strictest subdomain is the same for the callback as for when
reading from file.
Also strip trailing dots from the hostname added by the callback.
A minor side-effect is that the hostname provided by the callback can
now enable subdomains by starting the name with a dot, but we discourage
using such hostnames in documentation.
Viktor Szakats [Thu, 2 Apr 2026 09:46:22 +0000 (11:46 +0200)]
GHA/windows: drop building with libssh
Bumping `msys2/setup-msys2` from 2.30.0 to 2.31.0 also brought libssh
0.12.0 (after 0.11.3). libssh has been long known for loading OpenSSH
configuration from disk insecurely on Windows. 0.12.0 brings some fixes
to this (CVE-2025-14821), which in turn may be changing its behavior on
the default GH Windows runner to fail all curl SCP/SFTP tests.
Detecting what is the exact root cause, then defining exact runtime
conditions for it is difficult and fragile. Same for changing these
libssh defaults (if at all possible.)
But, since configuration loading remains insecure and broken on Windows
even after the mitigations made by 0.12.0 [0], this patch removes libssh
from the Windows CI job using it previously.
If someone figures out how to run in CI, it can be readded, though in
general, using libssh on Windows seems to be less than ideal.
Daniel Stenberg [Wed, 1 Apr 2026 13:44:02 +0000 (15:44 +0200)]
url: init req.no_body in DO so that it works for h2 push
req.no_body was only initialized in Curl_connect, while HTTP/2 server
push adds a duplicated handle via Curl_multi_add_perform and calls
Curl_init_do with conn==NULL, never invoking Curl_connect.
- update `actions/cache` from 5.0.3 to 5.0.4
- update `actions/download-artifact` from 7.0.0 to 8.0.1
- update `actions/upload-artifact` from 6.0.0 to 7.0.0
- update `msys2/setup-msys2` from 2.30.0 to 2.31.0
- update pip `ruff` from 0.15.7 to 0.15.8
Stefan Eissing [Tue, 31 Mar 2026 09:45:21 +0000 (11:45 +0200)]
lib: make resolving HTTPS DNS records reliable:
- allow to specify when they are wanted on starting a resolve
- match dns cache entries accordingly. An entry which never
tried to get HTTPS-RRs is no answer for a resolve that wants
it.
- fix late arrivals of resolve answers to match the "async"
records that started them - if it still exists.
- provide for multiple "async" resolves in a transfer at the
same time. We may need to resolve an IP interface while the
main connection resolve has not finished yet.
- allow lookup of HTTPS-RR information as soon as it is
available, even if A/AAAA queries are still ongoing.
For this, the "async" infrastructure is changed:
- Defined bits for DNS queries `CURL_DNSQ_A`, `CURL_DNSQ_AAAA`
and `CURL_DNSQ_HTTPS`. These replace `ip_version` which says
nothing about HTTPS.
Use them in dns cache entries for matching.
- enhance the `async->id` to be a unique `uint32_t` for
resolves inside one multi. This is weak, as the id may
wrap around. However it is combined with the `mid` of
the easy handle, making collisions highly unlikely.
`data->state.async` is only accessed in few places where
the mid/async-id match is performed.
- vtls: for ECH supporting TLS backends (openssl, rustls, wolfssl),
retrieve the HTTPS-RR information from the dns connection filter.
Delay the connect if the HTTPS-RR is needed, but has not
been resolved yet.
The implementation of all this is complete for the threaded
resolver. c-ares resolver and DoH do not take advantage of
all new async features yet. To be done in separate PRs.
Details:
c-ares: cleanup settings and initialisation. Any ares channel
is only being created on starting a resolve and propagating
operations in setopt.c to the channel are not helpful.
Changed threaded+ares pollset handling so that they do not
overwrite each others `ASYNC_NAME` timeouts.
Add trace name 'threads' for tracing thread queue and
pool used by threaded resolver.
Daniel Stenberg [Wed, 1 Apr 2026 08:24:06 +0000 (10:24 +0200)]
HSTS: cap the list at 1,000 entries
Avoid never-ending growth.
When adding more entries, it now deletes the first entry in the list,
which is the oldest added entry still held in memory. I decided to avoid
a Least Recently Used concept as I suspect with a list with this many
entries most entries have not been used, and we don't save the timestamp
of recent use anyway.
The net effect might (no matter what) be that the removed entry might
feel a bit "random" in the eyes of the user.
Daniel Stenberg [Wed, 1 Apr 2026 07:53:42 +0000 (09:53 +0200)]
altsvc: cap the list at 5,000 entries
Avoid never-ending growth.
When adding more entries, it now deletes the first entry in the list,
which is the oldest added entry still held in memory. I decided to avoid
a Least Recently Used concept as I suspect with a list with this many
entries most entries have not been used, and we don't save the timestamp
of recent use anyway.
The net effect might (no matter what) be that the removed entry might
feel a bit "random" in the eyes of the user.
Daniel Stenberg [Wed, 1 Apr 2026 06:09:47 +0000 (08:09 +0200)]
cookie: fix rejection when tabs in value
A previous refactor changed the TAB check so that the octet could be
accepted in the 'path', which would cause an invalid line in the saved
cookie file so not possible to read the cookie back. Not terrible
because the path cannot contain a raw tab anyway so it would never match
anyway.
Viktor Szakats [Tue, 31 Mar 2026 19:01:57 +0000 (21:01 +0200)]
GHA: try workaround for slow Azure Ubuntu distro server (cont.)
- fail if all retries failed.
- run `dpkg --configure -a` after an aborted slow attempt.
```
Selecting previously unselected package libsys-hostname-long-perl.
Error: slow server, retry
E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
[...]
```