@@ -130,9 +130,21 @@ final class LocalStaticHTTPServer {
130130 private var rootDirectory : URL ?
131131 private let queue = DispatchQueue ( label: " LocalStaticHTTPServer.queue " )
132132 private var serverStarted = false
133- private var activeConnections : Set < NWConnection > = [ ]
133+ private var activeConnections : Set < ConnectionWrapper > = [ ]
134134 private let connectionsLock = NSLock ( )
135135
136+ private struct ConnectionWrapper : Hashable {
137+ let connection : NWConnection
138+
139+ static func == ( lhs: ConnectionWrapper , rhs: ConnectionWrapper ) -> Bool {
140+ return ObjectIdentifier ( lhs. connection) == ObjectIdentifier ( rhs. connection)
141+ }
142+
143+ func hash( into hasher: inout Hasher ) {
144+ hasher. combine ( ObjectIdentifier ( connection) )
145+ }
146+ }
147+
136148 // Start HTTP (or HTTPS if tlsIdentity is provided) on given port. Serves static files from rootDir.
137149 func start( host: NWEndpoint . Host = . ipv4( IPv4Address ( " 127.0.0.1 " ) !) ,
138150 port: UInt16 = 7404 ,
@@ -259,9 +271,10 @@ final class LocalStaticHTTPServer {
259271 InstallLogger . shared. log ( " Stopping HTTP server " )
260272
261273 connectionsLock. lock ( )
262- for connection in activeConnections {
263- connection. cancel ( )
274+ for wrapper in activeConnections {
275+ wrapper . connection. cancel ( )
264276 }
277+
265278 activeConnections. removeAll ( )
266279 connectionsLock. unlock ( )
267280
@@ -273,7 +286,7 @@ final class LocalStaticHTTPServer {
273286 // Very minimal GET-only static file handler.
274287 private func handleConnection( _ connection: NWConnection ) {
275288 connectionsLock. lock ( )
276- activeConnections. insert ( connection)
289+ activeConnections. insert ( ConnectionWrapper ( connection: connection ) )
277290 connectionsLock. unlock ( )
278291
279292 var received = Data ( )
@@ -387,9 +400,10 @@ final class LocalStaticHTTPServer {
387400
388401 private func removeConnection( _ connection: NWConnection ) {
389402 connectionsLock. lock ( )
390- if activeConnections. contains ( connection) {
403+ let wrapper = ConnectionWrapper ( connection: connection)
404+ if activeConnections. contains ( wrapper) {
391405 connection. cancel ( )
392- activeConnections. remove ( connection )
406+ activeConnections. remove ( wrapper )
393407 }
394408 connectionsLock. unlock ( )
395409 }
@@ -890,3 +904,4 @@ public func installApp(from ipaURL: URL) throws {
890904 try ? summary. write ( to: summaryURL, atomically: true , encoding: . utf8)
891905 InstallLogger . shared. log ( " Summary written to: \( summaryURL. path) " )
892906}
907+
0 commit comments