Commit Graph

123 Commits

Author SHA1 Message Date
Johannes Weiss a296f30e45
OnLoopSendable: Sendable containers if on EventLoop (#2370)
Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-02-27 07:11:37 -08:00
George Barnett 4dfae01cc6
Add a pooled recv buffer allocator (#2362)
Motivation:

Channels can read `ChannelOptions.maxMessagesPerRead` times from a
socket in each read cycle. They typically re-use the same buffer for
each read and rely on it CoWing if necessary. If we read more than once
in a cycle then we may CoW the buffer. Instead of reusing one buffer we
can reuse a pool of buffers limited by `maxMessagesPerRead` and cycle
through each, reducing the chance of CoWing the buffers.

Modifications:

- Extend `RecvByteBufferAllocator` to provide the size of the next
  buffer with a default implementation returning `nil`.
- Add an recv buffer pool which lazily grows up to a fixed size and
  attempts to reuse buffers where possible if doing so avoids CoWing.

Results:

Fewer allocations
2023-02-20 17:00:19 +00:00
David Nadoba 810544ec41
Add `RawSocketBootstrap` (#2320) 2022-12-01 15:35:04 +01:00
George Barnett edfceecba1
Add utilties for reading and writing UUIDs (#2045)
Motivation:

UUIDs are often sent over the wire but writing and reading their bytes
to/from a buffer is a bit of a pain.

Modifications:

- Add utilties to 'NIOFoundationCompat' for reading/writing and
  getting/setting a UUID on a `ByteBuffer`.

Result:

Easier to write/read UUIDs to/from a buffer.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-10-31 06:25:28 -07:00
Cory Benfield 522f08ca68
Move 5.7 beta APIs to NIOCore (#2300)
Motivation:

As 5.7 has shipped we no longer need to keep these APIs in _NIOBeta.
We're going to do a two-stage removal: first we're going to move the
APIs to NIOCore and keep them in _NIOBeta with deprecations on them. In
a later release, we'll remove the APIs from _NIOBeta entirely.

Modifications:

- Move the TimeAmount + Duration APIs to NIOCore
- Deprecate the APIs in _NIOBeta.

Result:

We're on a path to remove _NIOBeta
2022-10-25 15:38:47 +01:00
George Barnett fcca969463
Raise minimum supported Swift version from 5.4 to 5.5 (#2267)
Motivation:

SwiftNIO periodically drops support for older Swift versions. Now that
5.7 has been released, 5.4 will be dropped.

Modifications:

- Remove 5.4 specific Package.swift and docker-compose
- Update the 5.7 docker-compose to use the released 5.7 and move from
  focal (2004) to jammy (2204)
- Remove unused swiftformat from Dockerfile
- Update tools version in syscall wrapper tests to 5.5
- Update docs

Results:

Minimum Swift version is 5.5
2022-09-29 11:47:44 +01: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
Johannes Weiss f16991836d
helpful error message when compiling without test discovery on >= Swift 5.5 (#2264) 2022-09-07 15:49:48 +01:00
Cory Benfield f5448fbbc2
Provide NIOAsyncTestingChannel (#2238)
Motivation

Testing versions of NIO code that involve interfacing with Swift
Concurrency is currently a difficult business. In particular,
EmbeddedChannel is not available in Swift concurrency, making it
difficult to write tests where you fully control the I/O.

To that end, we should provide a variation of EmbeddedChannel that makes
testing these things possible.

Modifications

Provide an implementation of NIOAsyncTestingChannel.

Results

Users can write tests confidently with async/await.
2022-08-10 11:09:56 +01:00
Cory Benfield bedb9fe613
Enhance and rename AsyncEmbeddedEventLoop (#2224)
* Enhance and rename AsyncEmbeddedEventLoop

Motivation

AsyncEmbeddedEventLoop is an important part of our ongoing testing story
for NIO. However, it suffers from two problems.

The first is a usability one. As we discovered during the original
implementation, following EmbeddedEventLoop's pattern of not having any
EventLoop "Tasks" execute until run() meant that simple constructs like
`EventLoopFuture.wait` and `EventLoopFuture.get` didn't work at all,
forcing us to add an annoying `awaitFuture` method.

When playing with implementing EmbeddedChannel, this got worse, as I/O
methods also don't run immediately if called from the testing thread. We
couldn't easily work around this issue, and it meant that common
patterns (like calling `channel.writeAndFlush`) would deadlock!

This is unacceptable, so a change had to be made.

While we're here, we received feedback that the name is unclear to
users. Given that this particular event loop is in no sense "embedded",
we no longer need the name, so we can take this opportunity to use a
better one.

Modifications

Changed `func execute` to immediately execute its task body, and to
dequeue all pending tasks at this time. Essentially, it's the equivalent
to run(). This is a major change in its behaviour.

Renamed the loop to `NIOAsyncTestingEventLoop`.

Result

Better names, easier to use.

* Make soundness happy

* Remove awaitFuture
2022-07-27 08:03:06 +01:00
Si Beaumont 4588691a1a
Provide conversion APIs between TimeAmount and Swift.Duration (#2191)
* Provide conversion APIs between TimeAmount and Swift.Duration

Signed-off-by: Si Beaumont <beaumont@apple.com>

* fixup: Remove unnecessary overflow check

Signed-off-by: Si Beaumont <beaumont@apple.com>

* fixup: Move into new _NIOBeta57 module

Signed-off-by: Si Beaumont <beaumont@apple.com>

* fixup: Rename _NIOBeta57 module to _NIOBeta and move tests to own target

Signed-off-by: Si Beaumont <beaumont@apple.com>

* soundness: copyright years for some reason

Signed-off-by: Si Beaumont <beaumont@apple.com>
2022-06-14 14:38:17 +01:00
Cory Benfield ad8500b3d0
Define AsyncEmbeddedEventLoop (#2083)
Motivation

The rise of Swift concurrency has meant that a number of our APIs need
to be recontextualised as async/await capable. While generally this is a
straightforward task, any time those APIs were tested using
EmbeddedChannel we have a testing issue. Swift Concurrency requires the
use of its own cooperative thread pool, which is completely incapable of
safely interoperating with EmbeddedChannel and EmbeddedEventLoop. This
is becuase those two types "embed" into the current thread and are not
thread-safe, but our concurrency-focused APIs want to enable users to
use them from any Task.

To that end we need to develop new types that serve the needs of
EmbeddedChannel and EmbeddedEventLoop (control over I/O and task
scheduling) while remaining fully thread-safe. This is the first of a
series of patches that adds this functionality, starting with the
AsyncEmbeddedEventLoop.

Modifications

- Define AsyncEmbeddedEventLoop

Result

A required building block for AsyncEmbeddedChannel exists.

Co-authored-by: Franz Busch <privat@franz-busch.de>
2022-05-04 09:03:03 -07:00
David Nadoba 4f2c6a3e0b
Add `collect(upTo:) -> ByteBuffer` and variations to `AsyncSequence` (#2038) 2022-02-03 10:31:09 -08:00
Franz Busch acbd697113
Conform `AddressedEnvelope` conditionally to `Hashable` & `Equatable` (#2017)
### Motivation:

Sometimes, it is nice to check `AddressedEnvelope`s for equality or hash them. Especially, in tests this comes in handy.

### Modifications:

This PR, adds conditional conformances to `AddressedEnvelope` for `Equatable` and `Hashable` depending on its generic `DataType` .

I also added a new module `NIOCoreTests` which was an open todoleft from the creation of the `NIOCore` module. To not add more tests that we have to migrate in the future, I started to create the new tests in the new module right away. I also created issue https://github.com/apple/swift-nio/issues/2016, to keep track of our open task to move the other tests over.

### Result:

`AddressedEnvelope` is conditionally `Equatable` and `Hashable`
2021-12-20 10:22:13 -08: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 f2ab9ab422
Move EmbeddedChannel to its own library. (#1933)
Motivation:

EmbeddedChannel is an important testing tool, and we want to use it
without needing to bring along the POSIX layer. They are not tightly
coupled. However, it also doesn't belong naturally in NIOCore, so we
should probably put it in its own place.

Modifications:

- Moved EmbeddedChannel and EmbeddedEventLoop to NIOEmbedded.
- Moved the tests to NIOEmbeddedTests
- Duplicated some test helpers

Result:

Easy to use EmbeddedChannel without the POSIX layer.
2021-08-11 10:50:32 +01:00
Cory Benfield d62c733653
Extract PriorityQueue to its own module. (#1932)
Motivation:

I'd like to move EmbeddedChannel and friends out of the main NIO
repository and into their own module. Unfortunately, EmbeddedChannel
shares the PriorityQueue implementation we wrote with the various POSIX
channels. To avoid duplicating the code, we should pull it out to its
own module.

However, we've never wanted to commit to the API of this data structure,
and the same is true now. To that end, I'm pulling it into an
underscored module that is not a product of the package.

We could have used the `@_spi` annotation here but honestly I'm a bit
nervous about doing that at the low-level of NIO itself, as if the Swift
team does change the spelling of it at any point in the future we'll be
in real trouble. This way works almost as well, and makes our intent a
lot clearer.

Modifications:

- Extracted Heap and PriorityQueue to a new module.
- Made everything @inlinable to do our best to make performance
  acceptable.

Result:

We can re-use PriorityQueue.
2021-08-09 11:00:03 +01:00
Matt Eaton 4c0c5e555c
issue-1891: API Addition for JSONSerialization in NIOFoundationCompat (#1906)
Motivation:

Issue for #1891 to add JSONSerialization in NIOFoundationCompat.

Modifications:

Adds:
JSONSerialization+ByteBuffer.swift
JSONSerialization+ByteBufferTest.swift
JSONSerialization+ByteBufferTest+XCTest.swift

Result:

Support for transforming byteBuffer data to a Foundation object.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2021-07-26 14:21:42 +01:00
David Nadoba 906d5c554b
Add ByteBuffer.writeLengthPrefixed (#1902)
A convenience method to write a message and prepend its length in front of it.

### Motivation:
Many protocols use a length field to split a byte stream into multiple separate messages. `swift-nio-extras` supports these kind of protocols through `LengthFieldPrepender` and friends. However, sometimes a channel handler is not the right tool, especially if the a message itself contains multiple dynamic length fields. One example is [RSocket Routing Metadata Extensions](https://github.com/rsocket/rsocket/blob/master/Extensions/Routing.md). 

A `ByteBuffer` is probably a better tool to create this message. This can be tricky to get right if strings are part of the message. A naive solution like the following has two issues:
```swift
func add(tag: String, to buffer: inout ByteBuffer) {
    let length = tag.count
    buffer.writeInteger(UInt8(length))
    buffer.writeString(tag)
}
```
The `count` property in Swift is different than in most other languages. It does **not** return the number of UTF-8 code points and can result in incorrect behavior if multi-byte characters are used (e.g. Emojis). Furthermore, the size of the string could be larger than `UInt8` can represent.
### Modifications:

This PR introduces a new method on `ByteBuffer` called `writeLengthPrefix(endianness:as:writeMessage:)`. It solves both problems mentioned above. It first reserves space for the length prefix and delegates the actually writing of the message to `writeMessage`. Afterwards, it counts how many bytes were written during the call to `writeMessage` and then sets it on the previously reserved space in front of the actually message.

### Result:
We can now write arbitrary content to a buffer and prefix it with the number of bytes written.
```swift
func add(tag: String, to buffer: inout ByteBuffer) {
    buffer.writeLengthPrefix(as: UInt8.self) { buffer in
        buffer.writeString(tag)
    }
}
```
2021-07-22 18:22:08 +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
David Nadoba 465f87dd7c
Random WebSocket Request Key (#1855)
* add randomRequestKey method

* fix some typos

* fix compilation on 5.0

* run generate_linux_tests.rb

* add test with default random number generator

* @inlineable

* base64Encoding @inlineable
2021-05-24 16:02:16 +01:00
David Nadoba 4ded06871a
Add method to generate a random mask (#1824)
* add static method to generate a random mask

* use SystemRandomNumberGenerator by default and add documentation

* use WebSocketMaskingKey instead of Self to support Swift 5.0

* add tests for random masking key

* add return keyword to support Swift 5.0

* run scripts/generate_linux_tests.rb

* rename T to Generator

* test SystemRandomNumberGenerator

* Revert "test SystemRandomNumberGenerator"

This reverts commit d9bdbe57ac.

* work around thread sanitizer bug on Swift 5.3
2021-05-24 10:12:36 +01:00
David Nadoba 6befe13e23
WebSocket Frame Aggregator (#1823)
* implement and test WebSocketFrameAggregator

* add documentation

* fix review comments

* run scripts/generate_linux_tests.rb

* fix Swift 5.0

* move redundant channel creation into init

* create channel in setUp

* wrap all trys in XCTAssertNoThrow

* cache accumulatedFrameSize

* accumulate buffered frames into the first frames data buffer

* Revert "accumulate buffered frames into the first frames data buffer"

This reverts commit 0f83823f95.

* use channel allocator
2021-04-30 15:39:24 +01:00
Cory Benfield c6fc49a84a
Reduce selector wakeups. (#1820)
Motivation:

Right now all tasks scheduled onto an event loop from a different loop
wake up the underlying selector by writing to an eventfd. This is a
fairly inefficient way to handle things: it incurs a lot of syscall
traffic unnecessarily.

Given that we currently protect the pending tasks queue with a big dumb
lock, we can safely keep track of whether we're going to dequeue this
task. If we are, we don't need to wake the selector.

Modifications:

- Keep track of whether we're de-queueing tasks or not.
- Arrange to wake the selector only once.

Result:

Cheaper task enqueueing on hot loops.
2021-04-28 15:09:07 +01:00
Johannes Weiss 06ce11fb82
generic integer bit packing (#1807)
Motivation:

With the registration ID refactoring (#1801) we'll now have the third
reimplementation of integer bit packing. Three is one too many, let's
make it generic.

Modifications:

Introduce generic integer bit packing and use it for _UInt56/24.

Result:

- Less bit packing code.
- Will simplify #1801
2021-04-22 15:02:47 +01:00
buttaface 44d67ba4e0
Update and finish Android port. (#1695)
Motivation:

Be able to run and test swift-nio on Android.

Modifications:

- Remove the custom ifaddrs and use the one from the Android NDK instead.
- Enable a bunch of conditionally-compiled code for Android.
- Add a handful of constants and other Android declarations.
- Cast some types because of mismatches specific to Android.

Result:

Most tests pass on Android AArch64 and ARMv7.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-11-27 11:16:11 +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
Graeme Jenkinson b5c1696033
Provide a convenience API for dispatching blocking work (#1563) (#1662)
Motivation:

SwiftNIO lacks a convenience API for performing blocking IO / tasks. As
this is a fairly common task it then requires the clients to make ad hoc
implementations that address this requirement.

Modifications:

Extension to DispatchQueue with the following method to schedule a work
item to the `DispatchQueue` and return and `EventLoopFuture` for the
result returned:

- `asyncWithFuture<NewValue>(eventLoop: EventLoop, _ callbackMayBlock: @escaping () throws -> NewValue) -> EventLoopFuture<NewValue>`

Added new unit tests for this function both when the promise succeeds
and fails.

Extention to EventLoopFuture with the following public functions:

- `flatMapBlocking<NewValue)(onto queue DispatchQueue, _ callbackMayBlock: @escpaing (Value) throws -> NewValue) -> EventLoopFuture<NewValue>`
- `whenSuccessBlocking(onto queue DispatchQueue, _ callbackMayBlock: @escaping (Value) -> Void) -> EventLoopFuture<NewValue>`
- `whenFailureBlocking()onto queue DispatchQueue, _ callbackMayBlock: @escaping (Error) -> Void) -> EventLoopFuture<NewValue>`
- `whenCompleteBlocking(onto queue DispatchQueue, _ callbackMayBlock: @escaping (Result<Value, Error>) -> Void) -> EventLoopFuture<NewValue>`

These functions may all be called safely with callbacks that perform blocking IO / Tasks.

Added new unit tests to EventLoopFutureTest.swift for each new function.

Result:

New public API for `EventLoopFuture` that allows scheduling of blocking IO / Tasks.
2020-09-30 17:04:21 +01:00
Peter Adams a0f6a48ec0
Ensure ByteBufferViewProtocolTests are run on linux (#1618)
Motivation:

All tests should get run.

Modifications:

The script to locate linux tests only scans files with names ending with Test/Tests.
Change the filename to match this.

Result:

All tests are run now on linux.
2020-08-13 10:46:15 +01:00
Cory Benfield 8dfcb578fc
Support writing ContiguousBytes and DataProtocol to ByteBuffers (#1615)
Motivation:

Per SR-10219, Data does not implement withContiguousStorageWithAvailable
and the maintainers do not believe it can. This forces code that writes
Data into ByteBuffers into slow-paths. Given that Data conforms to
ContiguousBytes and DataProtocol, we can arrange to serve a number of
use-cases by providing fast paths for all conforming types. This makes
it easier to use types vended by other Foundation-using libraries, such
as Swift Crypto.

Modifications:

- Implement `writeContiguousBytes` and `setContiguousBytes`.
- Implement `writeData` and `setData` for `DataProtocol` implementations

Result:

Better support for writing `Data` and friends into `ByteBuffer`s.
2020-08-12 08:04:52 +01:00
Peter Adams f12803dbf1
Add methods to create and parse cmsghdr structured data. (#1590)
Motivation:

cmsghdrs can be used to send an receive extra data on UDP packets.
For example ECN data.

Modifications:

Map in Linux and Darwin versions of cmsghdr macros as functions.
Create strctures for holding a received collection; parsing ecn
data from a received collection and building a collection suitable
for sending.

Result:

Functions to manipulate cmsghdr and data exist.
2020-07-14 12:29:31 +01:00
George Barnett 8a25c0f5a0
Make `TimeAmount` `Hashable` (#1571)
Motivation:

TimeAmount wasn't `Hashable` and there's no clear reason it shouldn't
be.

Modifications:

Add synthesized `Hashable` conformance to `TimeAmount`

Result:

`TimeAmount` is hashable.
2020-06-24 12:31:05 +01:00
Gautier Delorme 0695662d7d
fix cores count in containers (#1518)
Motivation:

The current System.coreCount implementation relies on _SC_NPROCESSORS_ONLN so isn't cgroups aware which might have a bad impact for apps runnings in containers (e.g. Docker, Kubernetes, Amazon ECS...).

Modifications:

- Changed System.coreCount on Linux only to make it read from CFS quotas and cpusets when present.
- Removed incorrect precondition in Sources/NIO/LinuxCPUSet.swift

Result:

System.coreCount returns correct values when apps run in containers.

Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2020-05-15 10:09:35 +01:00
Johannes Weiss b2d937b22f
shorten NIOThreadPool's thread names (#1466)
Motivation:

Previously, NIOThreadPool would use super long thread names. Linux
doesn't allow more than 15 bytes (+ \0 char) so in the end they would
never get set at all.

Modifications:

- Shorten NIOThreadPool's thread names
- Only take the first 15 characters of thread names in general on Linux

Result:

We don't lose thread names on Linux.
2020-03-31 20:01:56 +01:00
Johannes Weiss 2ad77f9a9b
WIP: universal bootstrap (#1323)
Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-03-18 16:20:19 +00:00
Doug Friedman a4fe7d4840
get IOError down to git in an existential container (#1355) (#1376)
resolves #1355 shaving off some bytes from IOError struct

Motivation:

It's important for frequently used errors to fit in existential containers because otherwise throwing them leads to allocations.

Modifications:

- Don't store `StaticString`s anymore which are 2 words + 1 bytes wide

Result:

Fewer allocations when IOErrors are thrown.
2020-02-03 12:30:37 +00:00
Johannes Weiss 52a4cae14d
add SAL (Syscall Abstraction Layer) and new SALChannelTests
## Motivation:

In SwiftNIO's codebase, most things were always testable just as well as user code is. With one big missing piece: We could never make the `Selector` do arbitrary things to the `Channel` implementations which lead to super expensive to (create, read, understand) integration tests like [`testWriteAndFlushFromReentrantFlushNowTriggeredOutOfWritabilityWhereOuterSaysAllWrittenAndInnerDoesNot `](5dc9083c6a/Tests/NIOTests/StreamChannelsTest.swift (L468-L760)).

## Modification

Add SAL, a 'syscall abstraction layer' which makes it possible to assert all syscalls that come through a `Socket` or the `Selector` by mocking them. It lets the NIO programmer play the kernel in these "SAL tests" which makes it possible to assert the exact syscalls (with their parameters) and decide the syscalls' returns.

## Result

Finally, we're able to write proper unit tests for scenarios where the `Channel` drove the `Selector` incorrectly.
2020-01-28 12:36:36 +00:00
Richard Low 1f94a6e620 Out of pipeline byte stream decoding (#1268)
* Add NIOSingleStepByteToMessageDecoder and NIOSingleStepByteToMessageProcessor
for processing byte streams outside of the channel pipeline.

Motivation:

ByteToMessageHandler works well when you can embed it in your pipeline, but if
you have a wrapped protocol (e.g. sending a protocol over HTTP), you can't use
it without losing the context of the outer protocol (e.g. HTTP headers/trailers).

Modifications:

Added NIOSingleStepByteToMessageDecoder and NIOSingleStepByteToMessageProcessor.

Result:

New functionality above.
2019-12-03 11:29:38 +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
Johannes Weiss 8dd62cb068
ByteBuffer: add direct Codable support (#1153)
Motivation:

So far, it has been harder than necessary to use Codable & ByteBuffer.
These new APIs should simplify that and allow future optimisations.

Modifications:

Add new API to use `JSONEncoder` and `JSONDecoder` directly with
`ByteBuffer`.

Result:

Easier Codable + ByteBuffer usage.
2019-10-17 16:03:44 -07:00
Johannes Weiss e102aa9ae9
add PipeChannel (#1138)
Motivation:

There are use-cases for SwiftNIO where there are no actual sockets but
rather two pipe file descriptors - one for input, one for output.
There's no real reason why SwiftNIO shouldn't work for those.

Modifications:

Add a PipeChannel.

Result:

More use-cases for SwiftNIO.
2019-10-16 22:06:55 -07:00
Mario Sangiorgio 23303e7ce7 NIOHTTP1TestServer (#1152)
* NIOHTTP1TestServer implementation

* Test simple request and two concurrent requests

* Accepting multiple connections but keeping only one active at a time

* Linux tests

* Addressed some PR comments
2019-10-02 12:10:09 +01: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
Will Lisac 26586835fd Fail promise in MessageToByteHandler write error cases (#1096)
* Fail promise in MessageToByteHandler write error cases

* Add test case for MessageToByteHandler failing write promises
2019-08-08 10:33:00 +01:00
Liam Flynn 64c673b6e8 Add a WebSocket client upgrader. (#1038)
Motivation:

There is a client protocol upgrader but, unlike the server protocol upgrader, it does not have a WebSocket protocol as part of the project.

Modifications:

Made the magic WebSocket GUID public to the WebSockets project.
Added a NIOWebSocketClientUpgrader.
Added tests for the upgrader.
Updated the Linux test script files.

Result:

The project now has a WebSocket client upgrader to match the WebSocket server upgrader.
2019-07-08 03:55:02 -04:00
Liam Flynn 57785e6d9c An HTTP upgrader class for a client pipeline. (#1001)
* Reorder ‘channel active’ calls to the same order as `_ChannelInboundHandler` and their likely chronological order.

Motivation:
When first viewing the example classes, coming to the ‘read’ method first, leaves the subject unclear as to what the method is ‘reading’.
It is preferable to view something being sent first, and then to view the reading of the response.
It also matches the call order against the protocol making it a little easier for those unfamiliar with the protocol to see which methods have been implemented.

Modifications:
Moved channel active calls to be top of the class.
Despite the diff there are no actual code modifications.
UDP Client changed to indent using spaces to match rest of project. Incidental change.

Result:
The examples are slighter clearer to read, particularly for newcomers to swift-no as the calls are in a logical chronological order.

* Fix an error in the upgrader and its tests which checked the connection header incorrectly.

Motivation:
To correct the logic in the upgrader. Previously it checked if the upgraders required headers include the connection header. Now it checks that the connection header value was present as a separate header in the incoming request.
To prepare the class naming for the presence of a client upgrader.

Modifications:
Slight change in server upgrader handler logic with accompanying tests.
Renamed upgrader and test files to include the word ‘server’.
Ran the linux test script.

Result:
The server upgrader now checks for the presence of the connection header value as a header of its own.

* Rename WebSocketServer upgrader to make the naming clearer and make way for a client version.

Motivation:

To make the web socket upgrader naming clearer, particularly once we add a client version.

Modifications:

Rename WebSocketUpgrader too WebSocketServerUpgrader.

Result:

Improved clarity of naming on the web socket upgrader.

* Adds  correct naming conventions to NIOWebSocketServerUpgrader. Sets back an incorrect fix (non-fix).

* Move deprecation for NIOWebSocketServerUpgrader typealias out of API shims file.

* Makes HTTPEncoder removable.
Adds a client upgrade handler with tests.
Adds the ability to use a client upgrader to the client setup.
Initial linux file update.

* Allow assertContains to be accessed publicly, so that it can be used in the client side tests.

* Update tests to remove server upgrader from client tests.
Change client tests to use Embedded channel.
Update HTTPUpgradeConfiguration class name to be NIOHTTPServerUpgradeConfiguration
Few other small stylistic changes.

* Removed awaiting upgrader state.
Removed future from handle upgrade call as is synchronous.
Removed protocol iterator from handle upgrade call as is not required by the client.

* Ensure that the client handler calls for the HTTPPipeline are backwards compatible.
Ensure that incoming promises to the handler write call are completed.
Neaten the upgrade header formation to remove looping.
Improve the correctness of the upgrade error throwing.

* Update scripts to match new unit tests.

* Change the documentation for HTTPServerPipeline to remove nil options which have now been removed.

* Restore an incorrectly added server pipeline comment change and make it to the client pipeline instead.

* Raise the allocation limits in the docker images to allow the tests to pass.
2019-06-16 11:10:12 +01:00
Liam Flynn f5084352c6 Rename the EndToEndTests in the WebSocket project to WebSocketServerEndToEndTests. (#1032)
Motivation:

To make the web socket server end to end tests class more descriptive.
This will allow ‘WebSocketClientEndToEndTests’ or other end to end tests to be added at a later date.

Modifications:

Renames the class and filename for ‘EndToEndTests’ to ‘WebSocketServerEndToEndTests’

Result:

The nomenclature now allow for other end to end tests to be added.
2019-06-11 19:22:02 -07:00
Johannes Weiss ccc459a86e TestUtils: EventCounterHandler (#1005)
Motivation:

In many unit tests, it's important to count the events. So far we have
many many ad-hoc handlers to do so but having one that counts all events
would be handy.

Modifications:

Add `EventCounterHandler` to count all events travelling the
`ChannelPipeline`.

Result:

Easier unit testing
2019-05-17 14:09:03 +01:00
Johannes Weiss 5513bb202a
Create NIOTestUtils & add B2MD verifier (#939)
Motivation:

When writing B2MDs, there are a couple of scenarios that always need to
be tested: firehose feeding, drip feeding, many messages, ...

It's tedious writing those tests over and over again for every B2MD.

Modifications:

- Add a simple B2MD verifier that users can use in unit tests.
- Add a new, public `NIOTestUtils` module which contains utilities
  mostly useful for testing. Crucially however, it does not depend on
  `XCTest` so it can be used it all targets.

Result:

Hopefully fewer bugs in B2MDs.
2019-05-10 17:29:13 +01:00
Liam Flynn 993a3b7521 Update naming to allow for the easy addition of a HTTP client upgrader. (#983)
Motivation:

To make the web socket upgrader naming clearer, particularly once we add a client version.

Modifications:

Rename WebSocketUpgrader too WebSocketServerUpgrader.

Result:

Improved clarity of naming on the web socket upgrader.
2019-05-02 11:02:48 +01:00