Commit Graph

60 Commits

Author SHA1 Message Date
Stefan Eissing
3e6254f819
url: proxy ssl connection reuse fix
- tunnel https proxy used for http: transfers does
  no check if proxy-ssl configuration matches
- test cases added, test_10_12 fails on 8.4.0

Closes #12255
2023-11-03 16:43:45 +01:00
Stefan Eissing
7e1c0851bf
pytest: use lower count in repeat tests
- lower large iteration counts in some tests somewhat for
  the same coverage with less duration

Closes #12248
2023-11-02 16:35:00 +01:00
Stefan Eissing
47f5b1a37f
lib: introduce struct easy_poll_set for poll information
Connection filter had a `get_select_socks()` method, inspired by the
various `getsocks` functions involved during the lifetime of a
transfer. These, depending on transfer state (CONNECT/DO/DONE/ etc.),
return sockets to monitor and flag if this shall be done for POLLIN
and/or POLLOUT.

Due to this design, sockets and flags could only be added, not
removed. This led to problems in filters like HTTP/2 where flow control
prohibits the sending of data until the peer increases the flow
window. The general transfer loop wants to write, adds POLLOUT, the
socket is writeable but no data can be written.

This leads to cpu busy loops. To prevent that, HTTP/2 did set the
`SEND_HOLD` flag of such a blocked transfer, so the transfer loop cedes
further attempts. This works if only one such filter is involved. If a
HTTP/2 transfer goes through a HTTP/2 proxy, two filters are
setting/clearing this flag and may step on each other's toes.

Connection filters `get_select_socks()` is replaced by
`adjust_pollset()`. They get passed a `struct easy_pollset` that keeps
up to `MAX_SOCKSPEREASYHANDLE` sockets and their `POLLIN|POLLOUT`
flags. This struct is initialized in `multi_getsock()` by calling the
various `getsocks()` implementations based on transfer state, as before.

After protocol handlers/transfer loop have set the sockets and flags
they want, the `easy_pollset` is *always* passed to the filters. Filters
"higher" in the chain are called first, starting at the first
not-yet-connection one. Each filter may add sockets and/or change
flags. When all flags are removed, the socket itself is removed from the
pollset.

Example:

 * transfer wants to send, adds POLLOUT
 * http/2 filter has a flow control block, removes POLLOUT and adds
   POLLIN (it is waiting on a WINDOW_UPDATE from the server)
 * TLS filter is connected and changes nothing
 * h2-proxy filter also has a flow control block on its tunnel stream,
   removes POLLOUT and adds POLLIN also.
 * socket filter is connected and changes nothing
 * The resulting pollset is then mixed together with all other transfers
   and their pollsets, just as before.

Use of `SEND_HOLD` is no longer necessary in the filters.

All filters are adapted for the changed method. The handling in
`multi.c` has been adjusted, but its state handling the the protocol
handlers' `getsocks` method are untouched.

The most affected filters are http/2, ngtcp2, quiche and h2-proxy. TLS
filters needed to be adjusted for the connecting handshake read/write
handling.

No noticeable difference in performance was detected in local scorecard
runs.

Closes #11833
2023-10-25 09:34:32 +02:00
Stefan Eissing
6b9a591bf7
h2: testcase and fix for pausing h2 streams
- refs #11982 where it was noted that paused transfers may
  close successfully without delivering the complete data
- made sample poc into tests/http/client/h2-pausing.c and
  added test_02_27 to reproduce

Closes #11989
Fixes #11982
Reported-by: Harry Sintonen
2023-09-30 23:53:33 +02:00
Stefan Eissing
3d53f211e5
pytest: exclude test_03_goaway in CI runs due to timing dependency
Closes #11860
2023-09-21 08:57:57 +02:00
Stefan Eissing
3b30cc1a0d
pytest: improvements
- set CURL_CI for pytest runs in CI environments
- exclude timing sensitive tests from CI runs
- for failed results, list only the log and stat of
  the failed transfer

