Commit Graph

1037 Commits

Author SHA1 Message Date
Daniel Stenberg
4ff04615a0
lib: use FMT_ as prefix instead of CURL_FORMAT_
For printf format defines used internally. Makes the code slighly
easier to read.

Closes #14764
2024-09-03 08:45:45 +02:00
Stefan Eissing
00ef607326
url: fix connection reuse for HTTP/2 upgrades
Normally, when a connection's filters have all connected, the
multiplex status is determined. However, HTTP/2 Upgrade:
requests will only do this when the first server response
has been received.

The current connection reuse mechanism does not accomodate
that and when the time between connect and response is large
enough, connection reuse may not happen as desired.

See test case 2405 failures, such as in
https://github.com/curl/curl/actions/runs/10629497461/job/29467166451

Add 'conn->bits.asks_multiplex' as indicator that a connection is
still being evaluated for mulitplexing, so that new transfers
may wait on this to be cleared.

Closes #14739
2024-09-02 12:39:03 +02:00
Stefan Eissing
29610e5f3d
transfer: skip EOS read when download done
When we downloaded all we wanted, and we did not want a response body,
and no Trailer: has been announced, and the receive gives EAGAIN, do not
hang around unnecessarily.

Some servers are buggy in HEAD processing and fail to send the HTTP/2
EOS. Since we do not need any more data, end the request right there.
This will cause us to send a RST_STREAM to the server.

Fixes #14670
Reported-by: Gruber Glass
Closes #14685
2024-08-28 13:54:38 +02:00
Stefan Eissing
1be704e17e
cpool: rename "connection cache/conncache" to "Connection Pools/cpool"
This is a better match for what they do and the general "cpool"
var/function prefix works well.

The pool now handles very long hostnames correctly.

The following changes have been made:

* 'struct connectdata', e.g. connections, keep new members
  named `destination` and ' destination_len' that fully specifies
  interface+port+hostname of where the connection is going to.
  This is used in the pool for "bundling" of connections with
  the same destination. There is no limit on the length any more.
* Locking: all locks are done inside conncache.c when calling
  into the pool and released on return. This eliminates hazards
  of the callers keeping track.
* 'struct connectbundle' is now internal to the pool. It is no
  longer referenced by a connection.
* 'bundle->multiuse' no longer exists. HTTP/2 and 3 and TLS filters
  no longer need to set it. Instead, the multi checks on leaving
  MSTATE_CONNECT or MSTATE_CONNECTING if the connection is now
  multiplexed and new, e.g. not conn->bits.reuse. In that case
  the processing of pending handles is triggered.
* The pool's init is provided with a callback to invoke on all
  connections being discarded. This allows the cleanups in
  `Curl_disconnect` to run, wherever it is decided to retire
  a connection.
* Several pool operations can now be fully done with one call.
  Pruning dead connections, upkeep and checks on pool limits
  can now directly discard connections and need no longer return
  those to the caller for doing that (as we have now the callback
  described above).
* Finding a connection for reuse is now done via `Curl_cpool_find()`
  and the caller provides callbacks to evaluate the connection
  candidates.
* The 'Curl_cpool_check_limits()' now directly uses the max values
  that may be set in the transfer's multi. No need to pass them
  around. Curl_multi_max_host_connections() and
  Curl_multi_max_total_connections() are gone.
* Add method 'Curl_node_llist()' to get the llist a node is in.
  Used in cpool to verify connection are indeed in the list (or
  not in any list) as they need to.

I left the conncache.[ch] as is for now and also did not touch the
documentation. If we update that outside the feature window, we can
do this in a separate PR.

Multi-thread safety is not achieved by this PR, but since more details
on how pools operate are now "internal" it is a better starting
point to go for this in the future.

Closes #14662
2024-08-28 13:52:49 +02:00
Viktor Szakats
42843af0b8
tidy-up: spelling WebSockets
Closes #14646
2024-08-22 17:43:57 +02:00
Stefan Eissing
a58b50fca6
transfer: Curl_sendrecv() and event related improvements
- Renames Curl_readwrite() to Curl_sendrecv() to reflect that it
  is mainly about talking to the server, not reads or writes to the
  client. Add a `nowp` parameter since the single caller already
  has this.
