Commit Graph

111 Commits

Author SHA1 Message Date
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
Dan Fandrich
41c980bb0d tests: capture stdin to get the vsftpd version number
vsftpd 3.0 at least writes its version number to stdin (!) instead of
stderr. This works due for backwards compatibility reasons in UNIX, so
we must check stdin for anything written there to reliably parse the
version string.

Closes #15278
2024-10-16 09:21:40 -07:00
Dan Fandrich
a3601cf571 tests: allow pytests to run in out-of-tree builds
Some of the files it needs are in the build directory but the code did
not make a distinction.

Closes #15257
2024-10-12 10:47:57 -07:00
Stefan Eissing
962097b8dd
TLS: TLSv1.3 earlydata support for curl
Based on #14135, implement TLSv1.3 earlydata support for the curl
command line, libcurl and its implementation in GnuTLS.

If a known TLS session announces early data support, and the feature is
enabled *and* it is not a "connect-only" transfer, delay the TLS
handshake until the first request is being sent.

- Add --tls-earldata as new boolean command line option for curl.
- Add CURLSSLOPT_EARLYDATA to libcurl to enable use of the feature.
- Add CURLINFO_EARLYDATA_SENT_T to libcurl, reporting the amount of
  bytes sent and accepted/rejected by the server.

Implementation details:
- store the ALPN protocol selected at the SSL session.
- When reusing the session and enabling earlydata, use exactly
  that ALPN protocol for negoptiation with the server. When the
  sessions ALPN does not match the connections ALPN, earlydata
  will not be enabled.
- Check that the server selected the correct ALPN protocol for
  an earlydata connect. If the server does not confirm or reports
  something different, the connect fails.
- HTTP/2: delay sending the initial SETTINGS frames during connect,
  if not connect-only.

Verification:
- add test_02_32 to verify earlydata GET with nghttpx.
- add test_07_70 to verify earlydata PUT with nghttpx.
- add support in 'hx-download', 'hx-upload' clients for the feature

Assisted-by: ad-chaos on github
Closes #15211
2024-10-11 12:28:22 +02:00
Dan Fandrich
57cc523378 tests: enable additional ruff Python lint options
These all seem reasonable to enable for this code.
2024-10-04 14:03:17 -07:00
Dan Fandrich
0f7ba5c5bf tests: change Python code style to pass ruff checks
Most of the changes consisted of removing unused imports and unnecessary
f-strings.
2024-10-04 14:02:05 -07:00
Dan Fandrich
2f3b7f20fb tests: fix some Python typing issues
These otherwise raise errors in pytype. A few problematic methods
weren't being used and are deleted.
2024-10-04 13:57:04 -07:00
Stefan Eissing
72d2090fc2
ftp: fix 0-length last write on upload from stdin
When uploading FTP with unknown length, we write a last 0-length chunk
with the EOS flag set. OpenSSL's SSL_write() errors on such a write.
Skip writing 0-length data to TLS backends instead.

Add test in FTPS for such uploads to verify.

Fixes #15101
Reported-by: Denis Goleshchikhin
Closes #15102
2024-10-01 13:57:12 +02:00
Viktor Szakats
d82f9f965c
build: add pytest targets
It enables running pytests in cmake jobs, regardless of underlying build
tool choice (= makes it work with ninja.)

Also:

- drop pytest logic launching `make` and exiting in case of failure.
  Maybe there is a better way and keep this functionality somehow, bind
  it to a command-line option? make it fail softly?

- GHA/linux: invoke pytest via the build, not directly.

- autotools: add missing dummy runtests targets when cross-compiling.

Closes #15034
2024-09-25 09:25:44 +02:00
Daniel Stenberg
fbf5d507ce
lib/src: white space edits to comply better with code style
... as checksrc now finds and complains about these.

Closes #14921
2024-09-19 14:59:12 +02:00
Gabriel Marin
5a263710f6
lib, src, tests: added space around ternary expressions
Closes #14912
2024-09-18 15:27:26 +02:00
Stefan Eissing
44d1b6c271
pytest: add ftp upload ascii test
Add a test the uploads a text file in ascii mode and checks
that lengths match expectations.

Closes #14721
2024-08-29 16:45:59 +02:00
Stefan Eissing
4c744c3ee2
tests/http: add HTTP/2 Upgrade and prior knowledge tests
Adds test cases to check that plain http: with HTTP/2 works
via 'Upgrade: h2c' or --http2-prior-knowledge'.

Also added tests to check connection reused in these situations.

Closes #14694
2024-08-28 14:04:11 +02:00
Stefan Eissing
ea6f5c9f0f
connect: limit update IP info
Update IP related information at the connection and the transfer in two
places only: once the filter chain connects and when a transfer is added
to a connection. The latter only updates on reuse when the filters
already are connected.

The only user of that information before a full connect is the HAProxy
filter. Add cfilter CF_QUERY_IP_INFO query to let it find the
information from the filters "below".

This solves two issues with the previous version:
- updates where often done twice with the same info
- happy eyeballing filter "forks" could overwrite each others
  updates before the full winner was determined.

Closes #14699
2024-08-28 13:58:10 +02:00