- fix type in http.c comment

Closes #11812
2023-09-07 10:30:14 +02:00
Stefan Eissing
2485547da0
http: fix sending of large requests
- refs #11342 where errors with git https interactions
  were observed
- problem was caused by 1st sends of size larger than 64KB
  which resulted in later retries of 64KB only
- limit sending of 1st block to 64KB
- adjust h2/h3 filters to cope with parsing the HTTP/1.1
  formatted request in chunks

- introducing Curl_nwrite() as companion to Curl_write()
  for the many cases where the sockindex is already known

Fixes #11342 (again)
Closes #11803
2023-09-05 16:36:03 +02:00
Stefan Eissing
a8a82140aa
pytest: fix check for slow_network skips to only apply when intended
Closes #11801
2023-09-05 14:10:01 +02:00
Dan Fandrich
876278935f tests: fix a type warning on 32-bit x86 2023-09-04 17:10:07 -07:00
Viktor Szakats
205d686ce1
tests: delete stray .orig file
Follow-up to 331b89a319
Closes #11797
2023-09-04 22:20:16 +00:00
Stefan Eissing
331b89a319
http2: polish things around POST
- added test cases for various code paths
- fixed handling of blocked write when stream had
  been closed inbetween attempts
- re-enabled DEBUGASSERT on send with smaller data size

- in debug builds, environment variables can be set to simulate a slow
  network when sending data. cf-socket.c and vquic.c support
  * CURL_DBG_SOCK_WBLOCK: percentage of send() calls that should be
    answered with a EAGAIN. TCP/UNIX sockets.
    This is chosen randomly.
  * CURL_DBG_SOCK_WPARTIAL: percentage of data that shall be written
    to the network. TCP/UNIX sockets.
    Example: 80 means a send with 1000 bytes would only send 800
    This is applied to every send.
  * CURL_DBG_QUIC_WBLOCK: percentage of send() calls that should be
    answered with EAGAIN. QUIC only.
    This is chosen randomly.

Closes #11756
2023-09-04 19:48:49 +02:00
Dave Cottlehuber
a86fcb284f
ws: fix spelling mistakes in examples and tests
Closes #11784
2023-09-03 18:01:58 +02:00
Stefan Eissing
40f3ee0db3 wolfssl, use master again in CI
- with the shared session update fix landed in master, it
  is time to use that in our CI again
2023-09-01 11:43:55 +02:00
Viktor Szakats
ce3dce9015
tidy-up: mostly whitespace nits
- delete completed TODO from `./CMakeLists.txt`.
- convert a C++ comment to C89 in `./CMake/CurlTests.c`.
- delete duplicate EOLs from EOF.
- add missing EOL at EOF.
- delete whitespace at EOL (except from expected test results).
- convert tabs to spaces.
- convert CRLF EOLs to LF in GHA yaml.
- text casing fixes in `./CMakeLists.txt`.
- fix a codespell typo in `packages/OS400/initscript.sh`.

Closes #11772
2023-08-31 23:02:10 +00:00
Stefan Eissing
3f283e90c3 test_07_upload.py: fix test_07_34 curl args
- Pass correct filename to --data-binary.

Prior to this change --data-binary was passed an incorrect filename due
to a missing separator in the arguments list. Since aacbeae7 curl will
error on incorrect filenames for POST.

Fixes https://github.com/curl/curl/issues/11761
Closes https://github.com/curl/curl/pull/11763
2023-08-30 11:32:15 -04:00
John Bampton
fb3180a024
misc: spellfixes
Closes #11730
2023-08-25 13:21:07 +02:00
Stefan Eissing
1bccee76c8
bearssl: handshake fix, provide proper get_select_socks() implementation
- bring bearssl handshake times down from +200ms down to other TLS backends
- vtls: improve generic get_select_socks() implementation
- tests: provide Apache with a suitable ssl session cache