- Curl_sendrecv() now runs all possible operations whenever it is
  called and either it had been polling sockets or the 'select_bits'
  are set.
  POLL_IN/POLL_OUT are not always directly related to send/recv
  operations. Filters like HTTP/2, QUIC or TLS may monitor reverse
  directions. If a transfer does not want to send (KEEP_SEND), it
  will not do so, as before. Same for receives.
- Curl_update_timer() now checks the absolute timestamp of an expiry
  and the last/new timeout to determine if the application needs
  to stop/start/restart its timer. This fixes edge cases where
  updates did not happen as they should have.
- improved --test-event curl_easy_perform() simulation to handle
  situations where no sockets are registered but a timeout is
  in place.
- fixed bug in events_socket() that complained about removing
  a socket that was unknown, when indeed it had removed the socket
  just before, only it was the last in the list
- fixed conncache's internal handle to carry the multi instance
  (where the cache has one) so that operations on the closure handle
  trigger event callbacks correctly.
- fixed conncache to not POLL_REMOVE a socket twice when a conneciton
  was closed.

Closes #14561
2024-08-17 10:52:53 +02:00
Daniel Stenberg
ba235ab269
llist: remove direct struct accesses, use only functions
- Turned them all into functions to also do asserts etc.

- The llist related structs got all their fields renamed in order to make
  sure no existing code remains using direct access.

- Each list node struct now points back to the list it "lives in", so
  Curl_node_remove() no longer needs the list pointer.

- Rename the node struct and some of the access functions.

- Added lots of ASSERTs to verify API being used correctly

- Fix some cases of API misuse

Add docs/LLIST.md documenting the internal linked list API.

Closes #14485
2024-08-12 13:18:10 +02:00
Stefan Eissing
709a6a3965
cfilters: send flush
Since data can be held in connection filter buffers when sending gives
EAGAIN, add methods to query this and perform flushing of those buffers.

The transfer loop will continue sending until all upload data is
processed and the connection is flushed.

- add `CF_QUERY_SEND_PENDING` to query filters
- add `CF_CTRL_DATA_SEND_FLUSH` to flush filters
- change `Curl_req_want_send()` to query the connection
  if it needs flushing
- use `Curl_req_want_send()` to determine the POLLOUT
  in the PERFORMING multi state
- implement flush handling in the HTTP/2 connection filter

