-
-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add NIOT #95
Open
hishnash
wants to merge
5
commits into
vapor:main
Choose a base branch
from
hishnash:AddNIOT
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Add NIOT #95
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
7f5776c
Add NIOTransportServices support
hishnash 3543b7a
Include response head on upgrade
hishnash a8ee93f
Add support for capturing the sent request
hishnash 0f737e2
Add tests that use `NIOTransportServices` when running on macOS
hishnash 21d1ad9
Add Swift 5.3 checks
hishnash File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// swift-tools-version:5.2 | ||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "websocket-kit", | ||
platforms: [ | ||
.macOS(.v10_15) | ||
], | ||
products: [ | ||
.library(name: "WebSocketKit", targets: ["WebSocketKit"]), | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.11.1"), | ||
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.0.0"), | ||
], | ||
targets: [ | ||
.target(name: "WebSocketKit", dependencies: [ | ||
.product(name: "NIO", package: "swift-nio"), | ||
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"), | ||
.product(name: "NIOFoundationCompat", package: "swift-nio"), | ||
.product(name: "NIOHTTP1", package: "swift-nio"), | ||
.product(name: "NIOSSL", package: "swift-nio-ssl"), | ||
.product(name: "NIOWebSocket", package: "swift-nio") | ||
]), | ||
.testTarget(name: "WebSocketKitTests", dependencies: [ | ||
.target(name: "WebSocketKit"), | ||
]), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import Foundation | ||
import NIOHTTP1 | ||
import NIO | ||
|
||
public final class HTTPChannelIntercepter: ChannelDuplexHandler, RemovableChannelHandler { | ||
|
||
public typealias OutboundIn = HTTPClientRequestPart | ||
public typealias OutboundOut = HTTPClientRequestPart | ||
|
||
public typealias InboundIn = HTTPClientResponsePart | ||
public typealias InboundOut = HTTPClientResponsePart | ||
|
||
let writeInterceptHandler: (HTTPRequestHead) -> Void | ||
|
||
public init(writeInterceptHandler: @escaping (HTTPRequestHead) -> Void) { | ||
self.writeInterceptHandler = writeInterceptHandler | ||
} | ||
|
||
public func write( | ||
context: ChannelHandlerContext, | ||
data: NIOAny, | ||
promise: EventLoopPromise<Void>? | ||
) { | ||
let interceptedOutgoingRequest = self.unwrapOutboundIn(data) | ||
|
||
if case .head(let requestHead) = interceptedOutgoingRequest { | ||
self.writeInterceptHandler(requestHead) | ||
} | ||
|
||
context.write(data, promise: promise) | ||
} | ||
} | ||
|
||
extension ChannelPipeline { | ||
public func addHTTPClientHandlers( | ||
position: Position = .last, | ||
leftOverBytesStrategy: RemoveAfterUpgradeStrategy = .dropBytes, | ||
withServerUpgrade upgrade: NIOHTTPClientUpgradeConfiguration? = nil, | ||
withExtraHandlers extraHandlers: [RemovableChannelHandler] = [] | ||
) -> EventLoopFuture<Void> { | ||
let requestEncoder = HTTPRequestEncoder() | ||
let responseDecoder = HTTPResponseDecoder(leftOverBytesStrategy: leftOverBytesStrategy) | ||
|
||
var handlers: [RemovableChannelHandler] = [requestEncoder, ByteToMessageHandler(responseDecoder)] + extraHandlers | ||
|
||
if let (upgraders, completionHandler) = upgrade { | ||
let upgrader = NIOHTTPClientUpgradeHandler( | ||
upgraders: upgraders, | ||
httpHandlers: handlers, | ||
upgradeCompletionHandler: completionHandler | ||
) | ||
handlers.append(upgrader) | ||
} | ||
|
||
return self.addHandlers(handlers, position: position) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file was part of the AsyncHTTPClient open source project | ||
// https://github.com/swift-server/async-http-client | ||
// | ||
// Copyright (c) 2020 Apple Inc. and the AsyncHTTPClient project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#if canImport(Network) && swift(>=5.3) | ||
|
||
import Foundation | ||
import Network | ||
import NIOSSL | ||
import NIOTransportServices | ||
|
||
extension TLSVersion { | ||
/// return Network framework TLS protocol version | ||
var nwTLSProtocolVersion: tls_protocol_version_t { | ||
switch self { | ||
case .tlsv1: | ||
return .TLSv10 | ||
case .tlsv11: | ||
return .TLSv11 | ||
case .tlsv12: | ||
return .TLSv12 | ||
case .tlsv13: | ||
return .TLSv13 | ||
} | ||
} | ||
} | ||
|
||
extension TLSVersion { | ||
/// return as SSL protocol | ||
var sslProtocol: SSLProtocol { | ||
switch self { | ||
case .tlsv1: | ||
return .tlsProtocol1 | ||
case .tlsv11: | ||
return .tlsProtocol11 | ||
case .tlsv12: | ||
return .tlsProtocol12 | ||
case .tlsv13: | ||
return .tlsProtocol13 | ||
} | ||
} | ||
} | ||
|
||
@available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *) | ||
extension TLSConfiguration { | ||
/// Dispatch queue used by Network framework TLS to control certificate verification | ||
static var tlsDispatchQueue = DispatchQueue(label: "TLSDispatch") | ||
|
||
/// create NWProtocolTLS.Options for use with NIOTransportServices from the NIOSSL TLSConfiguration | ||
/// | ||
/// - Parameter queue: Dispatch queue to run `sec_protocol_options_set_verify_block` on. | ||
/// - Returns: Equivalent NWProtocolTLS Options | ||
func getNWProtocolTLSOptions() -> NWProtocolTLS.Options { | ||
let options = NWProtocolTLS.Options() | ||
|
||
// minimum TLS protocol | ||
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) { | ||
sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, self.minimumTLSVersion.nwTLSProtocolVersion) | ||
} else { | ||
sec_protocol_options_set_tls_min_version(options.securityProtocolOptions, self.minimumTLSVersion.sslProtocol) | ||
} | ||
|
||
// maximum TLS protocol | ||
if let maximumTLSVersion = self.maximumTLSVersion { | ||
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) { | ||
sec_protocol_options_set_max_tls_protocol_version(options.securityProtocolOptions, maximumTLSVersion.nwTLSProtocolVersion) | ||
} else { | ||
sec_protocol_options_set_tls_max_version(options.securityProtocolOptions, maximumTLSVersion.sslProtocol) | ||
} | ||
} | ||
|
||
// application protocols | ||
for applicationProtocol in self.applicationProtocols { | ||
applicationProtocol.withCString { buffer in | ||
sec_protocol_options_add_tls_application_protocol(options.securityProtocolOptions, buffer) | ||
} | ||
} | ||
|
||
// the certificate chain | ||
if self.certificateChain.count > 0 { | ||
preconditionFailure("TLSConfiguration.certificateChain is not supported") | ||
} | ||
|
||
// cipher suites | ||
if self.cipherSuites.count > 0 { | ||
// TODO: Requires NIOSSL to provide list of cipher values before we can continue | ||
// https://github.com/apple/swift-nio-ssl/issues/207 | ||
} | ||
|
||
// key log callback | ||
if self.keyLogCallback != nil { | ||
preconditionFailure("TLSConfiguration.keyLogCallback is not supported") | ||
} | ||
|
||
// private key | ||
if self.privateKey != nil { | ||
preconditionFailure("TLSConfiguration.privateKey is not supported") | ||
} | ||
|
||
// renegotiation support key is unsupported | ||
|
||
// trust roots | ||
if let trustRoots = self.trustRoots { | ||
guard case .default = trustRoots else { | ||
preconditionFailure("TLSConfiguration.trustRoots != .default is not supported") | ||
} | ||
} | ||
|
||
switch self.certificateVerification { | ||
case .none: | ||
// add verify block to control certificate verification | ||
sec_protocol_options_set_verify_block( | ||
options.securityProtocolOptions, | ||
{ _, _, sec_protocol_verify_complete in | ||
sec_protocol_verify_complete(true) | ||
}, TLSConfiguration.tlsDispatchQueue | ||
) | ||
|
||
case .noHostnameVerification: | ||
precondition(self.certificateVerification != .noHostnameVerification, "TLSConfiguration.certificateVerification = .noHostnameVerification is not supported") | ||
|
||
case .fullVerification: | ||
break | ||
} | ||
|
||
return options | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't change the tools version as we need to keep support for 5.2 - does that block the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe 5.3 is require for the
If this is a blocker then i might look into how i could make changes to this package so that an additional package could provide the
NIOTransportServices
decency. (either through a subclass or a plugin like solution). what do you think would be the best approach?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a
[email protected]
manifest which contains the old version and then that should work (we might need to wrap the new methods in a Swift version check as well)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok i will give that a go, should i also update the GitHub workflow so that it includes both versions of swift?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gwynne could you update the CI with all the new fun stuff?