Stefan Eissing [Thu, 29 Feb 2024 09:12:39 +0000 (10:12 +0100)]
mime: add client reader
Add `mime` client reader. Encapsulates reading from mime parts, getting
their length, rewinding and unpausing.
- remove special mime handling from sendf.c and easy.c
- add general "unpause" method to client readers
- use new reader in http/imap/smtp
- make some mime functions static that are now only used internally
In addition:
- remove flag 'forbidchunk' as no longer needed
Stefan Eissing [Tue, 5 Mar 2024 10:48:16 +0000 (11:48 +0100)]
TIMER_STARTTRANSFER: set the same for everyone
- set TIMER_STARTTRANSFER on seeing the first response bytes
in the download client writer, not coming from a CONNECT
- initialized the timer the same way for all protocols
- remove explicit setting of TIMER_STARTTRANSFER in file.c
and c-hyper.c
http: better error message for HTTP/1.x response without status line
If a response without a status line is received, and the connection is
known to use HTTP/1.x (not HTTP/0.9), report the error "Invalid status
line" instead of "Received HTTP/0.9 when not allowed".
In cases where the connection was fast, curl sometimes failed to open a
connection. This fixes a regression of c2d973627bab12abc5486a3f3.
The regression triggered in these steps:
1. Create an smtp connection
2. Use STARTTLS
3. Receive the response
4. We are inside the loop in `smtp_statemachine`, calling
`smtp_state_starttls_resp`
5. In the good flow, we exit the loop, re-enter `smtp_statemachine` and
run `smtp_perform_upgrade_tls` at the start of the function.
In the bad flow, we stay in the while loop, calling
`Curl_pp_readresp`, which reads part of the TLS handshake and things
go wrong.
The reason is that `Curl_pp_moredata` changed behavior and always
returns `true`, so we stay in the loop in `smtp_statemachine`. With a
slow connection `Curl_pp_readresp` cannot read new data and returns
`CURL_AGAIN`, so we leave the loop and re-enter `smtp_statemachine`.
With a fast connection, `Curl_pp_readresp` reads new data from the tcp
connection, which is part of the TLS handshake.
The fix is in `Curl_pp_moredata`, which needs to take the final line
into account and return `false` if only the final line is stored.
Stefan Eissing [Thu, 29 Feb 2024 09:12:39 +0000 (10:12 +0100)]
lib: enhance client reader resume + rewind
- update client reader documentation
- client reader, add rewind capabilities
- tell creader to rewind on next start
- Curl_client_reset() will keep reader for future rewind if requested
- add Curl_client_cleanup() for freeing all resources independent of
rewinds
- add Curl_client_start() to trigger rewinds
- move rewind code from multi.c to sendf.c and make part of
"cr-in"'s implementation
- http, move the "resume_from" handling into the client readers
- the setup of a HTTP request is reshuffled to follow:
* determine method, target, auth negotiation
* install the client reader(s) for the request, including crlf
conversions and "chunked" encoding
* apply ranges to client reader
* concat request headers, upgrades, cookies, etc.
* complete request by determining Content-Length of installed
readers in combination with method
* send
- add methods for client readers to
* return the overall length they will generate (or -1 when unknown)
* return the amount of data on the CLIENT level, so that
expect-100 can decide if it want to apply itself
* set a "resume_from" offset or fail if unsupported
- struct HTTP has become largely empty now
- rename `Client_reader_*` to `Curl_creader_*`
Daniel Stenberg [Mon, 4 Mar 2024 14:16:11 +0000 (15:16 +0100)]
gen.pl: make the "manpageification" faster
The function that replaces occurances of "--longoption" with "-Z,
--longoption" etc with the proper highlight applied, no longer loops
over the options.
Daniel Stenberg [Sun, 3 Mar 2024 17:41:52 +0000 (18:41 +0100)]
cookie: if psl fails, reject the cookie
A libpsl install without data and no built-in database is now considered
bad enough to reject all cookies since they cannot be checked. It is
somewhat of a user error, but still.
Stefan Eissing [Fri, 1 Mar 2024 08:12:50 +0000 (09:12 +0100)]
bufq: writing into a softlimit queue cannot be partial
- when unable to obtain a new chunk on a softlimit bufq,
this is an allocation error and needs to be reported as
such.
- writes into a soflimit bufq never must be partial success
Reported-by: Dan Fandrich
Fixes #13020
Closes #13023
Dan Fandrich [Sat, 2 Mar 2024 02:27:35 +0000 (18:27 -0800)]
configure: Don't build shell completions when disabled
With the recent changes to completion file building, the files were
built always and only installation was selectively disabled. Now, when
they are disabled they aren't even built, avoiding a build-time error in
environments where it's not possible to run the curl binary that was
just created (e.g. if library paths were not set up correctly).
Dan Fandrich [Fri, 1 Mar 2024 07:38:22 +0000 (23:38 -0800)]
configure: Don't make shell completions without perl
The code that attempted to skip building the shell completions didn't
work properly and tried to build them even if perl wasn't available.
This step, as well as the install step, is now properly skipped without
perl.
Dan Fandrich [Thu, 8 Feb 2024 19:34:34 +0000 (11:34 -0800)]
configure: build & install shell completions when enabled
The --with-fish-functions-dir and --with-zsh-functions-dir options
currently have no effect on a normal build because the scripts/ directory
where they're used is not built. Add scripts/ to a normal build and
change the completion options to default to off to preserve the existing
behaviour.
Stefan Eissing [Thu, 15 Feb 2024 15:22:53 +0000 (16:22 +0100)]
lib: Curl_read/Curl_write clarifications
- replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to
clarify when and at what level they operate
- send/recv of transfer related data is now done via
`Curl_xfer_send()/Curl_xfer_recv()` which no longer has
socket/socketindex as parameter. It decides on the transfer
setup of `conn->sockfd` and `conn->writesockfd` on which
connection filter chain to operate.
- send/recv on a specific connection filter chain is done via
`Curl_conn_send()/Curl_conn_recv()` which get the socket index
as parameter.
- rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for
naming consistency
- clarify that the special CURLE_AGAIN hangling to return
`CURLE_OK` with length 0 only applies to `Curl_xfer_send()`
and CURLE_AGAIN is returned by all other send() variants.
- fix a bug in websocket `curl_ws_recv()` that mixed up data
when it arrived in more than a single chunk (to be made
into a sperate PR, also)
- old `Curl_buffer_send()` completely replaced by new `Curl_req_send()`
- old `Curl_fillreadbuffer()` replaced with `Curl_client_read()`
- HTTP chunked uploads are now formatted in a client reader added when
needed.
- FTP line-end conversions are done in a client reader added when
needed.
- when sending requests headers, remaining buffer space is filled with
body data for sending in "one go". This is independent of the request
body size. Resolves #12938 as now small and large requests have the
same code path.
Changes done to test cases:
- test513: now fails before sending request headers as this initial
"client read" triggers the setup fault. Behaves now the same as in
hyper build
- test547, test555, test1620: fix the length check in the lib code to
only fail for reads *smaller* than expected. This was a bug in the
test code that never triggered in the old implementation.
The curldown conversion accidentally replaced daniel@haxx.se with
just daniel.se. This reverts back to the proper email address in
the curldown docs as well as in a few other stray places where it
was incorrect (while unrelated to curldown).
Reviewed-by: Daniel Stenberg <daniel@haxx.se> Closes: #12997
When disabling all protocols without enabling any, the resulting
set of allowed protocols remained the default set. Clearing the
allowed set before inspecting the passed value from --proto make
the set empty even in the errorpath of no protocols enabled.
Co-authored-by: Dan Fandrich <dan@telarity.com> Reported-by: Dan Fandrich <dan@telarity.com> Reviewed-by: Daniel Stenberg <daniel@haxx.se> Closes: #13004
When building for 32-bit ARM or x86 Android, `st_mode` is defined as
`unsigned int` instead of `mode_t`, resulting in a
`-Wimplicit-int-conversion` clang warning because `mode_t` is
`unsigned short`. Add a cast to silence the warning, but only for
32-bit Android builds, because other architectures and platforms are
not affected.
Stefan Eissing [Thu, 15 Feb 2024 15:22:53 +0000 (16:22 +0100)]
lib: Curl_read/Curl_write clarifications
- replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to
clarify when and at what level they operate
- send/recv of transfer related data is now done via
`Curl_xfer_send()/Curl_xfer_recv()` which no longer has
socket/socketindex as parameter. It decides on the transfer
setup of `conn->sockfd` and `conn->writesockfd` on which
connection filter chain to operate.
- send/recv on a specific connection filter chain is done via
`Curl_conn_send()/Curl_conn_recv()` which get the socket index
as parameter.
- rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for
naming consistency
- clarify that the special CURLE_AGAIN hangling to return
`CURLE_OK` with length 0 only applies to `Curl_xfer_send()`
and CURLE_AGAIN is returned by all other send() variants.
- fix a bug in websocket `curl_ws_recv()` that mixed up data
when it arrived in more than a single chunk
The method for sending not just raw bytes, but bytes that are either
"headers" or "body". The send abstraction stack, to to bottom, now is:
* `Curl_req_send()`: has parameter to indicate amount of header bytes,
buffers all data.
* `Curl_xfer_send()`: knows on which socket index to send, returns
amount of bytes sent.
* `Curl_conn_send()`: called with socket index, returns amount of bytes
sent.
In addition there is `Curl_req_flush()` for writing out all buffered
bytes.
`Curl_req_send()` is active for requests without body,
`Curl_buffer_send()` still being used for others. This is because the
special quirks need to be addressed in future parts:
* `expect-100` handling
* `Curl_fillreadbuffer()` needs to add directly to the new
`data->req.sendbuf`
* special body handlings, like `chunked` encodings and line end
conversions will be moved into something like a Client Reader.
In functions of the pattern `CURLcode xxx_send(..., ssize_t *written)`,
replace the `ssize_t` with a `size_t`. It makes no sense to allow for negative
values as the returned `CURLcode` already specifies error conditions. This
allows easier handling of lengths without casting.
Daniel Stenberg [Mon, 26 Feb 2024 08:50:49 +0000 (09:50 +0100)]
multi: make add_handle free any multi_easy
If the easy handle that is being added to a multi handle has previously
been used for curl_easy_perform(), there is a private multi handle here
that we can kill off. While it flushes some caches etc for the easy
handle would it be used for an easy interface transfer again after being
used in the multi stack, this cleanup simplifies behavior and uses less
memory.
Stefan Eissing [Wed, 14 Feb 2024 11:09:32 +0000 (12:09 +0100)]
lib: send rework
Curl_read/Curl_write clarifications
- replace `Curl_read()`, `Curl_write()` and `Curl_nwrite()` to 1clarify
when and at what level they operate
- send/recv of transfer related data is now done via
`Curl_xfer_send()/Curl_xfer_recv()` which no longer has
socket/socketindex as parameter. It decides on the transfer setup of
`conn->sockfd` and `conn->writesockfd` on which connection filter
chain to operate.
- send/recv on a specific connection filter chain is done via
`Curl_conn_send()/Curl_conn_recv()` which get the socket index as
parameter.
- rename `Curl_setup_transfer()` to `Curl_xfer_setup()` for naming
consistency
- clarify that the special CURLE_AGAIN handling to return `CURLE_OK`
with length 0 only applies to `Curl_xfer_send()` and CURLE_AGAIN is
returned by all other send() variants.
SingleRequest reshuffling
- move functions into request.[ch]
- differentiate between reset and free
- add Curl_req_done() to perform last actions
- add a send `bufq` to SingleRequest for future use in keeping upload data
Stefan Eissing [Wed, 7 Feb 2024 11:05:05 +0000 (12:05 +0100)]
lib: move client writer into own source
Refactoring of the client writer that passes the data to the
client/application's callback functions.
- split out into own source cw-out.[ch] from sendf.c
- move tempwrite and tempcount from data->state into the context of the
client writer
- redesign the 3 tempwrite dynbufs as a linked list of dynbufs. On
paused transfers, this allows to "record" interleaved HEADER/BODY
chunks to be "played back" in the same order on unpausing.
- keep the overall size limit of all buffered data to DYN_PAUSE_BUFFER.
On exceeding that, return CURLE_TOO_LARGE instead of
CURLE_OUT_OF_MEMORY as before.
- add method to be called when a transfer is DONE to allow writing of
any data still buffered
- when paused, record HEADER writes exactly as they come for later
playback. HEADERs are documented to be written one-by-one.
Stefan Eissing [Fri, 16 Feb 2024 11:15:10 +0000 (12:15 +0100)]
urldata: move authneg bit from conn to Curl_easy
- from `conn->bits.authneg` to `data->req.authneg`
- this is a property of the request about to be made
and not a property of the connection
- in multiuse connections, transfer could step on each others
toes here potentially.
Stefan Eissing [Tue, 6 Feb 2024 12:55:07 +0000 (13:55 +0100)]
http: move headers collecting to writer
- add a client writer that does "push" response
headers written to the client if the headers api
is enabled
- remove special handling in sendf.c
- needs to be installed very early on connection
setup to catch CONNECT response headers
MAntoniak [Fri, 9 Feb 2024 17:20:47 +0000 (18:20 +0100)]
lib: remove curl_mimepart object when CURL_DISABLE_MIME
Remove curl_mimepart object from UserDefined structure when
CURL_DISABLE_MIME flag is active. Reduce size of UserDefined structure.
Also remove unreachable code: when CURL_DISABLE_MIME is set, httpreq can
never have HTTPREQ_POST_MIME value and the same goes for the
CURL_DISABLE_FORM_API flag and the HTTPREQ_POST_FORM value
Daniel Stenberg [Sun, 25 Feb 2024 21:52:40 +0000 (22:52 +0100)]
strtoofft: fix the overflow check
... to not rely on wrapping, since it is an undefined behavior that is
not what always might happen. This is in our private strtoff() parser
function, used only on platforms without a native version.
Reported-by: vulnerabilityspotter on hackerone
Closes #12990
Scott Talbert [Sat, 24 Feb 2024 03:02:09 +0000 (22:02 -0500)]
setopt: fix check for CURLOPT_PROXY_TLSAUTH_TYPE value
Prior to this change CURLOPT_PROXY_TLSAUTH_TYPE would return
CURLE_BAD_FUNCTION_ARGUMENT on any type other than NULL. Since there is
only one type of TLS auth and it is also the default (SRP) the TLS auth
would work anyway.
Jay Satiro [Fri, 16 Feb 2024 21:02:19 +0000 (16:02 -0500)]
mprintf: fix format prefix I32/I64 for windows compilers
- Support I32 & I64 (eg: %I64d) for all Win32 builds.
Prior to this change mprintf support for the I format prefix, which is a
Microsoft extension, was dependent on the compiler used.
When Borland compiler support was removed in fd7ef00f the prefix was
then no longer supported for that compiler; however since it's still
possible to build with Borland I'm restoring support for the prefix in
this way.
Stefan Eissing [Mon, 27 Nov 2023 10:30:25 +0000 (11:30 +0100)]
DoH: add trace configuration
- refs #12397 where it is dicussed how to en-/disable verbose output
of DoH operations
- introducing `struct curl_trc_feat` to track a curl feature for
tracing
- adding `data->state.feat` optionally pointing to the feature a
transfer belongs to
- adding trace functions and verbosity checks on features
- using trace feature in DoH code
- documenting `doh` as feature for `--trace-config`
Evgeny Grin [Thu, 8 Feb 2024 09:31:12 +0000 (10:31 +0100)]
digest: support SHA-512/256
Also fix the tests. New implementation tested with GNU libmicrohttpd.
The new numbers in tests are real SHA-512/256 numbers (not just some
random ;) numbers ).
Stefan Eissing [Tue, 13 Feb 2024 12:59:03 +0000 (13:59 +0100)]
OpenSSL QUIC: adapt to v3.3.x
- set our idle timeout as transport parameter
- query negotiated idle timeout for connection alive checks
- query number of available bidi streams on a connection
- use write_ex2 with SSL_WRITE_FLAG_CONCLUDE to signal
EOF on last chunk write, so stream close does not
require an additional QUIC packet
Stefan Eissing [Wed, 14 Feb 2024 15:27:23 +0000 (16:27 +0100)]
http_chunks: fix the accounting of consumed bytes
Prior to this change chunks were handled correctly although in verbose
mode libcurl could incorrectly warn of "Leftovers after chunking" even
if there were none.
Reported-by: Michael Kaufmann
Fixes https://github.com/curl/curl/issues/12937
Closes https://github.com/curl/curl/pull/12939
Stefan Eissing [Tue, 13 Feb 2024 10:39:06 +0000 (11:39 +0100)]
file: use xfer buf for file:// transfers
- For file:// transfers use the multi handle's transfer buffer for
up- and downloads.
Prior to this change a6c9a33 (precedes 8.6.0) changed the file://
transfers to use a smaller stack based buffer, and that caused a
significant performance decrease in Windows.
Evgeny Grin [Sun, 18 Feb 2024 06:36:27 +0000 (11:36 +0500)]
checksrc.pl: fix handling .checksrc with CRLF
- When parsing .checksrc chomp the (CR)LF line ending.
Prior to this change on Windows checksrc.pl would not process the
symbols in .checksrc properly, since many git repos in Windows use auto
crlf to check out files with CRLF line endings.