Closes #14271
2024-08-03 19:55:45 +02:00
Daniel Stenberg
c074ba64a8
code: language cleanup in comments
Based on the standards and guidelines we use for our documentation.

 - expand contractions (they're => they are etc)
 - host name = > hostname
 - file name => filename
 - user name = username
 - man page => manpage
 - run-time => runtime
 - set-up => setup
 - back-end => backend
 - a HTTP => an HTTP
 - Two spaces after a period => one space after period

Closes #14073
2024-07-01 22:58:55 +02:00
Stefan Eissing
3841569ec8
transfer: do not use EXPIRE_NOW while blocked
- When a transfer sets `data->state.select_bits`, it is
  scheduled for rerun with EXPIRE_NOW. If such a transfer
  is blocked (due to PAUSE, for example), this will lead to
  a busy loop.
- multi.c: check for transfer block
- sendf.*: add Curl_xfer_is_blocked()
- sendf.*: add client reader `is_paused()` callback
- implement is_paused()` callback where needed

Closes #13908
2024-06-13 15:13:43 +02:00
Daniel Stenberg
7208ff6534
http: remove "struct HTTP"
It is not actually used anymore and only contained a dummy struct field.
Remove all traces and uses of it.

Closes #13927
2024-06-12 16:04:53 +02:00
Stefan Eissing
385c62aabc
lib: xfer_setup and non-blocking shutdown
- clarify Curl_xfer_setup() with RECV/SEND flags and different calls for
  which socket they operate on. Add a shutdown flag for secondary
  sockets
- change Curl_xfer_setup() calls to new functions
- implement non-blocking connection shutdown at the end of receiving or
  sending a transfer

Closes #13913
2024-06-11 13:41:03 +02:00
Viktor Szakats
59dc9f7e69
build: untangle CURLDEBUG and DEBUGBUILD macros
`CURLDEBUG` is meant to enable memory tracking, but in a bunch of cases,
it was protecting debug features that were supposed to be guarded with
`DEBUGBUILD`.

Replace these uses with `DEBUGBUILD`.

This leaves `CURLDEBUG` uses solely for its intended  purpose: to enable
the memory tracking debug feature.

Also:
- autotools: rely on `DEBUGBUILD` to enable `checksrc`.
  Instead of `CURLDEBUG`, which worked in most cases because debug
  builds enable `CURLDEBUG` by default, but it's not accurate.
- include `lib/easyif.h` instead of keeping a copy of a declaration.
- add CI test jobs for the build issues discovered.

Ref: https://github.com/curl/curl/pull/13694#issuecomment-2120311894
Closes #13718
2024-05-28 08:12:00 +02:00
Stefan Eissing
17af2bca58
http: write last header line late
- HEADERFUNCTIONS might inspect response properties like
  CURLINFO_CONTENT_LENGTH_DOWNLOAD_T on seeing the last header line. If
  the line is being written before this is initialized, values are not
  available.

- write the last header line late when analyzing a HTTP response so that
  all information is available at the time of the writing.

- add test1485 to verify that CURLINFO_CONTENT_LENGTH_DOWNLOAD_T works
  on seeing the last header.

Fixes #13752
Reported-by: Harry Sintonen
Closes #13757
2024-05-25 23:42:53 +02:00
Stefan Eissing
5a4769b6d5
http: HEAD response body tolerance
- as reported in #13725, some servers wrongly send body bytes in
  responses to a HEAD request. This used to be tolerated in curl
  8.4 and before and leads to failed transfers in newer versions.
- restore previous behaviour for HTTP/1.1 and HTTP/2:
  * 1.1: do not add 'Transfer-Encoding' writers from HEAD
    responses. RFC 9112 says they do not apply.
  * 2: when the transfer expects 'no_body', to not report stream
    resets as error when all response headers have been received.

Reported-by: Jeroen Ooms
Fixes #13725
Closes #13732
2024-05-21 14:51:11 +02:00
Daniel Stenberg
7b5bacdd0a
http: remove redundant check
Spotted by CodeSonar

Closes #13582
2024-05-10 23:37:09 +02:00
Daniel Stenberg
c294f9cb56
lib: make protocol handlers store scheme name lowercase
- saves a lowercase operation when the "[scheme]_proxy" name is
  generated
- appears less "shouting"
- update test 970, 972, 1438 and 1536

Closes #13553
2024-05-08 09:39:30 +02:00
Daniel Stenberg
727c946d82
http: acknowledge a returned error code
... and do not overwrite it with a new value that could then hide the
problem.

Spotted by CodeSonar

Closes #13434
2024-04-21 10:49:48 +02:00
Daniel Stenberg
a032e97f2b
http: reject HTTP major version switch mid connection
A connection that has seen an HTTP major version now refuses any other
major HTTP version in future responses. Previously, a HTTP/1.x
connection would just silently accept HTTP/2 or HTTP/3 in the status
lines as long as it had support for those built-in. It would then just
lead to confusion and badness.

Indirectly Spotted by CodeSonar which identified a duplicate assignment
in this function.

Add test 471 to verify

Closes #13421
2024-04-19 13:34:00 +02:00
Viktor Szakats
49f83c30e4
lib: merge ENABLE_QUIC C macro into USE_HTTP3
Before this patch `lib/curl_setup.h` defined these two macros right
next to each other, then the source code used them interchangeably.

After this patch, `USE_HTTP3` guards all HTTP/3 / QUIC features.
(Like `USE_HTTP2` does for HTTP/2.) `ENABLE_QUIC` is no longer used.

This patch doesn't change the way HTTP/3 is enabled via autotools
or CMake. Builders who enabled HTTP/3 manually by defining both of
these macros via `CPPFLAGS` can now delete `-DENABLE_QUIC`.

Closes #13352
2024-04-13 08:33:27 +00:00
Stefan Eissing
8dd81bd5db
lib: add Curl_xfer_write_resp_hd
Add method in protocol handlers to allow writing of a single,
0-terminated header line. Avoids parsing and copying these lines.

Closes #13165
2024-04-11 09:29:21 +02:00
Daniel Stenberg
50def7c881
NTLM_WB: drop support
The feature has not worked for months and has been marked as DEPRECATED
for six+ months.

Closes #13249
2024-04-08 13:58:58 +02:00
MAntoniak
f46385d36d
urldata: remove fields not used depending on used features
Reduced size of dynamically_allocated_data structure.

Reduced number of stored values in enum dupstring and enum dupblob. This
affects the reduced array placed in the UserDefined structure.

Closes #13188
2024-04-05 16:06:22 +02:00
Stefan Eissing
721941aadf
http: with chunked POST forced, disable length check on read callback
- when an application forces HTTP/1.1 chunked transfer encoding
  by setting the corresponding header and instructs curl to use
  the CURLOPT_READFUNCTION, disregard any POST length information.
- this establishes backward compatibility with previous curl versions

Applications are encouraged to not force "chunked", but rather
set length information for a POST. By setting -1, curl will
auto-select chunked on HTTP/1.1 and work properly on other HTTP
versions.

Reported-by: Jeff King
Fixes #13229
Closes #13257
2024-04-02 08:41:44 +02:00
Daniel Stenberg
47da1f289c
http: remove stale comment about rewindbeforesend
... because that struct field exists no more.

Follow-up to 14bcea074a.

Closes #13187
2024-03-26 08:40:58 +01:00
Stefan Eissing
0f08b43557
http: separate response parsing from response action
- move code that triggers on end-of-response into separate function from
  parsing
- simplify some headp/headerlen usage
- add `httpversion` to SingleRequest to indicate the version of the
  current response

Closes #13134
2024-03-21 09:34:40 +01:00
Stefan Eissing
522ea5420f
http: improve response header handling, save cpu cycles
Saving some cpu cycles in http response header processing:
- pass the length of the header line along
- use string constant sizeof() instead of strlen()
- check line length if prefix is possible
- switch on first header char to limit checks

Closes #13143
2024-03-19 07:53:43 +01:00
Stefan Eissing
80a3b830cc
http: expect 100 rework
Move all handling of HTTP's `Expect: 100-continue` feature into a client
reader. Add sending flag `KEEP_SEND_TIMED` that triggers transfer
sending on general events like a timer.

HTTP installs a `CURL_CR_PROTOCOL` reader when announcing `Expect:
100-continue`. That reader works as follows:

- on first invocation, records time, starts the `EXPIRE_100_TIMEOUT`
  timer, disables `KEEP_SEND`, enables `KEEP_SEND_TIMER` and returns 0,
  eos=FALSE like a paused upload.

- on subsequent invocation it checks if the timer has expired. If so, it
  enables `KEEP_SEND` and switches to passing through reads to the
  underlying readers.

Transfer handling's `readwrite()` will be invoked when a timer expires
(like `EXPIRE_100_TIMEOUT`) or when data from the server arrives. Seeing
`KEEP_SEND_TIMER`, it will try to upload more data, which triggers
reading from the client readers again. Which then may lead to a new
pausing or cause the upload to start.

Flags and timestamps connected to this have been moved from
`SingleRequest` into the reader's context.

Closes #13110
2024-03-18 12:41:56 +01:00
Stefan Eissing
77b0571cdc
http: revisit http_perhapsrewind()
- use facilities provided by client readers better
- work also for non-uploading requests like GET/HEAD
- update documentation

Closes #13117
2024-03-15 10:50:44 +01:00
Stefan Eissing
4e4e8af1f6
lib: move 'done' parameter to SingleRequests
A transfer may do several `SingleRequest`s for its success. This happens
regularly for authentication, follows and retries on failed connections.
The "readwrite()" calls and functions connected to those carried a `bool
*done` parameter to indicate that the current `SingleRequest` is over.
This may happen before `upload_done` or `download_done` bits of
`SingleRequest` are set.

The problem with that is now `write_resp()` protocol handlers are
invoked in places where the `bool *done` cannot be passed up to the
caller. Instead of being a bool in the call chain, it needs to become a
member of `SingleRequest`, reflecting its state.

This removes the `bool *done` parameter and adds the `done` bit to
`SingleRequest` instead. It adds `Curl_req_soft_reset()` for using a
`SingleRequest` in a follow up, clearing `done` and other
flags/counters.

Closes #13096
2024-03-11 23:27:02 +01:00
Stefan Eissing
a586b8ca40
lib: client reader polish
- seek_func/seek_client, use transfer values only
    - remove copies held in `struct connectdata`, use only
      ever `data->set.seek_func`
    - resolves possible issues in multiuse connections
    - new mime post reader eliminates need to ever overwriting this

- websockets, remove empty Curl_ws_done() function

Closes #13079
2024-03-08 13:11:17 +01:00
Stefan Eissing
2ca530d2fa
http: fix dead code in setting post client reader
- postsize was always 0, thus the check's else never happened
  after the mime client reader was introduced

Follow-up to 0ba47146f7
Closes #13060
2024-03-06 14:35:23 +01:00
Stefan Eissing
0ba47146f7
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

Closes #13039
2024-03-06 00:17:37 +01:00
Michael Kaufmann
df1fcb41e2
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".

Closes #13045
2024-03-05 16:02:44 +01:00
Stefan Eissing
14bcea074a
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_*`

Closes #13026
2024-03-05 13:26:05 +01:00
Stefan Eissing
e3905de819
lib: further send/upload handling polish
- Move all the "upload_done" handling to request.c

  - add possibility to abort sending of a request
  - add `Curl_req_done_sending()` for checks
  - transfer.c: readwrite_upload() now clean

- removing data->state.ulbuf and data->req.upload_fromhere

  - as well as data->req.upload_present
  - set data->req.upload_done on having read all from
    the client and completely flushed the send buffer

- tftp, remove setting of data->req.upload_fromhere

  - serves no purpose as `upload_present` is not set
    and the data itself is directly `sendto()` anyway

- smtp, make upload EOB conversion a client reader
- xfer_ulbuf addition

  - add xfer_ulbuf for borrowing, similar to xfer_buf
  - use in file upload
  - use in c-hyper body sending

- h1-proxy, remove init of data->state.uilbuf that is never used
- smb, add own send_buf instead of using data->state.ulbuf

Closes #13010
2024-03-04 08:42:56 +01:00
RainRat
2cd78f525c misc: Fix typos in docs and lib
This fixes miscellaneous typos and duplicated words in the docs, lib
and test comments and a few user facing errorstrings.

Author: RainRat on Github
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dan Fandrich <dan@coneharvesters.com>
Closes: #13019
2024-03-01 09:59:48 +01:00
Stefan Eissing
9369c30cd8
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)

