Allow retrieval of metadata from `NWConnection` (#163)
* Allow retrieval of metadata for a specific protocol from the underlying `NWConnection` * Address review comments * Address review comment * Add availability annotation to tests * Rename `NIOTSChannelIsNotATransportServicesChannel ` to `NIOTSChannelIsNotANIOTSConnectionChannel `
This commit is contained in:
parent
de5ea3d0b4
commit
c0d9a144cf
|
|
@ -893,4 +893,61 @@ extension NIOTSConnectionChannel {
|
||||||
return SynchronousOptions(channel: self)
|
return SynchronousOptions(channel: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public struct NIOTSConnectionNotInitialized: Error, Hashable {
|
||||||
|
public init() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct NIOTSChannelIsNotANIOTSConnectionChannel: Error, Hashable {
|
||||||
|
public init() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
|
||||||
|
extension NIOTSConnectionChannel {
|
||||||
|
fileprivate func metadata(definition: NWProtocolDefinition) throws -> NWProtocolMetadata? {
|
||||||
|
guard let nwConnection = self.nwConnection else {
|
||||||
|
throw NIOTSConnectionNotInitialized()
|
||||||
|
}
|
||||||
|
return nwConnection.metadata(definition: definition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
|
||||||
|
extension Channel {
|
||||||
|
/// Retrieves the metadata for a specific protocol from the underlying ``NWConnection``
|
||||||
|
/// - Throws: If `self` isn't a `NIOTS` channel with a `NWConnection` this method will throw
|
||||||
|
/// ``NIOTSChannelIsNotATransportServicesChannel`` or ``NIOTSConnectionNotInitialized``.
|
||||||
|
public func getMetadata(definition: NWProtocolDefinition) -> EventLoopFuture<NWProtocolMetadata?> {
|
||||||
|
guard let channel = self as? NIOTSConnectionChannel else {
|
||||||
|
return self.eventLoop.makeFailedFuture(NIOTSChannelIsNotANIOTSConnectionChannel())
|
||||||
|
}
|
||||||
|
if self.eventLoop.inEventLoop {
|
||||||
|
return self.eventLoop.makeCompletedFuture {
|
||||||
|
try channel.metadata(definition: definition)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return self.eventLoop.submit {
|
||||||
|
try channel.metadata(definition: definition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieves the metadata for a specific protocol from the underlying ``NWConnection``
|
||||||
|
/// - Precondition: Must be called on the `EventLoop` the `Channel` is running on.
|
||||||
|
/// - Throws: If `self` isn't a `NIOTS` channel with a `NWConnection` this method will throw
|
||||||
|
/// ``NIOTSChannelIsNotATransportServicesChannel`` or ``NIOTSConnectionNotInitialized``.
|
||||||
|
public func getMetadataSync(
|
||||||
|
definition: NWProtocolDefinition,
|
||||||
|
file: StaticString = #fileID,
|
||||||
|
line: UInt = #line
|
||||||
|
) throws -> NWProtocolMetadata? {
|
||||||
|
self.eventLoop.preconditionInEventLoop(file: file, line: line)
|
||||||
|
guard let channel = self as? NIOTSConnectionChannel else {
|
||||||
|
throw NIOTSChannelIsNotANIOTSConnectionChannel()
|
||||||
|
}
|
||||||
|
return try channel.metadata(definition: definition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ final class NIOTSBootstrapTests: XCTestCase {
|
||||||
XCTFail("can't connect to server1")
|
XCTFail("can't connect to server1")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
XCTAssertNotNil(try client1.getMetadata(definition: NWProtocolTCP.definition).wait() as? NWProtocolTCP.Metadata)
|
||||||
XCTAssertNoThrow(try client1.writeAndFlush(buffer).wait())
|
XCTAssertNoThrow(try client1.writeAndFlush(buffer).wait())
|
||||||
|
|
||||||
// The TLS connection won't actually succeed but it takes Network.framework a while to tell us, we don't
|
// The TLS connection won't actually succeed but it takes Network.framework a while to tell us, we don't
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This source file is part of the SwiftNIO open source project
|
||||||
|
//
|
||||||
|
// Copyright (c) 2022 Apple Inc. and the SwiftNIO project authors
|
||||||
|
// Licensed under Apache License v2.0
|
||||||
|
//
|
||||||
|
// See LICENSE.txt for license information
|
||||||
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#if canImport(Network)
|
||||||
|
import Network
|
||||||
|
import NIOCore
|
||||||
|
import XCTest
|
||||||
|
@testable import NIOTransportServices
|
||||||
|
|
||||||
|
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
|
||||||
|
final class NIOTSChannelMetadataTests: XCTestCase {
|
||||||
|
func testThrowsIfCalledOnWrongChannel() throws {
|
||||||
|
let eventLoopGroup = NIOTSEventLoopGroup()
|
||||||
|
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) }
|
||||||
|
let listenerBootsrap = NIOTSListenerBootstrap(group: eventLoopGroup)
|
||||||
|
let listenerChannel = try listenerBootsrap.bind(host: "localhost", port: 0).wait()
|
||||||
|
defer { XCTAssertNoThrow(try listenerChannel.close().wait()) }
|
||||||
|
|
||||||
|
XCTAssertThrowsError(try listenerChannel.getMetadata(definition: NWProtocolTLS.definition).wait()) { error in
|
||||||
|
XCTAssertTrue(error is NIOTSChannelIsNotANIOTSConnectionChannel, "unexpected error \(error)")
|
||||||
|
}
|
||||||
|
try! listenerChannel.eventLoop.submit {
|
||||||
|
XCTAssertThrowsError(try listenerChannel.getMetadataSync(definition: NWProtocolTLS.definition)) { error in
|
||||||
|
XCTAssertTrue(error is NIOTSChannelIsNotANIOTSConnectionChannel, "unexpected error \(error)")
|
||||||
|
}
|
||||||
|
}.wait()
|
||||||
|
|
||||||
|
}
|
||||||
|
func testThowsIfCalledOnANonInitializedChannel() {
|
||||||
|
let eventLoopGroup = NIOTSEventLoopGroup()
|
||||||
|
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) }
|
||||||
|
let channel = NIOTSConnectionChannel(eventLoop: eventLoopGroup.next() as! NIOTSEventLoop, tcpOptions: .init(), tlsOptions: .init())
|
||||||
|
XCTAssertThrowsError(try channel.getMetadata(definition: NWProtocolTLS.definition).wait()) { error in
|
||||||
|
XCTAssertTrue(error is NIOTSConnectionNotInitialized, "unexpected error \(error)")
|
||||||
|
}
|
||||||
|
try! channel.eventLoop.submit {
|
||||||
|
XCTAssertThrowsError(try channel.getMetadataSync(definition: NWProtocolTLS.definition)) { error in
|
||||||
|
XCTAssertTrue(error is NIOTSConnectionNotInitialized, "unexpected error \(error)")
|
||||||
|
}
|
||||||
|
}.wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue