Commit graph

124 commits

Author SHA1 Message Date
Viktor Szakats
a87383828e
badwords: fix issues found in tests
There remain some false positives, hits in test data, and `dir` use,
around 100 issues in total.

There is no plan to enforce badwords on tests.

Also:
- badwords.txt: let a few `manpage[s]` occurrences through
  (in Perl code).

Closes #19541
2025-11-17 13:30:35 +01:00
Stefan Eissing
217f0e4d59
pytest fixes and improvements
- fix test_17_20 flakiness: the test case did not have `nghttpx` in
  its parameters, causing it to no check if a reload was necessary.
  When that test ran behind one that gave nghttpx another certificate,
  eg. in parallel mode, it used the wrong pinned pubkey.
- Have `env` provide lists of HTTP protocol versions available for
  testing. Replace parameterized tests on a fixed protocol list with
  the dynamic one from env. This makes checks for protocol availability
  in the test function bodies superfluous.

refs #19489
Closes #19540
2025-11-17 08:02:52 +01:00
Viktor Szakats
b81d30ade3
pytest: fix conditions for test_02_28
- allow 02_28 to run in HTTP/1.1 without H2 support again.
  Follow-up to 3752de465d #19412

- fix to skip 02_28 for all protocols for curl without compression
  support (either zlib, brotli or ztsd).

Closes #19458
2025-11-10 23:30:20 +01:00
Stefan Eissing
f55974c139
vtls: fix CURLOPT_CAPATH use
A regression in curl 8.17.0 led to a customer CAPATH set by the
application (or the curl command) to be ignored unless licurl was built
with a default CAPATH.

Add test cases using `--capath` on the custom pytest CA, generated with
the help of the openssl command when available.

Fixes #19401
Reported-by: Brad King
Closes #19308
2025-11-08 17:02:54 +01:00
Stefan Eissing
692c7f133e
TLS: IP address verification, extend test
Change the test certificate to carry a altname 'dns:127.0.0.1' which
should *not* match in test_17_05_bad_ip_addr.

wolfSSL: since `wolfSSL_check_domain_name()` does not differentiate
between DNS and IP names, use if only for DNS names. For IP addresses,
get the peer certificate after the handshake and check that using
wolfSSL_X509_check_ip_asc().

Unfortunately, this succeeds where it should not, as wolfSSL internally
used the same check code for both cases. So, skip the test case until
wolfSSL fixes that.

Reported-by: Joshua Rogers
Closes #19252
2025-10-27 17:22:17 +01:00
Stefan Eissing
40f7cd2bdd
mime: fix unpausing of readers
When unpausing a transfer, check if the reader pause state differs
in addition to the "keepon" flags.

Reported-by: 包布丁
Fixes #18848
Closes #19178
2025-10-21 16:30:47 +02:00
Viktor Szakats
026498df43
mod_curltest: tidy-ups and small fixes
- honor request id (`id=<number>`) in `curltest/put` and
  `curltest/sslinfo` handlers.
- do not truncate `max_upload` input parameter.
- delete unused variables.
- formatting.

Inspired by Joshua's report on tests.

Closes #19061
2025-10-19 13:46:59 +02:00
Stefan Eissing
1ea99afdc7
scorecard: add perf support on linux
When calling scorecard with --flame to produce a flamegraph, use
"perf" on linux platforms to do the measurements. Update the scorecard
documentation about it.

Closes #19058
2025-10-14 16:24:35 +02:00
Stefan Eissing
357808f4ad
multi: add notifications API
Add infrastructure to colled and dispatch notifications for transfers
and the multi handle in general. Applications can register a callback
and en-/disable notification type the are interested in.

Without a callback installed, notifications are not collected. Same when
a notification type has not been enabled.

Memory allocation failures on adding notifications lead to a general
multi failure state and result in CURLM_OUT_OF_MEMORY returned from
curl_multi_perform() and curl_multi_socket*() invocations.

Closes #18432
2025-10-07 10:55:31 +02:00
Viktor Szakats
34dc762cef
pytest: skip specific tests for no-verbose builds
Detect via curlinfo if curl has verbose strings disabled, and skip
tests that require it.

Also:
- cmake: make pytests depend on curlinfo.

Cherry-picked from #18797
Closes #18801
2025-10-02 10:41:46 +02:00
Stefan Eissing
b022389757
ip-happy: do not set unnecessary timeout
When attempts on all addresses have been started, do no longer set any
EXPIRE_HAPPY_EYEBALLS timeouts.

Fixes #18767
Reported-by: Johannes Schindelin
Closes #18768
2025-10-01 08:01:47 +02:00
Stefan Eissing
b0f6593219
openssl-quic: check results better
Fail on errors from SSL_handle_events().
Force quit Caddy test instance that is left hanging longer with
openssl-quic tests for unknown reasons.

Reported in Joshua's sarif data

Closes #18720
2025-09-25 14:07:56 +02:00
Stefan Eissing
115fe808f2
ngtcp2: check error code on connect failure
Access the error codes of ngtcp2 when a connect attempt failes. Trace
the information for analysis. Treat errors as permanent failure by
default, trigger retrying only when the server refused without
indicating an error.

Closes #18521
2025-09-11 16:00:58 +02:00
Viktor Szakats
61759a9843
pytest: bind to localhost
Pointed out by CodeQL

Fixes https://github.com/curl/curl/security/code-scanning/298

Closes #18506
2025-09-10 00:55:07 +02:00
Stefan Eissing
24badd29f5
multi: limit-rate revisited
Tweaks around handling of --limit-rate:

* tracing: trace outstanding timeouts by name
* multi: do not mark transfer as dirty that have
  an EXPIRE_TOOFAST set
* multi: have one static function to asses speed limits
* multi: when setting EXPIRE_TOOFAST remove the transfers
  from the dirty set
* progress: rename vars and comment on how speed limit
  timeouts are calculated, for clarity
* transfer: when speed limiting, exit the receive loop
  after a quarter of the limit has been received, not
  on the first chunk received.
* cf-ip-happy.c: clear EXPIRE_HAPPY_EYEBALLS on connect
* scorecard: add --limit-rate parameter to test with
  speed limits in effect

Closes #18454
2025-09-03 15:53:41 +02:00
Viktor Szakats
7956a2a756
gnutls: fix building with older supported GnuTLS versions
Also:
- GHA/linux-old: switch jobs from OpenSSL 1.0.2 to GnuTLS 3.5.8.

Ref: https://gitlab.com/gnutls/gnutls/blob/master/NEWS
Follow-up to fa0ccd9f1f #15774
Follow-up to 68bd759c2b #15667
Cherry-picked from #18330
Closes #18335
2025-08-21 18:04:25 +02:00
Stefan Eissing
83da4d9d3b
connectdata: remove primary+secondary ip_quadruple
Since the content varies during connection setup and while doing it
(eyeballing), remove these strcut from `connectdata` and replace use
with querying the connection filters. Those keep that information
already.

Change the info logging of established connections to also give the
local address and port.

Closes #17960
2025-07-30 10:56:19 +02:00
Viktor Szakats
00887aee8c
tests: merge clients into libtests, drop duplicate code
libtests and clients were built the same way after recent overhauls.
libtests are used by runtests, clients by pytests.

Merge clients into libtests, aligning their entry function signature,
dropping common utility functions, and simplifying the build.

Note: After this patch `CURLDEBUG` applies to cli tests, when enabled.