Added as documented [in
CLIENT-READER.md](5b1f31dfba/docs/CLIENT-READERS.md).

- 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.

Closes #12969
2024-02-28 12:58:55 +01:00
Stefan Eissing
3755153571
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.

Closes #12964
2024-02-27 14:13:56 +01:00
Stefan Eissing
5929822114
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

Closes #12963
2024-02-27 08:58:10 +01:00
Stefan Eissing
2254551403
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.

Closes #12949
2024-02-26 10:30:52 +01:00
Stefan Eissing
2abfa3833b
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

Closes #12880
2024-02-26 09:44:15 +01:00
MAntoniak
e26c362544
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

Closes #12948
2024-02-26 09:22:34 +01:00
Daniel Stenberg
066ed4e514
http: only act on 101 responses when they are HTTP/1.1
For 101 responses claiming to be any other protocol, bail out. This
would previously trigger an assert.

Add test 1704 to verify.

Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66184
Closes #12811
2024-01-27 21:49:20 +01:00
Stefan Eissing
a069c6aeb2
http, use stack scratch buffer
- instead of data->state.buffer

Closes #12791
2024-01-25 22:31:08 +01:00
Daniel Stenberg
879a44084f
http: check for "Host:" case insensitively
When checking if the user wants to replace the header, the check should
be case insensitive.