Closes #11675
2023-08-17 13:45:08 +02:00
Stefan Eissing
57e81ff3db
tests: TLS session sharing test
- test TLS session sharing with special test client
- expect failure with wolfSSL
- disable flaky wolfSSL test_02_07b

Closes #11675
2023-08-17 13:44:55 +02:00
Stefan Eissing
199fb4b94a
http3/ngtcp2: shorten handshake, trace cleanup
- shorten handshake timing by delayed x509 store load (OpenSSL)
  as we do for HTTP/2
- cleanup of trace output, align with HTTP/2 output

Closes #11609
2023-08-07 17:13:52 +02:00
Stefan Eissing
e12b39e133
trace: make tracing available in non-debug builds
Add --trace-config to curl

Add curl_global_trace() to libcurl

Closes #11421
2023-08-03 17:32:25 +02:00
Stefan Eissing
944e219f10
http2: upgrade tests and add fix for non-existing stream
- check in h2 filter recv that stream actually exists
  and return error if not
- add test for parallel, extreme h2 upgrades that fail if
  connections get reused before fully switched
- add h2 upgrade upload test just for completeness

Closes #11563
2023-08-03 17:05:13 +02:00
Stefan Eissing
3f518ce4b1
CI ngtcp2+quictls: use nghttpx cache as in quiche build 2023-07-27 16:59:37 +02:00
Stefan Eissing
bea86dad6e
GHA: adding quiche workflow
- adding separate quiche workflow to also build nghttpx server for testing

Closes #11517
2023-07-26 18:19:30 +02:00
Stefan Eissing
c76df46a19
http: VLH, very large header test and fixes
- adding tests using very large passwords in auth
- fixes general http sending to treat h3 like h2, and
  not like http1.1
- eliminate H2_HEADER max definitions and use the commmon
  DYN_HTTP_REQUEST everywhere, different limits do not help
- fix http2 handling of requests denied by nghttp2 on send
  to immediately report the refused stream

Closes #11509
2023-07-24 19:25:20 +02:00
Stefan Eissing
cae12480fc tests/http: Add mod_h2 directive H2ProxyRequests
master of mod_h2 now requires H2ProxyRequests directives for forward
proxying with HTTP/2 to work.

Ref: https://github.com/icing/mod_h2/commit/3897a7086

Closes https://github.com/curl/curl/pull/11392
2023-06-28 15:37:10 -04:00
Stefan Eissing
873b958d0b
http2: h2 and h2-PROXY connection alive check fixes
- fix HTTP/2 check to not declare a connection dead when
  the read attempt results in EAGAIN
- add H2-PROXY alive check as for HTTP/2 that was missing
  and is needed
- add attach/detach around Curl_conn_is_alive() and remove
  these in filter methods
- add checks for number of connections used in some test_10
  proxy tunneling tests

Closes #11368
2023-06-22 17:32:15 +02:00
Stefan Eissing
d435bf1baf
http2: error stream resets with code CURLE_HTTP2_STREAM
- refs #11357, where it was reported that HTTP/1.1 downgrades
  no longer works
- fixed with suggested change
- added test_05_03 and a new handler in the curltest module
  to reproduce that downgrades work

Fixes #11357
Closes #11362
Reported-by: Jay Satiro
2023-06-22 17:07:27 +02:00
Stefan Eissing
81e6793ec9
hyper: unslow
- refs #11203 where hyper was reported as being slow
- fixes hyper_executor_poll to loop until it is out of
  tasks as advised by @seanmonstar in https://github.com/hyperium/hyper/issues/3237
- added a fix in hyper io handling for detecting EAGAIN
- added some debug logs to see IO results
- pytest http/1.1 test cases pass
- pytest h2 test cases fail on connection reuse. HTTP/2
  connection reuse does not seem to work. Hyper submits
  a request on a reused connection, curl's IO works and
  thereafter hyper declares `Hyper: [1] operation was canceled: connection closed`
  on stderr without any error being logged before.