Also:
- lib552: drop local copy-paste debug callback in favor of testtrace.
- lib552: drop local copy-paste dump function in favor of testtrace.
- clients: use `long` for HTTP version, drop casts.
- clients: replace local dump function in favor of testrace clone.
- sync cli test entry function prototype with libtests'.
- h2_serverpush: replace local trace callback with testtrace.
- de-duplicate 3 websocket close, ping, ping, functions. Kept the pong
  iteration from `ws_pingpong`. Note: the pong clone in `lib2304` was
  returning an error when `curl_ws_recv()` returned non-zero and
  the payload matched the expected one anyway. After this patch, this
  case returns success, as it does in `ws_pingpong`.
  `lib2304` keeps passing, but I'm not sure if the previous behavior
  was intentional.
- display full value in websocket close, ping, pong, drop casts.

Closes #18079
2025-07-30 02:38:13 +02:00
Stefan Eissing
6b70e8a838
pytest: use dante-server in CI
- add startup check for 'danted' to avoid fails on low cpu
- rename 'sockd' to 'danted' everywhere to clarify what we use
- add proper defaults for 'danted' for debian
- install 'dante-server' in pytest ci runs

Closes #18075
2025-07-29 15:02:30 +02:00
Stefan Eissing
6845533e24
curl: add long option '--out-null'
Add a new commandline option --out-null that discards all
response bytes into the void. Replaces non-portable use of
'-o /dev/null' with more efficiency.

Feature added in 8.16.0

Closes #17800
2025-07-28 14:57:38 +02:00
Viktor Szakats
89771d19d5
tidy-up: prefer ifdef/ifndef for single checks
Closes #18018
2025-07-27 22:35:17 +02:00
Stefan Eissing
ab5e0bfddc
pytest: add SOCKS tests and scoring
Configure curl with `--with-test-sockd=<path to sockd>` for a locally
installed dante sockd server and new `test_40_*` will verify that
down- and uploads work via SOCKS.

Invoke scorecard.py with `--socks4` or `--socks5` to run performance
tests with SOCKS. Note that SOCKS is not supported for HTTP/3.

Ref: #17969
Closes #17986
2025-07-23 18:12:31 +02:00
Stefan Eissing
53e5cdc47b
pytest: increase server KeepAliveTimeout
When CI is not able to give clients enough cpu, the default Apache
KeepAliveTimeout of 5 seconds may trigger and cause tests to fail.

Increase the timeout to 30 seconds for reliability.

Ref: #17963
Closes #17968
2025-07-20 23:15:11 +02:00
Stefan Eissing
51f933801e
scorecard: flame graphs and documentation
Add `--flame` option to scorecard.py for generating flame graphs.
Add documentation in docs/internal/SCORECARD.md on how to use this.

Closes #17792
2025-07-07 09:04:22 +02:00
Stefan Eissing
21ecc7e376
cf-socket: make socket data_pending a nop
Eliminating the socket readability check in the socket connection
filters for the 'data_pending' callback. Improves performance of
handling of transfers, up to ~30%, depending on parallelism and response
size.

Whatever `data_pending()` once was, its semantics are now:
"Is there anything buffered in the connection filters that needs
 receive?"
Any checks of the socket's readability are done via `multi_wait()`
and friends.

Fix the one place in HTTP/1 proxy code that checked `data_pending()` and
did an early return if false. Remove that check and actually try to
receive data every time.

Closes #17785
2025-06-30 13:44:24 +02:00
Viktor Szakats
9b7c488f17
tests/http/clients: move to tests/client
To have all the tests binaries directly under the tests directory.

There seems to be no issue adding non-http test clients to this subdir.

Closes #17637
2025-06-17 19:39:36 +02:00
Viktor Szakats
739c09c8a4
tests: bundle http clients, de-dupe, enable for MSVC
To make building the http client tests faster, with no duplication, by
using the build method that other test binaries already use.

The difference compared to other tests is that these don't use internal
libcurl headers or code. With the exception of `curl_config.h`, for
a feature macro.

Before this patch, these tests were built like examples.

Also:
- de-duplicate code and give unique names to colliding symbols.
- add local getopt implementation and enable all code for MSVC.
  Adapted for curl via Public Domain source:
  4e618ef782/getopt.h
  Credits-to: Christopher Wellons
  Thanks!

