Commit Graph

190 Commits

Author SHA1 Message Date
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
carolinacass af41276062
Use #fileID/#filePath instead of #file (#2306)
Motivation:

#fileID introduced in Swift 5.3, so no longer need to use #file anywhere

Modifications:

Changed #file to #filePath or #fileID depending on the situation
2022-11-03 16:43:13 +00: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 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 b99da5d3fe
Workaround `Sendable` warning from Swift 5.7 (#2225)
Workaround for https://github.com/apple/swift/issues/59911
```swift
/src/Tests/NIOHTTP1Tests/HTTPTest.swift:148:21: warning: 'buf' mutated after capture by sendable closure
                buf.writeString("\(c)")
```
The variable `buf` is mutated but only before being capture by the sendable closure.

All other warnings/errors are fixed with the latest Swift 5.7 toolchain
2022-07-21 18:20:49 +01: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
Fabian Fett addf69cfe6
Allow HTTP Server to send multiple informational heads before actual response head (#1985)
Co-authored-by: Helge Heß <devteam@zeezide.de>
Co-authored-by: Tobias Haeberle <tobias.haeberle@holidu.com>

Co-authored-by: Helge Heß <devteam@zeezide.de>
Co-authored-by: Tobias Haeberle <tobias.haeberle@holidu.com>
2021-11-09 10:20:51 +00:00
Fabian Fett 7a36304aa4
[HTTPDecoder] Decode informational http response head correctly (#1984)
Motivation:
- Currently http 1xx response heads are handled incorrectly

Modifications:
- Add an `InformationalResponseStrategy` that allows the user to specify whether http 1xx responses shall be forwarded or dropped. 
- Implement the necessary cases in `HTTPDecoder` and `BetterHTTPParser`

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-11-08 19:41:08 +01:00
George Barnett f475d152fb
Don't count CR or LF as whitespace when trimming canonical header values (#1954)
Motivation:

Follow up to https://github.com/apple/swift-nio/pull/1952#discussion_r707351015

The OWS rule from the HTTP semantics draft only considers 'SP' and
'HTAB' to be whitespace. We also (unnecessarily) consider CR and LF to
be whitespace.

Modifications:

- Remove CR and LF from the characters we consider to be whitespace
- Update tests

Result:

We no longer consider CR or LF to be whitespace when trimming
whitespace when producing the canonical form of header values.
2021-09-14 08:26:05 +01:00
Cory Benfield b05c6f2206
Move NIO to NIOPosix, make NIO a shell. (#1936)
Motivation:

The remaining NIO code really conceptually belongs in a module called
NIOPosix, and NIOCore should really be called NIO. We can't really do
that last step, but we can prepare by pushing the bulk of the remaining
code into a module called NIOPosix.

Modifications:

- Move NIO to NIOPosix
- Make NIO an umbrella module.

Result:

NIOPosix exists.
2021-08-16 16:50:40 +01:00
Cory Benfield 64285cbff2
Clean up dependencies and imports. (#1935)
Motivation:

As we've largely completed our move to split out our core abstractions,
we now have an opportunity to clean up our dependencies and imports. We
should arrange for everything to only import NIO if it actually needs
it, and to correctly express dependencies on NIOCore and NIOEmbedded
where they exist.

We aren't yet splitting out tests that only test functionality in
NIOCore, that will follow in a separate patch.

Modifications:

- Fixed up imports
- Made sure our protocols only require NIOCore.

Result:

Better expression of dependencies.

Co-authored-by: George Barnett <gbarnett@apple.com>
2021-08-12 13:49:46 +01:00
Matt Eaton 3873886ebd
issue-1036: Fix for dates on Linux test generation script. (#1894)
* issue-1036: Fix for dates on Linux test generation script.

Motivation:

Fix for issue-1036 to add a date or date range for the header.
These dates are derived from the git log on the file.

Modifications:

Parsing method to extract the date or date range from the git log
of the file.  This was added to generate_linux_tests.

Result:

Dynamic date or date range added to the file header.

* issue-1036: Added revised headers from generation script

* Regenerating dates on XCTests.

Motivation:

Addressing feedback from PR.

Modifications:

All of the XCTests now have -2021 as a header date attached to them.

Result:

Dates modified on the XCTests.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-07-13 14:31:01 +01:00
Johannes Weiss de3c2dba50
HTTP server upgrade tests: cosmetic improvements (#1763)
Motivation:

The HTTP server upgrade tests had unncessarily wide and also verbose
test assertions.

Modifications:

Rewrote them much simpler and narrowed what states are allowed.

Result:

- Neater code
- Works around https://bugs.swift.org/browse/SR-14253
2021-02-23 15:34:37 +00:00
Fabian Fett 76b4637122
Make language more welcoming (#1728) 2021-01-21 12:45:46 +00:00
Cory Benfield 8ea768b0b8 Add static vars for common HTTP versions (#1723)
Motivation:

I'm sick of typing `.init(major: 1, minor: 1)`.

Modifications:

- Added static vars for common HTTP versions.

Result:

Maybe I'll never type `.init(major: 1, minor: 1)` ever again.
2021-01-19 17:27:02 +00:00
Andrius e6b7d718a8
HTTPObjectAggregator implementation (#1664)
* HTTPServerObjectAggregator for requests

* Apply suggestions from code review

Co-authored-by: Cory Benfield <lukasa@apple.com>

* most of code review comments addressed

* tidy up state machine close

* bad line breaks

* more verbose error reporting

* removes expect:continue functionality due to #1422

* public type naming and error handling tweaks

* wrong expectation in test

* do not quietly swallow unexpected errors in channelRead

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-10-08 11:37:32 +01:00
Johannes Weiss 6046aaa629
forward #file to #filePath differently (#1560)
Motivation:

only works if done when _calling_ a function, not when defining one :|.

- https://github.com/apple/swift/pull/32445
- https://bugs.swift.org/browse/SR-12936
- https://bugs.swift.org/browse/SR-12934
- https://bugs.swift.org/browse/SR-13041

Modifications:

Silence #file to #filePath differently.

Result:

Hopefully at some point we get this working.
2020-06-18 15:12:11 +01:00
Johannes Weiss adeafa9ce1
remove fullFilePath() hack (#1544)
Motivation:

The fullFilePath() hack doesn't actually work
(https://bugs.swift.org/browse/SR-12934). This is expected behaviour so
currently, the only workaround would be to `#if` whole function bodies
which is a lot of work. Given that in Swift 5.3 `#file` == `#filePath`
still, we can just silence the warning for now.

Modifications:

- Replace `fullFilePath()` by `(#file)`.

Result:

- file locations working properly again.

Co-authored-by: George Barnett <gbarnett@apple.com>
2020-06-05 11:13:09 +01:00
Johannes Weiss e57122bd89
ByteBuffer: add convenience initialisers (#1533)
Motivation:

There are multiple sub-optimal ByteBuffer creation patterns that occur
in the wild. Most often they happen when people don't actually have
access to a `Channel` just want to "convert" a `String` into a
`ByteBuffer`. To do this, they are forced to type

    var buffer = ByteBufferAllocator().buffer(capacity: string.utf8.count)
    buffer.writeString(string)

Sometimes, they don't get the capacity calculation right or just put a
`0`.

Similar problems happen if NIO users want to cache a ByteBuffer in their
`ChannelHandler`. You will then find this code:

```swift
if self.buffer == nil {
    self.buffer = receivedBuffer
} else {
    var receivedBuffer = receivedBuffer
    self.buffer!.writeBuffer(&receivedBuffer)
}
```

And lastly, sometimes people want to append one `ByteBuffer` to another
without mutating the appendee. That's also cumbersome because we only
support a mutable version of `writeBuffer`.

Modifications:

- add `ByteBuffer` convenience initialisers
- add convenience `writeBuffer` methods to `Optional<ByteBuffer>`
- add `writeBufferImmutable` which doesn't mutate the appendee.

Result:

More convenience.

Co-authored-by: Cory Benfield <lukasa@apple.com>

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-06-04 21:02:11 +01:00
Johannes Weiss 8b05ba64b1
silence the #file used instead of #filepath warning (#1526)
Motivation:

Very recent versions of the Swift compiler complain if you pass `#file`
to a parameter that is defaulted to `#filePath`. You can silence the
warning by using `(#file)`. We cannot migrate to `#filepath` because we
support Swift 5.0 and 5.1 which don't have `#filepath` yet.

Modifications:

- replace all occurances of `#file` by a special (test `internal`)
  function `fullFilePath()` which gives you the full path and is defined
  differently depending on the compiler version.

Result:

No warnings even on the latest compiler versions.
2020-06-02 11:56:42 +01:00
Johannes Weiss c1d86289ed
HTTPEncoder: fix 0 length chunks (#1524)
Motivation:

Previously, if the user sent us a 0 length chunk, we would encode it as
`0\r\n\r\n` which means the _end_ of the body in chunked encoding. But
the end in NIO is send by sending `.end(...)`.

Modifications:

Don't write anything for 0 length writes.

Result:

More correct behaviour with 0 length body chunks.
2020-05-18 18:50:43 +01:00
Cory Benfield 30265d69a8
Adjust names of BSDSocket option values. (#1510)
Motivation:

The names of most of the BSD socket option values were brought over into
their NIO helper properties, with their namespace removed. This vastly
increases the risk of collision, particularly for things like TCP_INFO,
which just became .info.

Modifications:

- Added the prefixes back, e.g. `.info` is now `.tcp_info`.
- Renamed socket type `.dgram` to `.datagram`, as this is the nice clean
  API and we should use nice clean names.

Result:

Better APIs
2020-05-11 15:13:58 +01:00
David Evans 8da802c5eb
Add 5.3 CI (#1498) 2020-05-01 19:17:44 +01:00
Saleem Abdulrasool bcc180dab6
Add new `BSDSocket` namespace (#1461)
* NIO: Add new `BSDSocket` namespace

This starts the split of the POSIX/Linux/Darwin/BSD interfaces and the
BSD Socket interfaces in order to support Windows.  The constants on
Windows are not part of the C standard library and need to be explicitly
prefixed.  Use the import by name to avoid the `#if` conditions on the
wrapped versions.  This will allow us to cleanly cleave the dependency
on the underlying C library.

This change adds a `BSDSocket.OptionLevel` and `BSDSocket.Option` types
which allow us to get proper enumerations for these values and pipe them
throughout the NIO codebase.

* Apply suggestions from code review

Co-Authored-By: Cory Benfield <lukasa@apple.com>
2020-04-02 19:06:48 +01:00
Ludovic Dewailly fefd0c854f
Provides a means to control the underlying header storage capacity. (#1451)
Motivation:

It's not always possible to initialize `HTTPHeaders` with all the headers one needs to set. In such case, the underlying array will be expanded as and when needed upon headers being appended. `Array` provides the means to reserve capacity to optimize such use case. This PR exposes this functionality in `HTTPHeaders`.

Modifications:

Expose method `reserveCapacity(_ minimumCapacity: Int)` and computed variable `capacity: Int` in `HTTPHeaders` and added some tests.

Result:

Developers will be able to control the capacity of the underlying headers array as such:

```
var headers = HTTPHeaders()
headers.reserveCapacity(5)
```

Co-authored-by: Ludovic Dewailly <ldewailly@apple.com>
2020-03-16 17:47:34 +00:00
Johannes Weiss 8912d1a48b
tests: improve tests that are supposed to throw (#1430)
Motivation:

The

    do {
        try someOperation()
	XCTFail("should throw") // easy to forget
    } catch error as SomethingError {
        XCTAssertEqual(.something, error as? SomethingError)
    } catch {
        XCTFail("wrong error")
    }

pattern is not only very long, it's also very error prone. If you forget
any of the XCTFails, you might not tests what it looks like

    XCTAssertThrowsError(try someOperation) { error in
        XCTAssertEqual(.something, error as? SomethingError)
    }

is much safer and shorter.

Modifcations:

Do many of the above replaces.

Result:

Cleaner, shorter, and safer tests.
2020-03-03 18:14:49 +00:00
Johannes Weiss 4022c91507
test that massive chunked encoding chunks behave sensibly (#1407)
Motivation:

Was talking about chunked encoding with @adtrevor, so I thought let's
actually capture it in a test.

Modifications:

- add a test

Result:

- more tests
2020-02-19 13:24:24 +00:00
Cory Benfield bfde40cac8
Update http-parser for CVE. (#1387)
Motivation:

http-parser shipped a patche for node.js CVE-2019-15605, which allowed
HTTP request smuggling. This affected SwiftNIO as well, and so we need
to immediately ship an update to help protect affected users.

A CVE for SwiftNIO will follow, but as this patch is in the wild and
SwiftNIO is known to be affected we should not delay shipping this fix.

Modifications:

- Update http-parser.
- Add regression tests to validate this behaviour.

Result:

Close request smugging vector.
2020-02-10 16:44:44 +00:00
Johannes Weiss d220737da7
make more tests faster (#1367)
Motivation:

Some tests are slow (#1358), they should be faster.

Modifications:

Make more tests faster.

Result:

Faster test suite
2020-01-29 17:00:13 +00:00
Fabian Fett ea5a64978d Initializing HTTPMethod with String picks explicit value over catch all RAW(value) (#1329)
Motivation:

When initializing an `HTTPMethod` with a `String` we currently switch over all expected values to pick an explicit value, only to overwrite our found explicit value with a catchall `RAW(value: String)`. This doesn’t make a ton of sense. This went unnoticed because we use the conditional conformance on `RawRepresentable` to be `Equatable`. But `switch`es  don’t use the `Equatable` protocol to match enums. The issue is visible there.

Modifications:

Added a testcase with a switch that fails, if the `.RAW(value: String)` value is used for `”GET”`. Removed the final overwrite in HTTPMethod(rawValue: String). Therefore the test passes.

Result:

We can initialize the HTTPMethod with a String and get an explicit value.
2020-01-02 11:39:54 -05:00
Cory Benfield 4dd5586c4b HEAD and DELETE may have bodies. (#1314)
Motivation:

We incorrectly asserted that HEAD and DELETE may not have request
bodies, but they can, it's just unlikely.

Modifications:

Change the categorisation of HEAD and DELETE.

Result:

Better behaviour in unusual cases.
2019-12-18 18:41:43 +00:00
George Barnett 6761c87d1e Add first(name:) to HTTPHeaders (#1282)
Motivation:

In some cases you only expect (or care about) a single value for a
header. However, getting this value without allocating an array or
traversing the whole array requres using first(where:) provided by
Sequence. This is not very ergonomic as it requires users to do the
case-insensitive comparison and then exctact the value from the
HTTPHeaders. Additionally, users cannot use NIO's case insensitive
ASCII comparison.

Modifications:

- Provide a first(name:) method on HTTPHeaders which returns the value
  from the first header whose name is a case insentive match of the
  subscript parameter.

Result:

It's easier to get the first value from HTTPHeaders matching a given
name.
2019-12-06 16:31:38 +00:00
Jari (LotU) 198b84b01c Webhooks upgrade complete fix (#1280)
Motivation:

Fixes the bug described in #1279

Modifications:

Moved state change in NIOHTTPClientUpgradeHandler.performUpgrade to after firing buffered messages.

Result:

- The upgradeState will now only change to upgradeComplete after buffered reads are handeld.
- Fixes #1279
2019-12-04 12:04:05 +00:00
Johannes Weiss ee0ed3b129
fix a number of memory leaks in the test suite (#1157)
Motivation:

Memory leaks are bad, even in test suites.

Modifications:

Fix a number of memory leaks.

Result:

Fewer leaks.
2019-11-27 19:25:06 +00:00
Johannes Weiss c2c725044a
allow deprecated tests to test deprecated functionality (#1271)
Motivation:

It's important to also test deprecated functionliaty. One way of
achieving this without warnings is to also deprecate the tests that test
this deprecated functionality. Unfortunately, on Linux we need to
generate lists of tests which would then reference deprecated tests
(which gives us a warning).

Modifications:

Deprecate test suites and the main test runner all the way to the top so
never get warnings.

Result:

Possible to test deprecated functionlity without warnings.
2019-11-27 14:26:51 +00:00
Jake 8066b0f581 Add option to reserve writable capacity to writeWithUnsafeMutableBytes (#1105) (#1175)
Motivation:

writeWithUnsafeMutableBytes cannot tolerate arbitrarily large writes because it is not possible to resize the buffer by the time body receives the buffer pointer. This change provides an option for the user to reserve writable capacity before the pointer is passed to body.

Modifications:

Added a backward compatible optional parameter to writeWithUnsafeMutableBytes which can reserve writable capacity before the pointer is passed to body.

Result:

Additive change only. Users can optionally specify a minimum writable capacity when calling writeWithUnsafeMutableBytes.
2019-10-22 16:40:02 -07:00
Johannes Weiss 2fe1154d4f fix new Swift compiler warnings (#1170)
Motivation:

Very recent Swift compilers have more warnings.

Modifications:

Fix the warnings.

Result:

No warnings when compiling.
2019-10-19 13:09:29 -07:00
George Barnett a545d59c47 Fix creating HTTPResponseStatus from 418 (#1140)
Motivation:

I ran across a case in a test where `HTTPResponseStatus(statusCode: 418)`
unexpectedly returned a `.custom` response status.

Modifications:

- Add a missing `case` for creating a status from `418`
- Shuffled some of cases around so that they are correctly listed in the
  correct 2xx, 3xx, 4xx etc. sections

Result:

- `HTTPResponseStatus(statusCode: 418)` now returns `.imATeapot`
2019-09-13 15:28:40 +01:00
Johannes Weiss 8aa84453d4 HTTPServerUpgradeHandler: Tolerate futures from other ELs (#1134) 2019-09-09 18:03:40 +01:00
Johannes Weiss f98ed180e5
HTTPDecoder: don't deliver unsolicited responses (#1093)
Motivation:

Despite the fact that we already stopped delivering unsolicited
responses for the HTTP response decoder, there was a window where we
would deliver a second .head for a response that come without a request.

Modifications:

Don't deliver a second .head even if send together with a first, legit
response.

Result:

Being a HTTP client using NIO is now easier.
2019-08-06 17:39:38 +01:00
Cory Benfield 5d54458488 Deliver HTTPServerUpgradeHandler data on removal. (#1092)
Motivation:

There is currently a pair of windows in which it is possible for the
HTTPServerUpgradeHandler to buffer some data without replaying it. This
can happen if it is reentrantly called just after it finishes
unbuffering data, which is not great.

To avoid this, we move to execute this data delivery while we're
removing ourselves. This ensures that we are confident that we cannot be
reentrantly called after our last outcall, meaning we can be confident
of 100% data delivery.

Modifications:

- Moved delayed data delivery to removeHandler.

Result:

Less chance of quiet data loss
2019-08-05 16:07:19 +01:00
Konrad `ktoso` Malawski 0225a2bf22 nil out writeRecorder, same as all other fields in teardown (#1090)
Motivation:

Without niling out it may linger around once the last test has
completed, and keep some messages in memory which will not be inspected
anymore

Modifications:

nil out the writeRecorder same as all other fields are currently nilled
out

Result:

In case XCTest keeps the class around, not keeping around the messages
stored by the writeRecorder
2019-07-31 09:34:06 +01:00
Cory Benfield 2b1d7be0bc
Tolerate unsolicited HTTP responses. (#1084)
Motivation:

Right now NIO clients will crash in the (admittedly unlikely) event that
a HTTP server sends an unsolicited extra response on a connection. This
seems pretty unnecessary, and fairly graceless.

Modifications:

- Replace a forcible pop with an optional one.
- Added NIOHTTPDecoderError type.

Result:

Removed a crash that we definitely don't want.
2019-07-30 10:53:14 +01:00