Fixes #11203
Reported-by: Gisle Vanem
Advised-by: Sean McArthur
Closes #11344
2023-06-20 09:11:41 +02:00
Daniel Stenberg
78886afb50
ws: make the curl_ws_meta() return pointer a const
The returned info is read-only for the user.

Closes #11261
2023-06-07 23:37:21 +02:00
Stefan Eissing
f4b5c88ab7
http2: better support for --limit-rate
- leave transfer loop when --limit-rate is in effect and has
  been received
- adjust stream window size to --limit-rate plus some slack
  to make the server observe the pacing we want
- add test case to confirm behaviour

Closes #11115
2023-06-02 23:06:12 +02:00
Stefan Eissing
5c58cb0212
http2: fix EOF handling on uploads with auth negotiation
- doing a POST with `--digest` does an override on the initial request
  with `Content-Length: 0`, but the http2 filter was unaware of that
  and expected the originally request body. It did therefore not
  send a final DATA frame with EOF flag to the server.
- The fix overrides any initial notion of post size when the `done_send`
  event is triggered by the transfer loop, leading to the EOF that
  is necessary.
- refs #11194. The fault did not happen in testing, as Apache httpd
  never tries to read the request body of the initial request,
  sends the 401 reply and closes the stream. The server used in the
  reported issue however tried to read the EOF and timed out on the
  request.

Reported-by: Aleksander Mazur
Fixes #11194
Cloes #11200
2023-05-25 08:26:18 +02:00
Stefan Eissing
88332049ea
http/2: unstick uploads
- refs #11157 and #11175 where uploads get stuck or lead to RST streams
- fixes our h2 send behaviour to continue sending in the nghttp2 session
  as long as it wants to. This will empty our send buffer as long as
  the remote stream/connection window allows.
- in case the window is exhausted, the data remaining in the send buffer
  will wait for a WINDOW_UPDATE from the server. Which is a socket event
  that engages our transfer loop again
- the problem in the issue was that we did not exhaust the window, but
  left data in the sendbuffer and no further socket events did happen.
  The server was just waiting for us to send more.
- relatedly, there was an issue fixed that closing a stream with KEEP_HOLD
  set kept the transfer from shutting down - as it should have - leading
  to a timeout.

Closes #11176
2023-05-22 16:19:13 +02:00
Stefan Eissing
0cab1359a1
http2: upload improvements
Make send buffer smaller to have progress and "upload done" reporting
closer to reality. Fix handling of send "drain" condition to no longer
trigger once the transfer loop reports it is done sending. Also do not
trigger the send "drain" on RST streams.

Background:
- a upload stall was reported in #11157 that timed out
- test_07_33a reproduces a problem with such a stall if the
  server 404s the request and RSTs the stream.
- test_07_33b verifies a successful PUT, using the parameters
  from #11157 and checks success

Ref: #11157
Closes #11165
2023-05-20 23:07:45 +02:00
Stefan Eissing
408eb87bb3
cf-socket: completely remove the disabled USE_RECV_BEFORE_SEND_WORKAROUND
Closes #11118
2023-05-18 20:55:16 +02:00
Stefan Eissing
a9b7f72bc9
http2: do flow window accounting for cancelled streams
- nghttp2 does not free connection level window flow for
  aborted streams
- when closing transfers, make sure that any buffered
  response data is "given back" to the flow control window
- add tests test_02_22 and test_02_23 to reproduce

Closes #11052
2023-04-28 13:55:39 +02:00
Marcel Raad
da2470de96
tests/http: make curl_setup.h the first include
This is required for the macros there to take effect for system
libraries. Specifically, including the system libraries first led to
warnings about `_FILE_OFFSET_BITS` being redefined in curl_config.h on
the Solaris autobuilds for ws-data.c and ws-pingpong.c.
Also make the curl includes come first for the other source files here
for consistency.