Closes #17627
2025-06-16 12:29:05 +02:00
Stefan Eissing
d9bebede59
pytest: adapt for runs with openssl-1.1.1
Fix use of nghttpx fixture to be present even when h3 is not
available in curl. Fix TLS protocol versions expectations for
older openssl versions.

Closes #17538
2025-06-05 13:52:29 +02:00
Stefan Eissing
dc60a82747
scorecard: rework format and add json print
Improve the JSON result format to be more descriptive and
easier to parse.

Add --print option to scorecard.py that prints a saved JSON file
Add date field to score card.

Closes #17465
2025-06-02 23:15:33 +02:00
Stefan Eissing
71bb004c29
http: fail early when rewind of input failed when following redirects
When inspecting a possible follow HTTP request, the result of a rewind
of the upload data was ignored as it was not clear at that point in time
if the request would become a GET.

This initiated the followup, rewound again, which failed again and
terminated the follow up.

This was confusing to users as it was not clear of the follow up was
done or not.

Fix: fail the early rewind when the request is not converted to GET.

Fixes #17472
Closes #17474
Reported-by: Jeroen Ooms
2025-05-28 14:53:02 +02:00
Stefan Eissing
e1f65937a9
pytest: add pinnedpubkey test cases
Add positive/negative test cases in pytest for pinned public keys.

Closes #17412
2025-05-21 22:45:42 +02:00
Viktor Szakats
42331cb48a
pytest: enable in 5 GHA jobs, fix fallouts
They take about 4.5 minutes of CI time in GHA/macos.

Also:
- autotools: improve `caddy`, `vsftpd` detection.
  Bringing it closer to cmake.
- autotools: fix `--with-test-caddy=no`, `--with-test-vsftps=no`,
  `--with-test-nghttpx=no` options.
- cmake: sync `nghttpx` default with autotools.
- pytest: disable failing mbedTLS tests on macOS CI.
- pytest: disable failing earlydata tests on macOS CI.
- GHA/macos: keep vsftpd pytests disabled due to lengthy run times.
- pytest: fix test_05_04 for LibreSSL. Ref: #17367
  Authored-by: Stefan Eissing

Remaining issues:
- some unidentified tests taking a long time with mbedTLS:
  `================= 462 passed, 278 skipped in 347.93s (0:05:47) =================`
  Ref: https://github.com/curl/curl/actions/runs/15073354301/job/42374999041#step:17:1536
  Workaround: not enabling pytest for mbedTLS jobs
- 17 FTP tests taking a long time (affecting all TLS backends):
  without vsftpd:
  `====================== 496 passed, 244 skipped in 56.15s =======================`
  Ref: https://github.com/curl/curl/actions/runs/15073354301/job/42374998230#step:17:1536
  with vsftpd:
  `================= 513 passed, 227 skipped in 409.37s (0:06:49) =================`
  Ref: https://github.com/curl/curl/actions/runs/15073678568/job/42376039672?pr=17362#step:17:1537
  Workaround: force-disable vsftpd.
- 100 tests failing with SecureTransport. Let's ignore that due to imminent deprecation.
  Ref: https://github.com/curl/curl/actions/runs/15055652333/job/42320873732#step:17:15362

Follow-up to 30ef79ed93 #17295
Follow-up to 9147903366 #16518

Closes #17362
2025-05-19 15:38:05 +02:00
Stefan Eissing
a85f1df480
pytest tls: extend coverage
Add possibility to reload QUIC test server with another certificate. Add
tests for more coverage of handshakes.

Closes #17382
2025-05-19 13:30:02 +02:00
Stefan Eissing
30ef79ed93
pytest-xdist: pytest in parallel
Require now pytest-xdist from tests/http/requirements.txt and
run pytest in 'auto' parallel mode (counts cpu cores).

For CI runs, set the worker count to 4, overriding the
core count of 2 exposed in the images.

