Skip to content

Commit c949cfc

Browse files
authored
Nest SocketAddress in NIOHTTPServer (#47)
Motivation: The `HTTPServer` module defines a `SocketAddress` type, but this has the same name as the type in the [`NIOCore` module](https://swiftpackageindex.com/apple/swift-nio/2.92.2/documentation/niocore/socketaddress). Due to a [compiler bug](swiftlang/swift#43510), when a module imports both `HTTPServer` and `NIOCore`, the `HTTPServer` module's `SocketAddress` type cannot be referenced, because `HTTPServer` also contains a protocol with the same name (the `HTTPServer` protocol). In this case, using the module name as a namespace qualifier doesn't work as intended: ```swift import HTTPServer import NIOCore let a: SocketAddress // error: 'SocketAddress' is ambiguous for type lookup in this context let b: HTTPServer.SocketAddress // error: 'SocketAddress' is not a member type of protocol 'HTTPServer.HTTPServer' let c: NIOCore.SocketAddress // compiles fine. ``` Modifications: Nested `SocketAddress` under `NIOHTTPServer`, since that type is only used in the concrete NIO implementation. Result: `NIOHTTPServer.SocketAddress` can be used without running into swiftlang/swift#43510.
1 parent db837a7 commit c949cfc

3 files changed

Lines changed: 79 additions & 75 deletions

File tree

Sources/HTTPServer/NIOHTTPServer+ListeningAddress.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ extension NIOHTTPServer {
124124
}
125125
}
126126

127-
extension SocketAddress {
127+
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
128+
extension NIOHTTPServer.SocketAddress {
128129
fileprivate init(_ address: NIOCore.SocketAddress?) throws(ListeningAddressError) {
129130
guard let address, let port = address.port else {
130131
throw ListeningAddressError.addressOrPortNotAvailable

Sources/HTTPServer/SocketAddress.swift

Lines changed: 76 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -11,97 +11,100 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14-
/// Represents an IPv4 address.
15-
public struct IPv4: Hashable, Sendable {
16-
/// The resolved host address.
17-
public var host: String
18-
/// The port to connect to.
19-
public var port: Int
14+
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
15+
extension NIOHTTPServer {
16+
/// Represents an IPv4 address.
17+
public struct IPv4: Hashable, Sendable {
18+
/// The resolved host address.
19+
public var host: String
20+
/// The port to connect to.
21+
public var port: Int
2022

21-
/// Creates a new IPv4 address.
22-
///
23-
/// - Parameters:
24-
/// - host: Resolved host address.
25-
/// - port: Port to connect to.
26-
public init(host: String, port: Int) {
27-
self.host = host
28-
self.port = port
23+
/// Creates a new IPv4 address.
24+
///
25+
/// - Parameters:
26+
/// - host: Resolved host address.
27+
/// - port: Port to connect to.
28+
public init(host: String, port: Int) {
29+
self.host = host
30+
self.port = port
31+
}
2932
}
30-
}
3133

32-
/// Represents an IPv6 address.
33-
public struct IPv6: Hashable, Sendable {
34-
/// The resolved host address.
35-
public var host: String
36-
/// The port to connect to.
37-
public var port: Int
38-
39-
/// Creates a new IPv6 address.
40-
///
41-
/// - Parameters:
42-
/// - host: Resolved host address.
43-
/// - port: Port to connect to.
44-
public init(host: String, port: Int) {
45-
self.host = host
46-
self.port = port
47-
}
48-
}
34+
/// Represents an IPv6 address.
35+
public struct IPv6: Hashable, Sendable {
36+
/// The resolved host address.
37+
public var host: String
38+
/// The port to connect to.
39+
public var port: Int
4940

50-
/// An address to which a socket may connect or bind to.
51-
public struct SocketAddress: Hashable, Sendable {
52-
enum Base: Hashable, Sendable {
53-
case ipv4(IPv4)
54-
case ipv6(IPv6)
41+
/// Creates a new IPv6 address.
42+
///
43+
/// - Parameters:
44+
/// - host: Resolved host address.
45+
/// - port: Port to connect to.
46+
public init(host: String, port: Int) {
47+
self.host = host
48+
self.port = port
49+
}
5550
}
5651

57-
let base: Base
52+
/// An address to which a socket may connect or bind to.
53+
public struct SocketAddress: Hashable, Sendable {
54+
enum Base: Hashable, Sendable {
55+
case ipv4(IPv4)
56+
case ipv6(IPv6)
57+
}
5858

59-
/// Creates an IPv4 socket address.
60-
public static func ipv4(host: String, port: Int) -> Self {
61-
Self(base: .ipv4(.init(host: host, port: port)))
62-
}
59+
let base: Base
6360

64-
/// Creates an IPv6 socket address.
65-
public static func ipv6(host: String, port: Int) -> Self {
66-
Self(base: .ipv6(.init(host: host, port: port)))
67-
}
61+
/// Creates an IPv4 socket address.
62+
public static func ipv4(host: String, port: Int) -> Self {
63+
Self(base: .ipv4(.init(host: host, port: port)))
64+
}
6865

69-
/// Returns the address as an IPv4 address, if possible.
70-
public var ipv4: IPv4? {
71-
guard case .ipv4(let address) = self.base else {
72-
return nil
66+
/// Creates an IPv6 socket address.
67+
public static func ipv6(host: String, port: Int) -> Self {
68+
Self(base: .ipv6(.init(host: host, port: port)))
7369
}
7470

75-
return address
76-
}
71+
/// Returns the address as an IPv4 address, if possible.
72+
public var ipv4: IPv4? {
73+
guard case .ipv4(let address) = self.base else {
74+
return nil
75+
}
7776

78-
/// Returns the address as an IPv6 address, if possible.
79-
public var ipv6: IPv6? {
80-
guard case .ipv6(let address) = self.base else {
81-
return nil
77+
return address
8278
}
8379

84-
return address
85-
}
80+
/// Returns the address as an IPv6 address, if possible.
81+
public var ipv6: IPv6? {
82+
guard case .ipv6(let address) = self.base else {
83+
return nil
84+
}
8685

87-
/// The ``SocketAddress``'s host.
88-
public var host: String {
89-
switch self.base {
90-
case .ipv4(let ipv4):
91-
return ipv4.host
92-
case .ipv6(let ipv6):
93-
return ipv6.host
86+
return address
87+
}
88+
89+
/// The ``SocketAddress``'s host.
90+
public var host: String {
91+
switch self.base {
92+
case .ipv4(let ipv4):
93+
return ipv4.host
94+
case .ipv6(let ipv6):
95+
return ipv6.host
96+
}
9497
}
95-
}
9698

97-
/// The ``SocketAddress``'s port.
98-
public var port: Int {
99-
switch self.base {
100-
case .ipv4(let ipv4):
101-
return ipv4.port
99+
/// The ``SocketAddress``'s port.
100+
public var port: Int {
101+
switch self.base {
102+
case .ipv4(let ipv4):
103+
return ipv4.port
102104

103-
case .ipv6(let ipv6):
104-
return ipv6.port
105+
case .ipv6(let ipv6):
106+
return ipv6.port
107+
}
105108
}
106109
}
107110
}

Tests/HTTPServerTests/Utilities/Client.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func setUpClient(host: String, port: Int) async throws -> ClientChannel {
3939

4040
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, visionOS 26.0, *)
4141
func setUpClientWithMTLS(
42-
at address: HTTPServer.SocketAddress,
42+
at address: NIOHTTPServer.SocketAddress,
4343
chain: ChainPrivateKeyPair,
4444
trustRoots: [Certificate],
4545
applicationProtocol: String,

0 commit comments

Comments
 (0)