Closes https://github.com/curl/curl/pull/11046
2023-04-28 11:29:19 +02:00
Dan Fandrich
2572e1333e tests/http: fix out-of-tree builds
Add both lib/ directories (src & build) to the search path so
curl_setup.h and its dependencies can be found.

Followup-to acd82c8b

Ref: #11006
Closes #11036
2023-04-27 00:15:41 -07:00
Stefan Eissing
acd82c8bfd
tests/http: more tests with specific clients
- Makefile support for building test specific clients in tests/http/clients
- auto-make of clients when invoking pytest
- added test_09_02 for server PUSH_PROMISEs using clients/h2-serverpush
- added test_02_21 for lib based downloads and pausing/unpausing transfers

curl url parser:
- added internal method `curl_url_set_authority()` for setting the
  authority part of a url (used for PUSH_PROMISE)

http2:
- made logging of PUSH_PROMISE handling nicer

Placing python test requirements in requirements.txt files
- separate files to base test suite and http tests since use
  and module lists differ
- using the files in the gh workflows

websocket test cases, fixes for we and bufq
- bufq: account for spare chunks in space calculation
- bufq: reset chunks that are skipped empty
- ws: correctly encode frames with 126 bytes payload
- ws: update frame meta information on first call of collect
  callback that fills user buffer
- test client ws-data: some test/reporting improvements

Closes #11006
2023-04-26 23:24:46 +02:00
Stefan Eissing
cab2d56ea5
h2/h3: replace state.drain counter with state.dselect_bits
- `drain` was used by http/2 and http/3 implementations to indicate
  that the transfer requires send/recv independant from its socket
  poll state. Intended as a counter, it was used as bool flag only.
- a similar mechanism exists on `connectdata->cselect_bits` where
  specific protocols can indicate something similar, only for the
  whole connection.
- `cselect_bits` are cleard in transfer.c on use and, importantly,
  also set when the transfer loop expended its `maxloops` tries.
  `drain` was not cleared by transfer and the http2/3 implementations
  had to take care of that.
- `dselect_bits` is cleared *and* set by the transfer loop. http2/3
  does no longer clear it, only set when new events happen.

This change unifies the handling of socket poll overrides, extending
`cselect_bits` by a easy handle specific value and a common treatment in
transfers.

Closes #11005
2023-04-25 17:49:28 +02:00
Stefan Eissing
fc2f1e547a
http2: support HTTP/2 to forward proxies, non-tunneling
- with `--proxy-http2` allow h2 ALPN negotiation to
  forward proxies
- applies to http: requests against a https: proxy only,
  as https: requests will auto-tunnel
- adding a HTTP/1 request parser in http1.c
- removed h2h3.c
- using new request parser in nghttp2 and all h3 backends
- adding test 2603 for request parser
- adding h2 proxy test cases to test_10_*

scorecard.py: request scoring accidentally always run curl
with '-v'. Removed that, expect double numbers.

labeller: added http1.* and h2-proxy sources to detection

Closes #10967
2023-04-17 17:27:49 +02:00
Stefan Eissing
5126cbda00
tests: make test_12_01 a bit more forgiving on connection counts 2023-04-13 08:46:53 +02:00
Stefan Eissing
4ae2d9f24d
proxy: http2 proxy tunnel implementation
- currently only on debug build and when env variable
  CURL_PROXY_TUNNEL_H2 is present.
- will ALPN negotiate with the proxy server and switch
  tunnel filter based on the protocol negotiated.
- http/1.1 tunnel code moved into cf-h1-proxy.[ch]
- http/2 tunnel code implemented in cf-h2-proxy.[ch]
- tunnel start and ALPN set remains in http_proxy.c
- moving all haproxy related code into cf-haproxy.[ch]

VTLS changes
- SSL filters rely solely on the "alpn" specification they
  are created with and no longer check conn->bits.tls_enable_alpn.