Adding test 461 to verify

Found-by: Dan Fandrich
Ref: #12782
Closes #12784
2024-01-25 13:53:09 +01:00
Daniel Stenberg
199c1d720d
http: remove comment reference to a removed solution
Follow-up to 58974d25d

Closes #12785
2024-01-25 11:26:23 +01:00
Stefan Eissing
3378d2bd09
websockets: refactor decode chain
- use client writer stack for decoding frames
- move websocket protocol handler to ws.c

Closes #12713
2024-01-16 16:43:24 +01:00
Stefan Eissing
d7b6ce64ce
lib: replace readwrite with write_resp
This clarifies the handling of server responses by folding the code for
the complicated protocols into their protocol handlers. This concerns
mainly HTTP and its bastard sibling RTSP.

The terms "read" and "write" are often used without clear context if
they refer to the connect or the client/application side of a
transfer. This PR uses "read/write" for operations on the client side
and "send/receive" for the connection, e.g. server side. If this is
considered useful, we can revisit renaming of further methods in another
PR.

Curl's protocol handler `readwrite()` method been changed:

```diff
-  CURLcode (*readwrite)(struct Curl_easy *data, struct connectdata *conn,
-                        const char *buf, size_t blen,
-                        size_t *pconsumed, bool *readmore);
+  CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
+                         bool is_eos, bool *done);
```

