Commit Graph

240 Commits

Author SHA1 Message Date
Adam Fowler 61053a00bb NIOTypedHTTPClientUpgradeHandler will write Upgrade request on handlerAdded if active (#3473)
`NIOTypedHTTPClientUpgradeHandler.handlerAdded` will write upgrade
request if the channel is already active

### Motivation:

This has been added to make it easier to implement a websocket client
that supports proxies. If the upgrade handler is added after the proxy
connect has been processed previously nothing would happen.

### Modifications:

- Added new function
`NIOTypedHTTPClientUpgradeHandler.writeUpgradeRequest()` function. Call
this from `channelActive` and also from `handlerAdded` if the channel is
already active.
- Added test `testUpgradeHappensAfterHandlerAdded`

### Result:

NIOTypedHTTPClientUpgradeHandler now also works if it is added to a
channel after the channel is active

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2026-01-14 11:40:00 +00:00
aryan-25 a1605a3303 Use explicit class name in all Self.[un]wrap{In}{Out}bound{In}{Out} calls (#3463)
### Motivation:

Swift does not currently generic specialize static methods on final
classes that have no parent classes when the method is implemented in a
protocol. This means that calling such methods through `Self` will not
involve a generic specialization, whereas using the explicit type name
will.

This pattern manifests in the `[un]wrap{In}{Out}bound{In}{Out}` static
methods defined in the
[`ChannelInboundHandler`](https://github.com/apple/swift-nio/blob/27146d484478b1bb0f150e848758f3a34ed9cbd0/Sources/NIOCore/TypeAssistedChannelHandler.swift#L60)
and
[`ChannelOutboundHandler`](https://github.com/apple/swift-nio/blob/27146d484478b1bb0f150e848758f3a34ed9cbd0/Sources/NIOCore/TypeAssistedChannelHandler.swift#L95)
protocols and their use from all channel handler classes. As such, we
should replace the `Self` part in all
`Self.[un]wrap{In}{Out}bound{In}{Out}` calls with the explicit class
name.

### Modifications:

Replaced all `Self.[un]wrap{In}{Out}bound{In}{Out}` calls to use the
explicit class name.

### Result:

Eliminates unnecessary overhead.
2025-12-15 17:36:11 +00:00
George Barnett a65e9735ac Drop all server response parts after an invalid header (#3339)
Motivation:

NIOHTTPResponseHeadersValidator drops head/end response parts if they
contain invalid header fields. If a head part is dropped and the server
allows pipelining then the subsequent body/end part will reach the
pipelining handler and result in an assertion failure in debug builds.
In release builds, some parts may be incorrectly written out leading to
protocol violations.

Modifications:

- Drop all response parts after an invalid response part

Result:

- Fewer bugs
- Resolves #3326

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-08-12 09:33:24 +00:00
Fabian Fett 2c9b7c6061 [Windows] Ensure NIOHTTP1 compiles (#3338)
This only needs one `numericCast`.

Previous error:
```
C:\Users\fat\Developer\apple\swift-nio\Sources\NIOHTTP1\HTTPDecoder.swift:113:49: error: cannot convert value of type 'CUnsignedInt' (aka 'UInt32') to expected argument type 'Int32'
 111 |                 statusCode: Int(opaque!.pointee.status_code),
 112 |                 isUpgrade: opaque!.pointee.upgrade != 0,
 113 |                 method: llhttp_method(rawValue: CUnsignedInt(opaque!.pointee.method)),
     |                                                 `- error: cannot convert value of type 'CUnsignedInt' (aka 'UInt32') to expected argument type 'Int32'
 114 |                 keepAliveState: opaque!.keepAliveState
 115 |             ) {
```

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-08-11 17:20:12 +00:00
Rafael Cepeda 02be63c7f4 Fixes all warnings when -require-explicit-sendable flag is enabled (#3320)
Fixes all warnings when `-require-explicit-sendable` flag is enabled and
enables the flag on macOS CI.

### Motivation:

We want to ensure our public API is either explicitly marked as
`Sendable` or not.

### Modifications:

Marked appropriate public types as `Sendable`, or explicitly defined
their conformance to the `Sendable` protocol as unavailable.

### Result:

We can now enable `-require-explicit-sendable` compiler flag in our
codebase.
2025-07-30 11:50:28 +01:00
Rick Newton-Rogers 57658e12ff Drop Swift 5.9 (#3228)
Motivation:

Swift 5.9 is no longer supported, we should bump the tools version and
remove it from our CI.

Modifications:

* Bump the Swift tools version to Swift 5.10
* Remove Swift 5.9 jobs where appropriate in main.yml, pull_request.yml

Result:

Code reflects our support window.
2025-05-07 12:24:44 +00:00
Cory Benfield abe4f1bcb6 Replace almost all public static lets with computed vars (#3229)
Motivation:

Public static lets can serve a bunch of roles, but one of them is to
store simple constants: integers, and other trivial types, for example.
This is a nice pattern and for internal and private static lets it works
well, but for public ones it produces some inefficient code.

In particular, it has two downsides. First, it allocates storage for
that value. We don't actually need to allocate a few hundred extra
megabytes for the various integers we want to store.

Secondly, it forces calling code to access the address and call the
dispatch_once code in order to get hold of the value. For trivial types
we don't need that cost: they can just know what the value is directly.

Inlinable computed vars avoid all of these costs: they have no size
overhead for storage, and they are visible to all clients so their
values can be directly assembled.

While I'm here, I added a bunch of other inlinable annotations for a few
trivial data types I stumbled onto.

Modifications:

- Added loads of inlinables. Like, loads.
- Swapped many static lets to static vars.

Result:

Better codegen, smaller memory footprints, more attributes.
2025-05-02 16:08:10 +01:00
Adam Fowler d7a8ff6e36 Add errorCaught to NIOTypedHTTPClientUpgradeHandler (#3210)
To handle errors fired by previous ChannelHandlers. eg
NIOSSLClientHandler

### Motivation:

Otherwise if a ChannelHandler previous to the upgrade ChannelHandler
fails the error returned is `inappropriateOperationForState` and the
error fired by the original ChannelHandler is lost.

Added `testReturnsErrorsFromPriorChannelHandlers`. Also had to
reorganise `setUpClientChannel` slightly so I could get the result of
the upgrade.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-04-16 14:24:42 +00:00
Rick Newton-Rogers 5f60ceeca0 Enable strict concurrency checking for NIOHTTP1 (#3115)
### Motivation:

To ensure NIOHTTP1 concurrency safety.

### Modifications:

* Enable strict concurrency checking in the package manifest.
* Mark several objects `Sendable` with `@preconcurrency` annotations
where they are returned in futures which may execute in arbitrary
concurrency domains.
  * `NIOTypedHTTPClientProtocolUpgrader`
  * `NIOTypedHTTPClientUpgradeConfiguration`
  * `NIOUpgradableHTTPServerPipelineConfiguration`
  * `NIOUpgradableHTTPClientPipelineConfiguration`
  * `NIOTypedHTTPServerProtocolUpgrader`
  * `NIOTypedHTTPServerUpgradeConfiguration`
* Mark handlers as explicitly not sendable
  * `NIOTypedHTTPClientUpgradeHandler`
  * `NIOTypedHTTPServerUpgradeHandler`
* Added new Sendable type aliases:
  * `NIOHTTPClientUpgradeSendableConfiguration`
  * `NIOHTTPServerUpgradeSendableConfiguration`

### Result:

No more concurrency warnings. Builds will warn and CI will fail if
regressions are introduced.
2025-02-19 15:04:51 +00:00
Tim Condon ac79370dee Add ChannelPipeline.SynchronousOperations.Position (#3065)
Adds a new `ChannelPipeline.SynchronousOperations.Position` type to fill
a hole in the API that prevented non-sendable Channel handlers being
added at a position to the pipeline via the synchronous operations.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-02-04 10:31:29 +00:00
Mirza Učanbarlić bf41ad1595 Improve HTTPHeaders description performance (#3063)
### Motivation:

As outlined in this
[issue](https://github.com/apple/swift-nio/issues/2930) by @weissi, the
current performance of calling `description` on `HTTPHeaders` is
undermined by the dynamism of Array.

### Modifications:

The proposed solution replaces the implementation of `description` to
iterate over the items and print them out manually. This provides a
faster solution since we bypass the cost of calling into `description`
of an Array.


### Result:

A more performant implementation of `HTTPHeaders` description.

---------

Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-01-20 16:39:21 +00:00
Cory Benfield 96877aff7f Fix compiling on 6.1 (#3057)
Motivation:

Swift 6.1 nightlies have added many new warnings and errors to NIO. This
patch resolves all of them.

Modifications:

- Clean up missing imports
- Move away from @_implementationOnly where necessary
- Fix a few things where Sendable mismatches were present.

Result:

Clean compile again

---------

Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2025-01-14 16:36:17 +00:00
Johannes Weiss 6ba8f4f04a fix almost all Sendable warnings (#2994)
### Motivation:

Opening the `swift-nio` repository made me warning blind because there
were always so many trivially fixable warnings about things that were
correct but cannot be understood by the compiler.

### Modifications:

Fix all the sendable warnings that popped up, except for one test where
`NIOLockedValueBox<Thread?>` isn't sendable because `Foundation.Thread`
seemingly isn't `Sendable` which is odd. Guessing that'll be fixed on
their end.

### Result:

- Fewer warnings
- Less warning-blindness
- More checks
2024-11-25 17:56:44 +00:00
Adam Fowler a026de35e0 Close channel during upgrade, if client closes input (#2756)
Check for half closure during server upgrade and close channel if client
closes the channel

### Motivation:

This is to fix #2742 

### Modifications:

Add `userInboundEventTriggered` function to
`NIOTypedHTTPServerProtocolUpgrader` which checks for
`ChannelEvent.inputClosed`

### Result:

Negotiation future now errors when client closes the connection instead
of never completing

---------

Co-authored-by: Franz Busch <privat@franz-busch.de>
2024-11-14 18:15:12 +00:00
Rick Newton-Rogers adfd61adc5 Use Swift 6.0 docs pipeline (#2966)
### Motivation:

Documentation checking catches more issues in Swift 6.0.

### Modifications:

Adopt the Swift 6.0 image and fix the errors.

### Result:

More accurate docs.
2024-11-07 13:03:47 +00:00
Cory Benfield 411c2c553c Handle Sendability of RemovableChannelHandler (#2953)
Motivation:

RemovableChannelHandlers have a large API surface in NIOCore. That API
surface is a bit awkward with regard to strict concurrency, and needs
some cleanup.

Modifications:

This patch adds some new API that is necessary to safely work with
RemovableChannelHandlers, deprecates some API that cannot plausibly be
used, and cleans up some other parts of the API.

Result:

Easier to work with RemovableChannelHandlers
2024-10-29 10:40:47 +00:00
Franz Busch c9756e1083 Adopt swift-format (#2794)
* Apply formatting

* Apply no block comments rule

* Apply OmitExplicitReturns

* Apple OnlyOneTrailingClosureArgument

* Apply NoAssignmentInExpressions

* Fix up DontRepeatTypeInStaticProperties lint errors

* Apply `OrderedImports`

* Apply `ReplaceForEachWithForLoop`

* format file

* Enable the formatting pipeline

* Adopt `AmbiguousTrailingClosureOverload`

* Fix license header

* Fix format check

* Fix `EndOfLineComment`

* Fix CI

* Adapt CI script to check if changes when running formatting

* Separate lint and format into to steps

* Fix format

* Adopt `UseEarlyExits`

* Revert "Adopt `UseEarlyExits`"

This reverts commit d1ac5bbe12.
2024-07-19 11:48:17 +02:00
Johannes Weiss 7948ed2104 ChannelHandler: provide static (un)wrap(In|Out)bound(In|Out) (#2791) 2024-07-18 11:55:48 +01:00
Dimitri Bouniol 5e9a9ccc10 Improved documentation for HTTP Parts to clarify how often each part is received (#2775) 2024-07-12 02:20:14 -07:00
Dimitri Bouniol 72cab7d9a4 Correctly mark 304 as not having a response body (#2737)
* Fixed an issue where HTTP/2 connections would disconnect if response compression were used and a 304 Not Modified response was returned

* Added HTTP encoder tests for 304 Not Modified responses
2024-06-12 18:30:58 +01:00
Franz Busch 63e8c4e1aa Migrate to syncOperations in more places (#2661)
# Motivation

Adding a handler via the regular `pipeline.addHandler` APIs can lead to transferring the handler over isolation regions. To avoid running into `Sendable` warnings here we can use the `syncOperations` of the pipeline to avoid transferring the handlers.

# Modification

This PR is mostly changing code to avoid transferring handlers to and from the event loops in tests. This should be a no-op mostly.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2024-03-01 15:05:22 +00:00
Franz Busch 702cd7c56d Fix the typed HTTP upgrade compiler guards (#2594)
The compiler guards were unnecessarily complex and I also didn't cover 3 methods where we used the types.
2023-11-16 03:30:21 -08:00
Franz Busch c46199386c Revert "Back out new typed HTTP protocol upgrader (#2579)" (#2593)
* Revert "Back out new typed HTTP protocol upgrader (#2579)"

# Motivation
We have reverted the typed HTTP protocol upgrader pieces since adopters were running into a compiler bug (https://github.com/apple/swift/pull/69459) that caused the compiler to emit strong references to `swift_getExtendedExistentialTypeMetadata`. The problem is that `swift_getExtendedExistentialTypeMetadata` is not available on older runtimes before constrained existentials have been introduced. This caused adopters to run into runtime crashes when loading any library compiled with this NIO code.

# Modifications
This PR reverts the revert and guard all new code in a compiler guard that checks that we are either on non-Darwin platforms or on a new enough Swift compiler that contains the fix.

# Result
We can offer the typed HTTP upgrade code to our adopters again.

* Add compiler guards
2023-11-15 18:58:27 +00:00
Franz Busch 8c238f2cc1 Back out new typed HTTP protocol upgrader (#2579)
# Motivation
We got reports in https://github.com/apple/swift-nio/issues/2574 that our new typed HTTP upgrader are hitting a Swift compiler bug which manifests in a runtime crash on older iOS/macOS/etc.

# Modification
This PR backs out the new typed HTTP protocol upgrader APIs so that we can unblock our users until the Swift compiler bug is fixed.

# Result
No more crashes for our users.
2023-10-27 15:48:23 +01:00
hamzahrmalik a41b02c580 Avoid terminating when a precondition is not met in HTTPServerPipelineHandler (#2550)
* Avoid terminating when a precondition is not met in HTTPServerPipelineHandler

* Address review comments

* rename precondition to assertion

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-10-18 06:26:43 -07:00
Franz Busch f38b7fd38a Remove SPI from NIOAsyncChannel, new bootstrap methods, protocol negotiation and HTTP upgrade. (#2548)
# Motivation
Over the past months, we have been working on new async bridges to make using NIO's `Channel` from Swift Concurrency possible. Since this work was far reaching we have opted to land all of it as SPI. Now the time has come and we feel confident enough to make the SPI official API. This comes after testing the new APIs in various scenarios such as HTTP 1&2, HTTP upgrades, protocol negotiation and in benchmarks.

# Modification
This PR removes the SPI from the `NIOAsyncChannel`, the bootstrap methods, protocol negotiation and HTTP upgrade.

# Result
Everyone can use the our new APIs🚀
2023-10-17 14:14:02 +01:00
Franz Busch 0fb8cb7947 Add docs for the async NIO APIs (#2549) 2023-10-16 15:02:43 +01:00
Franz Busch 4ab8b98f9d Introduce new typed HTTPClientUpgrader and WebSocketClientUpgrader (#2526)
* Introduce new typed `HTTPClientUpgrader` and `WebSocketClientUpgrader`

# Motivation
In my previous PR https://github.com/apple/swift-nio/pull/2517, I added a new typed `HTTPServerUpgrader` and corresponding implementation for the `WebSocketServerUpgrader`. The goal of those is to carry type information across HTTP upgrades which allows us to build fully typed pipelines.

# Modification
This PR adds a few things:
1. A new `NIOTypedHttpClientUpgradeHandler` + `NIOTypedHttpClientProtocolUpgrader`. I also moved the state handling to a separate state machine. Similar to the server PR I did not unify the state machine between the newly typed and untyped upgrade handlers since they differ in logic.
2. A new `NIOTypedWebSocketClientUpgrader`
3. An overhauled WebSocket client example.

# Result
This is the last missing piece of dynamic pipeline changing where we did not carry around the type information. After this PR lands, we can finalize the `AsyncChannel` and async typed NIO pieces.

* Remove availability on the protocols
2023-10-06 16:33:25 +01:00
David Nadoba d367dc0a87 Tolerate empty HTTP response body parts (#2531)
* Tolerate empty HTTP response body parts

### Motivation

Empty HTTP response body parts currently eagerly end a response. This is unexpected and against NIOs documented behaviour.

### Modification

- add test which send an empty response body part and would previously fail
- skip empty response body parts

### Result

Users can send empty body parts without ending the response.

* add comment explaining why we do it here instead of fixing it at the source

* move empty body part logic to `writeChunk`
2023-10-04 06:42:26 -07:00
Franz Busch de07e573d6 Introduce new typed HTTPServerUpgrader and WebSocketServerUpgrader (#2517)
* Introduce new typed `HTTPServerUpgrader` and `WebSocketServerUpgrader`

# Motivation
With our new `NIOAsyncChannel` and typed bootstrap APIs we want to be able to let users spell out their pipeline in a typed way. Pipelines can contain handlers that have to make a forking decision such as HTTP upgrading. Our current `HTTPServerUpgradeHandler` is one of those handlers but it lacks strict typing. To interact nicely with our new typed APIs we need to have a new variant of the `HTTPServerUpgradeHandler` that can carry type information.

# Modification
This PR adds a few things:
1. A new `NIOTypedHTTPServerUpgradeHandler` + `NIOTypedHTTPServeProtocolUpgrader`. I also moved the state handling logic to a separate state machine. I thought about unifying the state machines of the _old_ handler and the new one but they differ in behaviour which makes the state machine more complicated.
2. A new `NIOTypedWebSocketServerUpgrader` that conforms to `NIOTypedHTTPServerProtocolUpgrader`
3. An overhauled WebSocket server example that fully uses Concurrency.

# Result
We now have a way to fully type the server side of HTTP protocol upgrading.

Code review

Update parameter names for new API and fix example

* Introduce new configuration struct and rename to `UpgradablePipeline`

* Review comments
2023-10-02 07:26:16 -07:00
Rick Newton-Rogers 67553a7d6d Bump minimum Swift version to 5.7 (#2524)
* Bump minimum Swift version to 5.7

Motivation:

Now that Swift 5.9 is GM we should update the supported versions and
remove 5.6

Modifications:

* Update `Package.swift`
* Remove `#if swift(>=5.7)` guards
* Delete the 5.6 docker compose file and make a 5.10 one
* Update integration test script
* Update docs

Result:

Remove support for Swift 5.6, add 5.10

* fix indentation issues

* 5.9 docker image use release image
2023-10-02 11:38:07 +01:00
Alex Taffe e0d85543d7 Simplify header separator and crlf (#2513)
Everywhere else in the file uses `crlf` and `headerSeperator` when writing those static strings, we shouldn't be using string literals here
2023-09-06 14:52:25 +01:00
Cory Benfield 7d9f892d83 Support users opting-out of us setting framing headers. (#2508)
Motivation:

Right now we always set the framing headers in HTTP requests and
responses that we send. This is a good practice for most users, but
it can cause issues, most notably in responses to CONNECT requests
which requires that we do not set framing headers.

Unfortunately, in NIO's current HTTP/1.1 design it is not possible
for us to suppress these headers. This is because the HTTP encoders
come _earlier_ in the pipeline than the decoders, so the HTTP
encoders do not know structurally what requests they are responding
to.

While we could merge the encoders/decoders, that's a fairly
substantial change. A better short-term change is to offer users
the ability to turn off the NIO header manipulation feature. In
this circumstance, users take on full responsibility for
appropriately framing their HTTP messages.

Modifications

- Add config to HTTPRequestEncoder and HTTPResponseEncoder.
- Plumb this config through.
- Add a bunch of tests.

Result

Users have way more control of HTTP/1.1 messages.
2023-08-22 02:51:05 -07:00
Cory Benfield 2d8e6ca36f Tolerate sending data after close(mode: .output) (#2421)
Motivation

We shouldn't crash on somewhat likely user error.

Modifications

Pass on writes after close(mode: .output) instead of crashing.

Result

User code is more robust to weird edge cases.
2023-05-09 10:52:48 +01:00
Cory Benfield 5f8b0647e4 Handle close(output) in the pipeline handler. (#2414)
Motivation:

Currently the server pipeline handler ignores close. This generally works,
except in the rare case that the user calls close(mode: .output). In this
instance they have signalled that they'll never write again, and they're
likely expecting a final close shortly after.

However, it is possible that the pipeline handler has suspended reads
at the same time. On Linux this isn't an issue, because we'll still be told
about the eventual socket close. However, on Apple platforms we won't: we've
masked off the reads, and we can't listen to EVFILT_EXCEPT due to some
other issues. This means that on Apple platforms the server pipeline handler
can accidentally wedge the Channel open and prevent it from closing.

We should take this opportunity to have the server pipeline handler be smart
about close(mode: .output). What _should_ happen here is that the pipeline
handler should immediately refuse to deliver further requests on the Channel.
If one is in-flight, it can continue, but everything else should be dropped.
This is because the server cannot possibly respond to further requests.

Modifications:

- Add new states to the server pipeline handler
- Drop buffered requests and new data after close(mode: .output)
- Add tests

Result:

Server pipeline handler behaves way better.
2023-04-28 06:22:07 -07:00
David Nadoba 6720612111 Drop Swift 5.5 (#2406)
* Drop Swift 5.5

* Use `swift-atomics` 1.1.0 with `Sendable` adoption
2023-04-17 08:40:35 +01:00
George Barnett 73eb597aa3 Don't unconditionally remove the HTTPServerUpgradeHandler (#2303)
Motivation:

The `HTTPServerUpgradeHandler` removes itself from the pipeline after an
upgrade and unbuffers any unconsumed reads. If an upgrade starts but
does not complete successfully then the pipeline may be left in an
unknown state.

If, for example, the failure occurs before the user provided upgrade
handler is run then unbuffered writes may be unwrapped by the wrong
channel handler as the wrong type leading to a crash.

Modifications:

- Only remove the upgrade handler and forward buffered writes if all
  parts of the upgrade complete successfully.
- If part of the upgrade fails then fire an error into the channel
  pipeline without removing the server upgrade handler.
- Remove a few unnecessary `map`s.
- Make `httpEncoder` non-optional since and remove associated dead code
  since it can never be `nil`.

Result:

Upgrade handling is safer.
2022-10-28 07:32:43 -07:00
David Nadoba 16b5b2b793 Replace NIOSendable with Sendable (#2291) 2022-10-13 15:56:27 +01:00
David Nadoba c7b4989b02 Remove #if compiler(>=5.5) (#2292)
### Motivation
We only support Swift 5.5.2+.

### Modification
Remove all `#if swift(>=5.5)` conditional compilation blocks.

### Result
less branching
2022-10-13 07:17:46 -07:00
Cory Benfield 5aa44987f8 Correctly manage Content-Length on HEAD responses (#2277)
Motivation

When we receive a HEAD response, it's possible that the response
contains a content-length. llhttp has a bug
(https://github.com/nodejs/llhttp/issues/202) that prevents it from
properly managing that issue, which causes us to incorrectly parse
responses.

Modifications

Forcibly set llhttp's content-length value to 0.

Result

Correctly handle HTTP framing around llhttp's issues.
2022-10-04 06:59:57 -07:00
Cory Benfield a16e2f54a2 Merge pull request from GHSA-7fj7-39wj-c64f
Motivation

HTTP headers are prevented from containing certain characters that can
potentially affect parsing or interpretation. Inadequately policing this
can lead to vulnerabilities in web applications, most notably HTTP
Response Splitting.

NIO was insufficiently policing the correctness of the header fields we
emit in HTTP/1.1. We've therefore added a new handler that is
automatically added to channel pipelines that will police the validity
of header fields.

For projects that are already running the validation themselves, this
can be easily disabled. Note that by default NIO does not validate
content length is correctly calculated, so applications can have their
framing fall out of sync unless they appropriately calculate this
themselves or use chunked transfer encoding.

Modifications

- Add thorough unit testing to confirm we will not emit invalid header
  fields.
- Error if a user attempts to send an invalid header field.

Result

NIO applications are no longer vulnerable to response splitting by CRLF
injection by default.
2022-09-27 13:09:52 +01:00
Cory Benfield 3cfd8ac5d9 Add support for newer LLHTTP status codes (#2269)
Motivation:

We should better tolerate LLHTTP status codes we don't yet know about.

Modifications:

- Added support for the status codes that currently exist
- Add a fallback to the RAW case for the future.

Result:

Better management of LLHTTP status codes
2022-09-16 08:33:40 -07:00
Cory Benfield 6918034260 Update HTTP parser to LLHTTP (#2263)
Motivation:

The node.js HTTP parser library that we use has been unmaintained for some time. We should move to the maintained replacement, which is llhttp. This patch will update our dependency and bring us over to the new library, as well as make any changes we need.

Modifications:

This patch comes in 4 parts, each contained in a separate commit in the PR.

The first commit drops the existing http_parser code and updates some of the repo state for using llhttp.
The second commit rewrites the update script to bring in llhttp instead of http_parser.
The third runs the actual script. You can skip reviewing this except to sanity check the outcome.
The fourth commit updates the NIO code and the tests to get everything working.

In general the substance of the product modifications was minimal. The logic around keeping track of where we are in the buffer and how upgrades work has changed a bit, so that required some fiddling. I also had to add an error reporting path for the delegates to be able to throw specific errors that llhttp no longer checks for. Finally, I removed two tests that were a little overzealous and that llhttp does not police.

Result:

Back on the supported path.
2022-09-13 14:09:57 +01:00
carolinacass 028cf7e606 HTTPResponseStatus should print code and reason (#2257)
* HTTPResponseStatus should print code and reason

* Update HTTPResponseStatusTests+XCTest.swift

Co-authored-by: Carolina Cassedy <ccassedy@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-08-31 05:37:08 -07:00
David Nadoba 1100054107 Functions passed to non-Sendable ChannelHandlers do *not* need to be Sendable (#2249) 2022-08-26 17:59:34 +02:00
David Nadoba b4e0a274f7 Fix compilation with Swift 5.5.0 and 5.5.1 (#2234) 2022-08-04 02:22:47 -07:00
David Nadoba 927b91a1e7 Adopt Sendable for closures in HTTPClientUpgradeHandler.swift and HTTPServerUpgradeHandler.swift (#2216)
* Adopt `Sendable` for closures in `HTTPPipelineSetup.swift`

* make `UnsafeTransfer` and `UnsafeMutableTransferBox` available in Swift 5.4 too

* fix code duplication

* Copy `UnsafeTransfer` to `NIOHTTP1Tests` to be able to remove `@testable` from `NIOCore` import

* Adopt `Sendable` for closures in `HTTPServerUpgradeHandler.swift`

* Adopt `Sendable` for closures in `HTTPClientUpgradeHandler.swift`
2022-07-05 02:42:29 -07:00
David Nadoba 8c922223db Adopt Sendable for closures in HTTPPipelineSetup.swift (#2214)
* Adopt `Sendable` for closures in `HTTPPipelineSetup.swift`

* make `UnsafeTransfer` and `UnsafeMutableTransferBox` available in Swift 5.4 too

* fix code duplication

* Copy `UnsafeTransfer` to `NIOHTTP1Tests` to be able to remove `@testable` from `NIOCore` import
2022-07-05 10:01:04 +01:00
David Nadoba 0abf7eb929 Adopt Sendable for types in NIOHTTP1 (#2213) 2022-07-04 00:37:23 -07:00
Franz Busch aae5fd056c Add Hashable conformance to HTTPResponseStatus (#2069)
# Motivation
`HTTPResponseStatus` is currently not conforming to `Hashable`.

# Modification
Add `Hashable` conformance to `HTTPResponseStatus`

# Result
`HTTPResponseStatus` is `Hashable`
2022-03-23 15:39:44 +00:00