Commit Graph
266 Commits
Author SHA1 Message Date
David NadobaandGitHub 4e74fefd1c Support custom backgroundActivityLogger with using the default ELG. (#711) 2023-09-06 13:49:25 +01:00
David NadobaandGitHub 75d7f63abf Automatically chunk large request bodies (#710)
* ChunkedCollection

* Use swift-algorithms

* SwiftFormat

* test chunking

* add documentation

* SwiftFormat

* fix old swift versions

* fix older swift versions

second attempt

* fix old swift versions

third attempt

* fix old swift versions

fourth attempt

* update documentation
2023-09-06 11:08:09 +01:00
8c90405f0c use NIOSingletons EventLoops/NIOThreadPool instead of spawning new (#697)
Co-authored-by: Johannes Weiss <johannes@jweiss.io>
2023-08-14 14:59:33 +01:00
668c193451 Removed duplicated code (#694)
Co-authored-by: Franz Busch <f.busch@apple.com>
2023-06-26 12:13:50 +02:00
brennoandGitHub c7fb77557c Replace os() with canImport(Darwin) (#693)
* Replace os() with canImport(Darwin)

* Remove compilation conditional since it'll always be true
2023-06-26 00:22:30 -07:00
David NadobaandGitHub 78db67e5bf Tolerate new request after connection error happened (#688)
* Tolerate new request after connection error happened

* fix tests
2023-05-17 09:37:35 +01:00
David NadobaandGitHub d62c475401 Drop Swift 5.5 (#686) 2023-04-14 17:05:09 +01:00
CoreyandGitHub 333e60cc90 Fix building transaction extension for Apple Platforms (#685) 2023-04-14 06:03:14 -07:00
David NadobaandGitHub b9029ef67c Add support for custom cancellation error (#683) 2023-04-13 17:00:03 +01:00
David NadobaandGitHub 45626d33c7 Pass request Task to FileDownloadDelegate reportHead and reportProgress closures (#681)
### Motivation
If the HTTP response status is not 2xx or the file being downloaded becomes too big, it is desirable to cancel the file download eagerly. This is currently quite hard because the `reportHead` and `reportProgress` closures do not have direct access to the `HTTPClient.Task`.

### Modifications
- Pass `HTTPClient.Task` additionally to `reportHead` and `reportProgress` closures

### Result
A file download can now easily be cancelled at any time.
2023-04-13 10:21:13 +01:00
David NadobaandGitHub e18db27dd3 Replace TransactionBody with NIOAsyncSequenceProducer (#677)
* save progress

* Replace `TransactionBody` with `NIOAsyncSequenceProducer`

* test

* revert unnesscary changes

* Add end-to-end test

which currently fails because of https://github.com/apple/swift-nio/issues/2398

* soundness

* Use latest swift-nio release

* throw CancellationError on task cancelation

* Fix Swift 5.5 & 5.6
2023-04-12 15:11:56 +01:00
George BarnettandGitHub 6c5058ee2c Add a control to limit connection reuses (#678)
Motivation:

Sometimes it can be helpful to limit the number of times a connection
can be used before discarding it. AHC has no such support for this at
the moment.

Modifications:

- Add a `maximumUsesPerConnection` configuration option which defaults
  to `nil` (i.e. no limit).
- For HTTP1 we count down uses in the state machine and close the
  connection if it hits zero.
- For HTTP2, each use maps to a stream so we count down remaining uses
  in the state machine which we combine with max concurrent streams to
  limit how many streams are available per connection. We also count
  remaining uses in the HTTP2 idle handler: we treat no remaining uses
  as receiving a GOAWAY frame and notify the pool which then drains the
  streams and replaces the connection.

Result:

Users can control how many times each connection can be used.
2023-04-11 14:49:44 +01:00
Cory BenfieldandGitHub 343cdf4639 Fix documentation and add support for CI-ing it (#679)
* Fix documentation and add support for CI-ing it

* Fixup license header
2023-04-11 13:35:46 +01:00
91b26407ad Update collect to use content-length to make early checks
Motivation:
not accumulate too many bytes

Modifications:
Implementing collect function to use NIOCore version to prevent overflowing

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-04-04 16:56:58 +01:00
David NadobaandGitHub 98b45ed1cd Allow DNS override (#675)
Sometimes it can be useful to connect to one host e.g. `x.example.com` but request and validate the certificate chain as if we would connect to `y.example.com`. This is what this PR adds support for by adding a `dnsOverride` configuration to `HTTPClient.Configuration`. This is similar to curls `—resolve-to` option but only allows overriding host and not ports for now.
2023-03-30 08:21:41 +01:00
David NadobaandGitHub 423fd0bd6b Fix crash if connection is closed very early (#671)
* Fix crash if connection is closed very early

If the channel is closed before flatMap is executed, all ChannelHandler are removed and `TLSEventsHandler` is therefore not present either. We need to tolerate this even though it is very rare.

Testing ideas welcome.

Fixes #670

* drop precondition to assert
2023-03-14 03:35:06 -07:00
Cory BenfieldandGitHub 864c8d9e0e Mark Task.wait() noasync and provide Task.get() (#668)
Motivation

Task.wait() is a convenience method to avoid needing to wait for the
response future. This has had the effect of "laundering" a noasync
warning from EventLoopFuture.wait(), hiding it within a purely sync call
that may itself be used in an async context.

We should discourage using these and prefer using .get() instead.

Modifications

Mark Task.wait() noasync.
Add Task.get() for backward compatibility.

Result

Safer migration to Swift concurrency
2023-02-14 01:48:22 -08:00
Fabian FettandGitHub e26459902c Fix HTTP2StreamChannel leak (#657)
* Fix HTTP2StreamChannel leak

* Update code comments.
2023-02-14 10:04:27 +01:00
Cory BenfieldandGitHub 9401037091 Make syncShutdown unavailable from async (#667)
* Make syncShutdown unavailable from async

Motivation

syncShutdown can cause unbounded thread blocking, we shouldn't allow it
in concurrent code.

Modification

Mark syncShutdown unavailable from async.

Result

Users are warned if they try to syncShutdown in an async context

* Only noasync on 5.7
2023-02-13 18:44:22 +01:00
1d24271fee Fix crash for large HTTP request headers (#661)
* Reproducer

* Refactor test case

* Refactor tests

* Remove debugging artefacts

* Fix typo

* Fix formatting

* Remove `promise?.succeed(())`

* Add test for HTTP2 request with large header

Motivation

We currently don't handle large headers well which trigger a channel writability change event.

Modification

Add failing (but currently skipped) tests which reproduces the issue
Result

We can reliably reproduce the large request header issue in an integration and unit test.
Note that the actual fix is not included to make reviewing easier and will come in a follow up PR.

* Remove logging

* Fix crash for large HTTP request headers

Fix crash for when sending HTTP request headers result in a channel writability change event

* Formatting and linux tests

* Formatting and linux tests

* Generate linux tests

* Use previous default max concurrent streams value of 10

* Fix crash if request is canceled after request header is send

* generate linux tests and run swift format

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-02-10 15:41:26 +01:00
David NadobaandGitHub aa66da80fa Fix request head continuation misuse (#666)
* Fix request head continuation misuse

Fixes #664

* remove unused function

* format & generate linux tests
2023-02-10 14:13:21 +00:00
Fabian FettandGitHub f65f45b727 Fix Request streaming memory leak (#665) 2023-02-07 17:18:56 +01:00
David NadobaandGitHub 67f99d1798 Add test for HTTP1 request with large header (#658)
* Reproducer

* Refactor test case

* Refactor tests

* Remove debugging artefacts

* Fix typo

* Fix formatting

* Remove `promise?.succeed(())`

* Rename `onRequestCompleted` to `onConnectionIdle`
2023-01-26 11:11:30 +00:00
Felix SchlegelandGitHub 817d9aa99f Make Task.logger accessible to delegate implementations outside of Package (#587)
Motivation:

This change was proposed in issue
[#389](https://github.com/swift-server/async-http-client/issues/389).
Users writing their own `HttpClientResponseDelegate` implementation
might want to emit log messages to the `task`'s `logger`.

Modifications:

Changed the access level of `Task`'s `logger` property from `internal`
to `public`.

Result:

Users can access the `logger` property of a `Task` outside of the
`async-http-client`.
2023-01-22 09:32:01 -08:00
Cory BenfieldandGitHub 7f05a8da46 Merge pull request from GHSA-v3r5-pjpm-mwgq
Motivation

Allowing arbitrary data in outbound header field values allows for the
possibility that users of AHC will accidentally pass untrusted data into
those values. That untrusted data can substantially alter the parsing
and content of the HTTP requests, which is extremely dangerous. The
result of this is vulnerability to CRLF injection.

Modifications

Add validation of outbound header field values.

Result

No longer vulnerable to CRLF injection
2023-01-17 11:06:08 +00:00
iMikeandGitHub 49abfc30ae Add Host header (#650) (#651) 2022-12-06 11:13:10 +00:00
David NadobaandGitHub 5bee16a799 Switch over state in HTTPConnectionPool.HTTP2StateMachine.failedToCreateNewConnection (#647) 2022-11-09 15:30:16 +01:00
David NadobaandGitHub fd03ed01c7 Tolerate shutdown message after channel is closed (#646)
* Tolerate shutdown message after channel is closed

### Motivation
A channel can close unexpectedly if something goes wrong. We may in the meantime have scheduled the connection for graceful shutdown but the connection has not yet seen the message. We need to still accept the shutdown message and just ignore it if we are already closed.

### Modification
- ignore calls to shutdown if the channel is already closed
- add a test which would previously crash because we have transition from the closed state to the closing state and we hit the deinit precondition
- include the current state in preconditions if we are in the wrong state

### Result

We don’t hit the precondition in the deinit in the scenario described above and have more descriptive crashes if something still goes wrong.
2022-11-08 17:48:56 +01:00
carolinacassandGitHub 8b84142a70 Use #fileID/#filePath instead of #file (#644) 2022-11-04 08:20:19 -07:00
Max DesiatovandGitHub 10f42e647a FileDownloadDelegate: mark Progress as Sendable (#643)
This is a trivial struct that should be `Sendable`, as it's a common use case to pass `Progress` values to `@Sendable` closures.
2022-10-26 02:50:36 -07:00
David NadobaandGitHub 0bdc425a84 Remove #if compiler(>=5.5) (#641)
* Remove `#if compiler(>=5.5)`

* Run SwiftFormat
2022-10-12 16:18:47 +01:00
David NadobaandGitHub 0b5bec741b Replace NIOSendable with Sendable (#640) 2022-10-12 08:50:28 +01:00
David NadobaandGitHub d7b69d9d56 Make HTTPClientResponse.init public (#632) 2022-10-11 10:36:21 +01:00
David NadobaandGitHub f17a47e916 Allow immediate request failure on connection error (#625) 2022-10-10 13:34:42 +01:00
David NadobaandGitHub 9937d8751a Handle ResponseAccumulator not being able to buffer large response in memory (#637)
* Handle ResponseAccumulator not being able to buffer large response in memory

Check content length header for early exit

* Add test which currently hangs indefinitely

* Run `generate_linux_tests.rb` and `SwiftFormat`

* Print type and value if assert fails

* Run `generate_linux_tests.rb` and `SwiftFormat`

* Remove duplicate test due too merge conflict

* Validate that maxBodySize is positive

* Address review comments
2022-10-10 11:18:58 +01:00
David NadobaandGitHub f7a84af5d6 Fix request hang if delegate fails promise returned by didReceiveBodyPart (#633)
* Add test which currently hangs indefinitely

* Fix request hang if delegate fails promise

* Run `generate_linux_tests.rb` and `SwiftFormat`
2022-10-07 08:22:56 -07:00
Fabian FettandGitHub 4d69c84617 Add Hashable conformance to HTTPClient.Configuration.HTTPVersion (#636) 2022-10-07 08:15:14 -07:00
Fabian FettandGitHub af5966f1d1 Reduce use of HTTPClient.Configuration in the Connection objects (#635) 2022-10-07 08:05:28 -07:00
Fabian FettandGitHub 64ff430582 Add Hashable conformace to HTTPClient.Configuration.Proxy (#634) 2022-10-07 15:49:29 +01:00
Fabian FettandGitHub 897d49aa1b Replace Lock with NIOLock (#628)
SwiftNIO 2.42.0 has deprecated Lock and replaced it with a new NIOLock. This commit removes all uses of Lock and replaces them with NIOLock. Further, now, we must require SwiftNIO 2.42.0
2022-09-27 15:42:47 +02:00
7f998f5118 add a future-returning shutdown method (#626)
Co-authored-by: Johannes Weiss <johannes@jweiss.io>
2022-09-07 06:12:05 -07:00
David NadobaandGitHub c3c90aab58 Adopt Sendable (#621) 2022-08-25 11:45:13 +02:00
David NadobaandGitHub 9c7ab039fe Allow HTTPClientRequest to be executed multiple times if body is an AsyncSequence (#620) 2022-08-23 13:46:17 +01:00
KarlandGitHub 18109d842d Use NIOCore.System.coreCount for the fileIO thread pool (#618) 2022-08-20 12:22:41 +01:00
fc510a39cf Fix thread leak in FileDownloadDelegate (#614)
* Fix thread leak in `FileDownloadDelegate`

* `SwiftFormat`

* Add a shared file IO thread pool per HTTPClient

* User bigger thread pool and initlize lazily during first file write

* thread pool is actually not used in tests

* Update documentation

* fix review comments

* make `fileIOThreadPool` internal

* Add test to verify that we actually share the same thread pool across all delegates for a given HTTPClient

Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-08-18 11:55:55 +02:00
David NadobaandGitHub 0469acb3bd Tollerate more data after request body is cancelled (#617)
* Tollerate more data after request body is cancelled

* wait is not needed if we shutdown the server first

* Remove test that depends on external resources

* Remove unused conformance to Equatable

* SwiftFormat

* run generate_linux_tests.rb

* Increase timeout for CI
2022-08-18 10:39:55 +01:00
Cory BenfieldandGitHub e294c8f28f Accurately apply the connect timeout in async code (#616)
Motivation

We should apply the connect timeout to the complete set of connection
attempts, rather than the request deadline. This allows users
fine-grained control over how long we attempt to connect for. This is
also the behaviour of our old-school interface.

Modifications

- Changed the connect deadline calculation for async/await to match that
  of the future-based code.
- Added a connect timeout test.

Result

Connect timeouts are properly handled
2022-08-16 13:17:45 +01:00
Cory BenfieldandGitHub 5e3e58dafd Use Docc for documentation (#613)
Motivation

Documentation is nice, and we can help support users by providing useful
clear docs.

Modifications

Add Docc to 5.6 and later builds
Make sure symbol references work
Add overview docs

Result

Nice rendering docs
2022-08-09 16:23:14 +01:00
df87a860fd Limit max recursion depth delivering body parts (#611)
Motivation

When receiving certain patterns of response body parts, we can end up
recursing almost indefinitely to deliver them to the application. This
can lead to crashes, so we might politely describe it as "sub-optimal".

Modifications

Keep track of our stack depth and avoid creating too many stack frames.
Added some unit tests.

Result

We no longer explode when handling bodies with lots of tiny parts.

Co-authored-by: David Nadoba <d_nadoba@apple.com>
2022-08-05 17:53:21 +01:00
David NadobaandGitHub 46d1c76715 Support transparent decompression with HTTP/2 (#610) 2022-08-05 17:04:57 +02:00