- use Filelock to generate allocated ports at start for all
  workers and have subsequent workers just read the file and
  take the ports for their slot
- make httpd config clearing a function fixture so every test
  starts with a clean httpd config
- have fixture `configures_httpd` as parameter of test cases
  that configure httpd anyway, saving one reload
- add pytest-xdist and filelock to required pyhton modules
- add installs to ruff CI
- give live checks waiting for a server to start up longer time
- add fixtures to tests that rely on a server
- do not stop servers unnecessarily. failures may not start them
  properly again, leading to unexpected fails in whatever follows
- add a https: port to httpd that is *not* back by QUIC to allow
  failover tests without stopping the QUIC server

Closes #17295
2025-05-15 21:44:31 +02:00
Stefan Eissing
1d66a769d7
http: fix HTTP/2 handling of TE request header using "trailers"
A "TE" request header is allowed in HTTP/2 when it only carries the
"trailers" value. RFC 9113 ch. 8.2.2. Check client supplied TE values
for the "trailers" token and only pass that one in a HTTP/2 request.

Add test_01_17 to verify.

Fixes #17122
Reported-by: epicmkirzinger on github
Closes #17128
2025-04-22 15:55:36 +02:00
Stefan Eissing
2b6f503570
pytest: make test_07_22 more lenient to exit codes
Depending on timing when the server aborting the connection is detected,
the reported curl exit code may vary. Check for the possible set of
expected codes instead of a single one.

Closes #17083
2025-04-17 17:30:03 +02:00
Stefan Eissing
35cfb081d2
pytest: check overlarge response headers
Add test_01 11, 12 and 13 to check various very long response
headers (accumulated and single) with http/1.1 and h2.

Closes #16541
2025-03-03 15:46:55 +01:00
Stefan Eissing
0d3b5937b3
OpenSSL/quictls: add support for TLSv1.3 early data
based on #16450

Adds support for TLSv1.3 early data for TCP and QUIC via ngtcp2.

Closes #16477
2025-03-03 09:27:04 +01:00
Stefan Eissing
df5db8afaf
conn: fix connection reuse when SSL is optional
In curl 8.12 I tried to improve the logic on how we handle connections
that "upgrade" to TLS later, e.g. with a STARTTLS. I found the existing
code hard to read in this regard. But of course, the "improvements" blew
up in my face.

We fixed issues with imap, opo3, smtp in 8.12.1, but ftp was no longer
reusing existing, upgraded control connections as before. This PR adds
checks in our pytest FTP tests that verify reuse is happening as
intended.

I rewrote the logic in url.c again, so that the new test checks now pass.

Reported-by: Zenju on github
Fixes #16384
Closes #16392
2025-02-20 16:23:35 +01:00
Stefan Eissing
f78700814d
client writer: handle pause before deocding
Adds a "cw-pause" client writer in the PROTOCOL phase that buffers
output when the client paused the transfer. This prevents content
decoding from blowing the buffer in the "cw-out" writer.

Added test_02_35 that downloads 2 100MB gzip bombs in parallel and
pauses after 1MB of decoded 0's.

This is a solution to issue #16280, with some limitations:
- cw-out still needs buffering of its own, since it can be paused
  "in the middle" of a write that started with some KB of gzipped
  zeros and exploded into several MB of calls to cw-out.
- cw-pause will then start buffering on its own *after* the write
  that caused the pause. cw-pause has no buffer limits, but the
  data it buffers is still content-encoded.
  Protocols like http/1.1 stop receiving, h2/h3 have window sizes,
  so the cw-pause buffer should not grow out of control, at least
  for these protocols.
- the current limit on cw-out's buffer is ~75MB (for whatever
  historical reason). A potential content-encoding that blows 16KB
  (the common h2 chunk size) into > 75MB would still blow the buffer,
  making the transfer fail. A gzip of 0's makes 16KB into ~16MB, so
  that still works.