- checks on which ALPN specification to use (or none at all) are
  done in vtls.c when creating the filter.

Testing
- added a nghttpx forward proxy to the pytest setup that
  speaks HTTP/2 and forwards all requests to the Apache httpd
  forward proxy server.
- extending test coverage in test_10 cases
- adding proxy tests for direct/tunnel h1/h2 use of basic auth.
- adding test for http/1.1 and h2 proxy tunneling to pytest

Closes #10780
2023-04-06 13:04:46 +02:00
Stefan Eissing
8f50e393ab
vtls and h2 improvements
- eliminate receive loop in vtls to fill buffer. This may
  lead to partial reads of data which is counter productive
- let http2 instead loop smarter to process pending network
  data without transfer switches

scorecard improvements
- do not start caddy when only httpd is requested
- allow curl -v to stderr file on --curl-verbose

Closes #10891
2023-04-06 09:41:54 +02:00
Stefan Eissing
e0c3424fb1
tests/http: improved httpd detection
- better error messages when not found/complete
- handling of `--without-test-httpd`

Reported-by: kwind on github
Fixes #10879
Closes #10883
2023-04-04 14:37:08 +02:00
Stefan Eissing
3797f1a4ca
rustls: fix error in recv handling
- when rustls is told to recieve more TLS data and its internal
  plaintext buffers are full, it returns an IOERROR
- avoid receiving TLS data while plaintext is not read empty

pytest:
- increase curl run timeout when invoking pytest with higher verbosity

Closes #10876
2023-03-31 16:05:15 +02:00
Stefan Eissing
544abeea83
http3: improvements across backends
- ngtcp2: using bufq for recv stream data
- internal stream_ctx instead of `struct HTTP` members
  for quiche, ngtcp2 and msh3
- no more QUIC related members in `struct HTTP`
- experimental use of recvmmsg(), disabled by default
  - testing on my old debian box shows no throughput improvements.
  - leaving it in, but disabled, for future revisit
- vquic: common UDP receive code for ngtcp2 and quiche
- vquic: common UDP send code for ngtcp2 and quiche
- added pytest skips for known msh3 failures
- fix unit2601 to survive torture testing
- quiche: using latest `master` from quiche and enabling large download
  tests, now that key change is supported
- fixing test_07_21 where retry handling of starting a stream
  was faulty
- msh3: use bufq for recv buffering headers and data
- msh3: replace fprintf debug logging with LOG_CF where possible
- msh3: force QUIC expire timers on recv/send to have more than
  1 request per second served

Closes #10772
2023-03-31 15:44:57 +02:00
Stefan Eissing
041cf77cbd
tests/http: relax connection check in test_07_02
Only 1 connection will be used when curl is slow, happens when
address-sanitized in CI, for example

Closes #10865
2023-03-30 23:51:16 +02:00
Stefan Eissing
744dcf22fa
http2: flow control and buffer improvements
- use bufq for send/receive of network data
- usd bufq for send/receive of stream data
- use HTTP/2 flow control with no-auto updates to control the
  amount of data we are buffering for a stream
  HTTP/2 stream window set to 128K after local tests, defined
  code constant for now
- elminiating PAUSEing nghttp2 processing when receiving data
  since a stream can now take in all DATA nghttp2 forwards

Improved scorecard and adjuste http2 stream window sizes
- scorecard improved output formatting and options default
- scorecard now also benchmarks small requests / second

Closes #10771
2023-03-30 23:11:26 +02:00
Stefan Eissing
f8f010e469
tests/http: fix log formatting on wrong exit code
Closes #10868
2023-03-30 13:09:12 +02:00
Stefan Eissing
8cabef6fc3
pytest: improvements for suitable curl and error output
- will check built curl for http and https support and
  skip all tests if not there
- will dump stdout/stderr/trace output on errored responses

Closes #10829
2023-03-29 13:25:18 +02:00