The name was changed to clarify that this writes reponse data to the
client side. The parameter changes are:

* `conn` removed as it always operates on `data->conn`
* `pconsumed` removed as the method needs to handle all data on success
* `readmore` removed as no longer necessary
* `is_eos` as indicator that this is the last call for the transfer
  response (end-of-stream).
* `done` TRUE on return iff the transfer response is to be treated as
  finished

This change affects many files only because of updated comments in
handlers that provide no implementation. The real change is that the
HTTP protocol handlers now provide an implementation.

The HTTP protocol handlers `write_resp()` implementation will get passed
**all** raw data of a server response for the transfer. The HTTP/1.x
formatted status and headers, as well as the undecoded response
body. `Curl_http_write_resp_hds()` is used internally to parse the
response headers and pass them on. This method is public as the RTSP
protocol handler also uses it.

HTTP/1.1 "chunked" transport encoding is now part of the general
*content encoding* writer stack, just like other encodings. A new flag
`CLIENTWRITE_EOS` was added for the last client write. This allows
writers to verify that they are in a valid end state. The chunked
decoder will check if it indeed has seen the last chunk.

The general response handling in `transfer.c:466` happens in function
`readwrite_data()`. This mainly operates now like:

```
static CURLcode readwrite_data(data, ...)
{
  do {
    Curl_xfer_recv_resp(data, buf)
    ...
    Curl_xfer_write_resp(data, buf)
    ...
  } while(interested);
  ...
}
```

All the response data handling is implemented in
`Curl_xfer_write_resp()`. It calls the protocol handler's `write_resp()`
implementation if available, or does the default behaviour.

All raw response data needs to pass through this function. Which also
means that anyone in possession of such data may call
`Curl_xfer_write_resp()`.

Closes #12480
2024-01-13 17:23:42 +01:00
Daniel Stenberg
cfe7902111
lib: add debug log outputs for CURLE_BAD_FUNCTION_ARGUMENT
Closes #12658
2024-01-08 22:48:24 +01:00