Commit Graph

1906 Commits

Author SHA1 Message Date
Joshua Rutkowski 2f9ea47738
Conform TimeAmount to AdditiveArithmetic (#1691)
Conforms TimeAmount to AdditiveArithmetic.

Motivation:
TimeAmount does not support -=, +=. Sometimes it is useful to manipulate time amounts when building up a delay and if that iteration fails, we would want to delay += .milliseconds(5) to add 5 milliseconds to our delay and try again.

Modifications:
Conformed TimeAmount to AdditiveArithmetic: added a static zero property and required operators.

Result:
TimeAmount conforms to AdditiveArithmetic.

Co-authored-by: Josh <jrtkski@icloud.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-11-17 15:30:17 +00:00
jemmons 5939c78fca
Removes misleading docs for whenComplete (#1687)
Upon the addition of `Result` in the Swift standard library, apple/swift-nio#734
updated `EventLoopFuture.whenComplete(_:)` to pass a `Result<T, Error>` to
its `callback`, but the documentation still confusingly states:

> Unlike its friends… `whenComplete` does not receive the result of the
> `EventLoopFuture`.

This patch fixes that by removing the (now inaccurate) lines.
2020-11-11 19:23:22 +00:00
Saleem Abdulrasool 255f29d3f3
NIO: implement address resolution on Windows (#1684)
Windows has a slightly different API for address resolution.  Implement
the Windows path for addrinfo resolution.
2020-11-02 17:02:35 +00:00
Saleem Abdulrasool 245ce96490
NIO: implement network interface enumeration for Windows (#1647)
Partially implement network interface enumeration.  This is sufficient
to build up the structures for basic operations.  Although the interface
information is incomplete, this provides enough structure to continue
porting the rest of the NIO interfaces.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-10-28 16:20:02 +00:00
Peter Adams 91eab6d836
Add multiple channel handlers in a single async call. (#1683)
Motivation:

Curently adding multiple channel handlers makes a call to the
async version of addHandler for each handler resulting in
n+1 futures.  It feels better to use just one future and add
all the handlers synchoronously.

Modifications:

Change sync functions with take a promise to instead return a Result.
Feed this back until reaching addHandlers.

Result:

Multiple handlers can be added more quickly.
2020-10-27 16:14:51 +00:00
George Barnett 74bedaf43b
Add watchOS deployment to PodSpec build script (#1679)
Motivation:

We support watchOS 6+ with SwiftNIO Transport Services; as such we should
include watchOS as a deployment target for our CocoaPods.

Modifications:

- Add a watchOS deployment target to `build_podspecs.sh`
- Update docs

Result:

Users can deploy to watchOS 6+ with CocoaPods.
2020-10-21 09:00:01 +01:00
Saleem Abdulrasool 366850acdd
NIO: implement `sendmsg` and `recvmsg` on Windows (#1674)
`WSASendMsg` and `WSARecvMsg` are not directly accessible to use.
Instead, one must perform an IOCTL on the socket to retrieve the
extension point and then use that function pointer to perform the
operation.  Use this to implement the functionality on Windows.
2020-10-20 08:22:20 +01:00
Saleem Abdulrasool 20e63d07dc
NIO: extract control message handling into a separate protocol (#1678)
These are part of the BSD sockets APIs, but not directly related to the
socket interfaces.  Create an extension point to permit the different
platforms to shuffle their implementation into place.  This provides a
nicer spelling for the functions and enables the codepaths on Windows as
well.
2020-10-19 16:18:57 +01:00
Saleem Abdulrasool 1cdbf763fb
NIO: reflow some comments (NFC) (#1677) 2020-10-14 18:05:40 +01:00
Saleem Abdulrasool d8c5a5ec84
NIO: expose `LINGER` as a public type on Windows (#1675)
The Windows `LINGER` type is meant to be exposed as it is a low-level
system detail for `SocketChannelOptions`.  See #1673 for relevant
discussion.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-10-14 08:54:37 +01:00
Saleem Abdulrasool 70ca7aad2b
NIO: silence error on Windows (#1668)
The `ignoreSIGPIPE` does nothing on Windows.  However, add an overload
to differentiate between a socket and file descriptor as they may be
different.  This is the case on Windows, where file descriptors are
32-bit but socket are 64-bit.

fixup! e51406c61972420c43734b1d089712bc408e097b
2020-10-14 08:25:28 +01:00
Saleem Abdulrasool 8e59cd159e
NIO: carve away more of `System.swift` on Windows (#1669)
`System` interfaces should be considered deprecated and not be used.
This removes more of the interfaces from Windows as the socket
interfaces are now part of BSDSocketAPI.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-10-13 10:17:24 +01:00
George Barnett 984af7f4eb
Fix incorrect new names for deprecated APIs (#1672)
Motivation:

Some of the deprecated APIs on the client, server and datagram
bootstraps included the type name in the "rename" field. Since the
underlying type hasn't changed, this isn't quite right results in the
typename being erroneously included when applying a fix-it in Xcode.

Modifications:

- Remove unnecessary typename from a few rename fields.

Result:

Fix-its work as expected.
2020-10-12 13:03:08 +01:00
tomer doron d9d4918333
remove symbolicate-linux-fatal from Docker (#1670)
motivation: we are not actually using symbolicate-linux-fatal in any meaningful way in CI and it's pinned to the master branch which has been removed

changes: remove symbolicate-linux-fatal fetching from Docker
2020-10-08 13:16:12 +01: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
Saleem Abdulrasool d2372de507
NIO: correct return value for messaging on Windows (#1667)
The return type failed to correctly convert the result to the return
value type.  Explicitly perform the return value initialization.
2020-10-06 10:00:12 +01:00
Saleem Abdulrasool 5d57ca0f3a
NIO: implement `cleanupSocket(unixDomainSocketPath:)` for Windows (#1654)
* NIO: implement `cleanupSocket(unixDomainSocketPath:)` for Windows

This adds an initial implementation for the UDS clean up path on
Windows.  Unlike Unix, you cannot simply `stat` the destination to
determine if it is a UDS endpoint.

One must first create a file handle from the path.  Assuming that we are
able to create that, we should verify that the file that we are dealing
with is a not a disk type as the subsequent checks will fail.  Now, we
can use the file handle to query the information of the file.  This will
allow us to determine if it is a reparse point.  If not, it is
impossible for it to be a UDS as a UDS endpoint is a reparse point with
the tag IO_REPARSE_TAG_AF_UNIX.  Once we know that we have a reparse
point, we must query the kernel for information about it via the
`DeviceIoControl` system call (perform an ioctl in Unix speak).  The
returned buffer's tag will identify if we have a UDS.

For the next dance, we must now _close_ the handle as the handle being
left open will cause the subsequent `DeleteFileW` to fail due to there
being an open handle.  Once we have cleaned up the file handle that we
created, we can safely attempt to remove the file via `DeleteFileW`.

This should hopefully be sufficiently robust from possible error
scenarios for the removal of a UDS endpoint.

* NIO: improve the UDS cleanup path on Windows

Instead of doing the complex close-handle dance, instead prefer
`SetFileInformationByHandle` which:
1. avoids a second UTF-8 -> UCS-2 conversion
2. avoids the need for the handle closing dance
3. avoids a third re-query of the handle
4. enables us to use "POSIX" deletion semantics (file is immediately
   removed from the namespace but data streams are left intact)

This comes at the cost of being Windows 10 centric, which I find a
reasonable trade-off as Windows 7 has been EOL'ed by Microsoft, and more
importantly, Unix Domain Sockets are only available on Windows 10!

Thanks to @adierking for the reminder about SetFileInformationByHandle!
2020-10-05 12:49:28 +01:00
Fabian Fett 7c92a3e4d8
NIOUDPServer use AddressedEnvelope as InboundIn and OutboundOut (#1666) 2020-10-02 17:08:54 +01:00
George Barnett bbb0e92702
Print the usage if no args ar provided to the build_podspecs script (#1665)
Motivation:

The information printed when invoking `build_podspecs.sh` without
arguments is outdated.

Modifications:

- Print usage information when invoking without arguments.

Result:

- 'build_podspecs.sh' is more helpful when you can't remember how it
  should be invoked
2020-10-01 17:37:55 +01:00
Cory Benfield c3e2359c55
Minor cleanups of Windows compatability code. (#1663)
Motivation:

Cleanup some noise that came in with some previous Windows compat
patches.

Modifications:

- Move INVALID_SOCKET to NIOBSDSocket, and refer to it by a better name
  there.
- Comment in an empty block to indicate that it's supposed to be empty.

Result:

Bit cleaner code.
2020-09-30 19:55:21 +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
Graeme Jenkinson 7c42e5a45d
A helper for easily unwrapping Optional values in an EventLoopFuture (#1656)
Motivation:

Unwrapping an `Optional` value from an `EventLoopFuture` is a fairly
common requirement that currently involves the client writing
boilerplate code, for example:

```
extension EventLoopFuture {
    func unwrapOptional<T>(orError error: Swift.Error) -> EventLoopFuture<T> where Value == T? {
        self.flatMapThrowing { value in
            guard let value = value else {
                throw error
            }
            return value
        }
    }
}
```

As this is a fairly common requirement adding an extension of
`EventLoopFuture` to unwrap `Optional` values would remove this
burden from clients.

Modifications:

Added Extension to `EventLoopFuture` containing the following functions:

- `unwrap<NewValue>(orError: Error)`: Unwraps a future returning a new
  `EventLoopFuture` with the same value as the resolved future when
  its value is Optional.some(...)`, otherwise the `Error` passed in
  the `orError` parameter is thrown

- func unwrap<NewValue>(orReplace: NewValue)`: Unwraps a future returning a new
  `EventLoopFuture` with either: the value passed in the `orReplace`
  parameter when the future resolved with value `Optional.none`, or
  the same value otherwise.

- func unwrap<NewValue>(orElse: @escaping ()- > NewValue): Unwraps a future
  returning a new `EventLoopFuture` with either: the value returned
  by the closure passed in the `orElse` parameter when the future
  resolved with value `Optional.none`, or the same value otherwise.

Added new unit tests for each new `unwrap(orXXX:)` function.

Result:

Client's no longer have to write their own boilerplate code.
2020-09-30 13:47:14 +01:00
Saleem Abdulrasool 934de6a284
NIO: implement address resolution for Windows (#1661)
This implements address resolution on Windows using the WinSock API.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-30 13:25:39 +01:00
Saleem Abdulrasool 8454066e8d
NIO: shave off parts of System (#1658)
This shaves off parts of System to reduce the noise when building to get
the Windows build more manageable.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-30 11:35:07 +01:00
Saleem Abdulrasool 7686fbf4b0
NIO: improvements to Windows BSD API (#1659)
Some improvements to the API surface to actually handle some more error
cases correctly and fix typing.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-30 10:50:10 +01:00
Saleem Abdulrasool 0ae9524ca8
NIO: invalid sockets are not `-1` but `INVALID_SOCKET` (#1660)
Adjust the sentinel indicating an invalid socket.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-30 10:32:52 +01:00
Saleem Abdulrasool bc328cd3a8
NIO: ignore `SIGPIPE` on Windows (#1653)
Windows does not support Unix-style signals.  Simply exclude the SIGPIPE
path on Windows.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-30 10:13:10 +01:00
Saleem Abdulrasool 2d913d65af
NIO: make BSDSocketAPI build on Windows (#1657)
These interfaces use types from WinSDK to re-export them in the NIO
namespace.  Import the types required.  This allows us to build this
file on Windows again.
2020-09-25 18:30:17 +01:00
Graeme Jenkinson f9a7eaf6e0
Disambiguate the capacity of the ByteBuffer (no. of addressable bytes) and capacity of underlying storage (#1485). (#1629)
Motivation:

The exisiting ByteBuffer`s `capacity` property exposes the number of
addressable bytes in the buffer (that is, the difference between its
upper and lower bound). This value can be significantly different than
the number of bytes allocated to the buffer's underlying storage.
For example, when constructing of COW slice from the original buffer the
underlying storage maybe tens of thousands of bytes while the slice's
capacity is 1.

To avoid any ambiguitity, a new property - `storageCapacity` - will be
added.

Modifications:

Added new `storageCapacity` property to expose the capacity of the buffer (or
derived COW slice) underlying storage (that is allocated to the buffer).
This property is part of public interface ans is typed as an Int.

Updated unit tests to verify `storedCapacity` remains constant when
slicing the ByteBuffer and also to account for the addition of the new
property in the CustomStringConvertible desciption.

Result:

The `storageCapacity` of a buffer and a COW slice taken from that buffer
with remain the same data is written to the slice.

Co-authored-by: Graeme Jenkinson <gcjenkinson@Graemes-MacBook-Pro.local>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-25 11:10:20 +01:00
Saleem Abdulrasool 715efd0c0d
NIO: add import for the C library for Windows (#1652)
`ByteBuffer` uses `size_t` which requires the C library.
2020-09-25 09:12:26 +01:00
Cory Benfield e7880565aa
We use main as our development branch now. (#1651) 2020-09-24 18:02:44 +01:00
Graeme Jenkinson 976ccdd0d0
Scheduling tasks Int.max ns into future results in an obtuse fatal error (#1056) (#1642)
Motivation:

When scheduling a task too far into the future on a Darwin-kernel,
a fatal error is produced. Whilst the error indicates that a parameter
to the kevent syscall was invalid (EINVAL) it gives no further
information as to the root cause.

As the user's intent is to schedule an task far into the future, a fatal
error should not result. Instead the time should be clamped to the
maximum value that the Darwin-kernel supports. This ensures that
, provided the system remains running, the task will eventually run
(though this may be several yeasr into the future).

Modifications:

Duplicated the bounds checks from those in Darwin-kernel interval timer,
clamping timespec values to the maximum value. Added an assert to check
that the timespec tv_nsec field is valid (according to definition of
the timespec datatype in ISO C11). And a precondition on the tv_sec
field being > 0 (tasks schedule with times <= 0 should not result in
a kevent being registered as they are scheduled immediately).

Added note clarifying behaviour under Darwin-based OSes to the EventLoop
scheduleTask() method.

Added new unit test scheduling a task at the maximum value (which
under any regression would crash).

Result:

Scheduled tasks where the timeout exceed the maximum value supported by
Darwin-based OSes will be clamped to the maximum.

Co-authored-by: Graeme Jenkinson <graemee_jenkinson@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-24 15:05:54 +01:00
Saleem Abdulrasool cf9140a686
CNIOWindows: correct declaration (#1646)
This repairs the build on the CNIOWindows module on Windows.  The `NIO`
macro is unavailable in the definition (intentionally) and was being
used accidentally.
2020-09-24 10:29:05 +01:00
Saleem Abdulrasool e183143648
CNIOWindows: add stubs for `sendmmsg` and `recvmmsg` (#1645)
These need to be filled out, but lets stub them out for the time being
to get the symbol resolution sorted out.  These are possible to
implement using the WinSDK.
2020-09-23 10:48:02 +01:00
Andrius 801b879b35
fixes docstring with correct return type (#1644) 2020-09-22 17:37:18 +01:00
Andrius b2f3de8ed5
Cleanup unix socket pathname on server socket close or bind (#1637)
* Cleanup unix socket pathname on server socket close or bind

* cleaner use of swift syntax

* using stat and unlink via syscal wrappers

* separate error type when UDS path is not a socket file

* track if socket needs cleanup to avoid extra syscall

* struct instead of enum for a single new error type

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-22 15:30:49 +01:00
Andrius bc72ee7537
Increases default initial size for `AdaptiveRecvByteBufferAllocator` (#1641)
Motivation:

Resolves https://github.com/apple/swift-nio/issues/1558
A common MTU on the internet is 1500 bytes, and it should fit in the initial size buffer

Modifications:

Only the default initial size is increased

Result:

Little is changed, but should result in fewer reallocations e.g. during TLS conneciton handshake
2020-09-22 11:43:10 +01:00
Saleem Abdulrasool b72ed545aa
NIO: import additional values from WinSDK (#1640)
These values are referenced but not imported which results in undefined
references.
2020-09-22 10:45:06 +01:00
Saleem Abdulrasool b6e53edb49
build: add `CNIOWindows` to Package.swift (#1638)
This adds the CNIOWindows module to the package definition which is
needed for Windows.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-21 18:03:41 +01:00
Saleem Abdulrasool c141d91338
CNIOWindows: preprocess away WinSock support code (#1639)
This preprocesses away the WinSock2 support code when on non-Windows
targets.
2020-09-21 17:23:03 +01:00
Cory Benfield 06554fd48e
Swift 5.3-RELEASE is out, let's use it. (#1631) 2020-09-21 12:09:47 +01:00
Saleem Abdulrasool 15a2e49402
NIO: fix `close(socket:)` (#1633)
`Posix.*` cannot be used on Windows.  Sockets and (file) descriptors are
in entirely different namespaces, and will result in an invalid
operation.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-21 10:45:00 +01:00
Saleem Abdulrasool f7dc232e0c
NIO: remove `poll` from the `_BSDSocketProtocol` protocol (#1635)
This removes the testing-only API of `poll` on Windows which does not
have a semantic compatible poll.

Co-authored-by: David Evans <d.evans@apple.com>
Co-authored-by: Cory Benfield <lukasa@apple.com>
2020-09-21 10:31:13 +01:00
Saleem Abdulrasool 0c2789c56a
NIO: remove unnecessary `@discardableResult` (#1634)
The function returns `Void`, the attribute does not apply.

Co-authored-by: David Evans <d.evans@apple.com>
2020-09-21 10:01:38 +01:00
Saleem Abdulrasool 36b19f98c3
NIO: repair the build after e3508b0d0 (#1636)
`ssize_t` is not a standard type and does not have a portable Swift
spelling.  Use `size_t` which is compatible in size, but is signed
instead.  This is needed in order to be compatible to more standard
conforming environments like Windows.
2020-09-21 09:36:18 +01:00
Max Desiatov 96db8838be
Note that certain NIOFileHandle.init overloads are blocking (#1630)
This was noted in review  of swift-server/async-http-client#275, but I don't think that this was clearly stated in the documentation.
2020-09-07 10:48:15 +01:00
George Barnett 98721c75b0
Remove incorrect assertion in MarkedCircularBuffer.popFirst (#1627)
Motivation:

`MarkedCircularBuffer.popFirst()` asserts that the backing buffer should
contain more than zero elements yet `popFirst()` allows `nil` to be
returned when there is no value to return.

Modifications:

- Move the assertion from `popFirst() -> Element?` to `removeFirst() -> Element`
- Test for `popFirst()`

Result:

- We can safely call `popFirst()` on an empty `MarkedCircularBuffer` in
  debug mode.
2020-09-03 14:06:14 +01:00
Andrew Naylor 08c7821ba3
Correct typo in `_ChannelOutboundHandler` docs (#1628)
Motivation:

The doc block for `_ChannelOutboundHandler.read(context:)` mentions suppressing
a *flush*, it appears this is a copy-paste error from the docs for `flush(context:)`
above and should in fact refer to suppressing the *read*.

Modifications:

Substituted `read` for `flush` in the doc block for `_ChannelOutboundHandler.read(context:)`
2020-09-03 13:46:28 +01:00
Cory Benfield a4a3a4b1b0
Add @inlinable to all BBV methods. (#1625)
Motivation:

While looking at a different part of the code in swift-nio-http2 I
noticed that we can't inline many straightforward ByteBufferView
operations, including bytewise-access. That's pretty sad, so I thought
we should fix it.

Modifications:

- Slap @inlinable on all the BBV entry points.

Result:

Better code generation, particularly around repeated subscript accesses.
2020-08-28 15:33:56 +01:00
George Barnett 5fc24345f9
Better handle writability changes in triggerWriteOperations (#1624)
Motivation:

If a write is buffered in the `PendingWritesManager` and the high
watermark is breached then a writability change will be fired as a
result. The corresponding event when the channel becomes writable again
comes when enough pending bytes have been written to the socket (i.e. as
a result of a `flush()`) and we fall below the low watermark.

However, if a promise associated with a write has a callback
registered on its future which writes enough data to breach the high
watermark (and also flushes) then we will re-entrantly enter
`flushNow()`. This is okay, `flushNow()` protects against re-entrancy
and any re-entrantly enqueud flushed writes will be picked up in the
write-spin-loop.

The issue here is that the `writeSpinLoop` does not monitor for changes
in writability. Instead if checks the writability before it begins and
after it completes, only signalling if there was a change. This is
problematic: the re-entrant write-and-flush could have caused the
channel to become unwritable yet no event will be fired to make it
writable again!

Modifications:

- Store a local writability state in the pending writes manager and
  modify it when we emit writability changes

Result:

- Better protection against re-entrant writability changes.
2020-08-26 12:26:05 +01:00