A better solution would be to allow CURLE_AGAIN handling in the client
writer chain and make all content encoders handle that. This would stop
explosion of encoding on a pause right away. But this is a large change
of the deocoder operations.

Reported-by: lf- on github
Fixes #16280
Closes #16296
2025-02-20 15:53:18 +01:00
Stefan Eissing
fa5d5ac1c9
pytest: use httpd/apache2 directly, no apachectl
Since the script 'apachectl' from the httpd project is severly mutilated
on several distros, use the executable httpd/apache2 directly in pytest
runs.

Remove detection of apachectl form autoconf and cmake.

Closes #16000
2025-01-14 11:33:49 +01:00
Stefan Eissing
68bd759c2b
QUIC: 0RTT for gnutls via CURLSSLOPT_EARLYDATA
When a QUIC TLS session announced early data support and
'CURLSSLOPT_EARLYDATA' is set for the transfer, send initial request and
body (up to the 128k we buffer) as 0RTT when curl is built with
ngtcp2+gnutls.

QUIC 0RTT needs not only the TLS session but the QUIC transport
paramters as well. Store those and the earlydata max value together with
the session in the cache.

Add test case for h3 use of this. Enable quic early data in nghttpx for
testing.

Closes #15667
2024-12-23 17:07:15 +01:00
Stefan Eissing
fd4528a8d8
OpenSSL: improvde error message on expired certificate
Fix regression that no longer printed the error messages about expired
certificates in openssl. Add test case for openssl/gnutls/wolfssl.

Fixes #15612
Reported-by: hiimmat on github
Closes #15613
2024-12-02 21:17:59 +01:00
Viktor Szakats
25025419c9
pytest: include curl version string and python platform in log
For the Test Clutch matrix.

https://testclutch.curl.se/static/reports/feature-matrix.html

Assisted-by: Dan Fandrich
Closes #15470
2024-11-02 01:56:55 +01:00
Dan Fandrich
d88db0b6b2 tests: use a set for several of the curl_props
These are used for member-of testing, so a set is more appropriate and
efficient. Also, fix a couple cases of bad exceptions.

Closes #15462
2024-10-31 20:14:44 -07:00
Viktor Szakats
bc6212004a
pytest: show curl features and protocols
For the Test Clutch matrix.

https://testclutch.curl.se/static/reports/feature-matrix.html

Closes #15452
2024-10-30 09:32:29 +01:00
Stefan Eissing
0d475da1c4
pytest: fix run against multissl curl
Changes to make a curl built with OpenSSL + GnuTLS to run successfully
in our pytests. Run

CURL_SSL_BACKEND=openssl pytest

to test a TLS backend other than the default.

Closes #15443
2024-10-29 11:13:56 +01:00
Stefan Eissing
701813b23f
tests/http: add --insecure tests
Add two test cases that connection using a hostname the server has no
certificate for. First, verify that the peer verification fail, as
expected. Second, provide '--insecure' to test that the connection
succeeded and returned some data.

Closes #15429
2024-10-28 13:04:28 +01:00
Stefan Eissing
0e0c8cdf89
tests/scorecard: allow remote server test
New args for scorecard.py:
* --remote ip:port to run tests against a remote server
* --start-only: to only start the servers, listing their ports

Start the server using "scorecard.py --start-only" on one machine and
then run the tests with "scorecard.py --remote ip:port" against that
machine.

Closes #15415
2024-10-28 11:41:19 +01:00
Stefan Eissing
fe2a72029e
http2: auto reset stream on server eos
When a server signals EOS from its side and the curl upload is
unfinished and the server has not given a positive HTTP status response,
auto RST the stream to signal that the upload is incomplete and that the
whole transfer can be stopped.

Fixes the case where the server responds with 413 on an upload but does
not RST the stream from its side, as httpd and others do.

Reported-by: jkamp-aws on github
Fixes #15316
Closes #15325
2024-10-17 23:03:41 +02:00