Skip to content

Commit

Permalink
Fixes for Swift 6 mode and strict concurrency (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler authored Aug 15, 2024
1 parent b199fd6 commit 2d6404a
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 16 deletions.
10 changes: 6 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import PackageDescription

let swiftSettings: [SwiftSetting] = [.enableExperimentalFeature("StrictConcurrency=complete")]

let package = Package(
name: "hummingbird-websocket",
platforms: [.macOS(.v14), .iOS(.v17), .tvOS(.v17)],
Expand All @@ -29,7 +31,7 @@ let package = Package(
.product(name: "Hummingbird", package: "hummingbird"),
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
]),
], swiftSettings: swiftSettings),
.target(name: "HummingbirdWSClient", dependencies: [
.byName(name: "HummingbirdWSCore"),
.product(name: "HTTPTypes", package: "swift-http-types"),
Expand All @@ -40,7 +42,7 @@ let package = Package(
.product(name: "NIOSSL", package: "swift-nio-ssl"),
.product(name: "NIOTransportServices", package: "swift-nio-transport-services"),
.product(name: "NIOWebSocket", package: "swift-nio"),
]),
], swiftSettings: swiftSettings),
.target(name: "HummingbirdWSCore", dependencies: [
.product(name: "HTTPTypes", package: "swift-http-types"),
.product(name: "NIOCore", package: "swift-nio"),
Expand All @@ -50,11 +52,11 @@ let package = Package(
.target(name: "HummingbirdWSCompression", dependencies: [
.byName(name: "HummingbirdWSCore"),
.product(name: "CompressNIO", package: "compress-nio"),
]),
], swiftSettings: swiftSettings),
.target(name: "HummingbirdWSTesting", dependencies: [
.byName(name: "HummingbirdWSClient"),
.product(name: "HummingbirdTesting", package: "hummingbird"),
]),
], swiftSettings: swiftSettings),
.testTarget(name: "HummingbirdWebSocketTests", dependencies: [
.byName(name: "HummingbirdWebSocket"),
.byName(name: "HummingbirdWSClient"),
Expand Down
68 changes: 68 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "hummingbird-websocket",
platforms: [.macOS(.v14), .iOS(.v17), .tvOS(.v17)],
products: [
.library(name: "HummingbirdWebSocket", targets: ["HummingbirdWebSocket"]),
.library(name: "HummingbirdWSClient", targets: ["HummingbirdWSClient"]),
.library(name: "HummingbirdWSCompression", targets: ["HummingbirdWSCompression"]),
.library(name: "HummingbirdWSTesting", targets: ["HummingbirdWSTesting"]),
],
dependencies: [
.package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0-rc.2"),
.package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.4.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.62.0"),
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.22.0"),
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.5.0"),
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.20.0"),
.package(url: "https://github.com/adam-fowler/compress-nio.git", from: "1.2.0"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"),
],
targets: [
.target(name: "HummingbirdWebSocket", dependencies: [
.byName(name: "HummingbirdWSCore"),
.product(name: "Hummingbird", package: "hummingbird"),
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
]),
.target(name: "HummingbirdWSClient", dependencies: [
.byName(name: "HummingbirdWSCore"),
.product(name: "HTTPTypes", package: "swift-http-types"),
.product(name: "Logging", package: "swift-log"),
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
.product(name: "NIOPosix", package: "swift-nio"),
.product(name: "NIOSSL", package: "swift-nio-ssl"),
.product(name: "NIOTransportServices", package: "swift-nio-transport-services"),
.product(name: "NIOWebSocket", package: "swift-nio"),
]),
.target(name: "HummingbirdWSCore", dependencies: [
.product(name: "HTTPTypes", package: "swift-http-types"),
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOWebSocket", package: "swift-nio"),
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
]),
.target(name: "HummingbirdWSCompression", dependencies: [
.byName(name: "HummingbirdWSCore"),
.product(name: "CompressNIO", package: "compress-nio"),
]),
.target(name: "HummingbirdWSTesting", dependencies: [
.byName(name: "HummingbirdWSClient"),
.product(name: "HummingbirdTesting", package: "hummingbird"),
]),
.testTarget(name: "HummingbirdWebSocketTests", dependencies: [
.byName(name: "HummingbirdWebSocket"),
.byName(name: "HummingbirdWSClient"),
.byName(name: "HummingbirdWSCompression"),
.byName(name: "HummingbirdWSTesting"),
.product(name: "Hummingbird", package: "hummingbird"),
.product(name: "HummingbirdTesting", package: "hummingbird"),
.product(name: "HummingbirdTLS", package: "hummingbird"),
]),
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import NIOWebSocket

/// PerMessageDeflate Websocket extension builder
struct PerMessageDeflateExtensionBuilder: WebSocketExtensionBuilder {
static var name = "permessage-deflate"
static let name = "permessage-deflate"

let clientMaxWindow: Int?
let clientNoContextTakeover: Bool
Expand Down Expand Up @@ -173,9 +173,9 @@ struct PerMessageDeflateExtension: WebSocketExtension {
fileprivate let decompressor: any NIODecompressor
var state: ReceiveState

init(_ decompressor: any NIODecompressor) throws {
init(_ algorithm: CompressionAlgorithm) throws {
self.state = .idle
self.decompressor = decompressor
self.decompressor = algorithm.decompressor
try self.decompressor.startStream()
}

Expand Down Expand Up @@ -228,8 +228,8 @@ struct PerMessageDeflateExtension: WebSocketExtension {
var sendState: SendState
let minFrameSizeToCompress: Int

init(_ compressor: any NIOCompressor, minFrameSizeToCompress: Int) throws {
self.compressor = compressor
init(_ algorithm: CompressionAlgorithm, minFrameSizeToCompress: Int) throws {
self.compressor = algorithm.compressor
self.minFrameSizeToCompress = minFrameSizeToCompress
self.sendState = .idle
try self.compressor.startStream()
Expand Down Expand Up @@ -277,7 +277,7 @@ struct PerMessageDeflateExtension: WebSocketExtension {
configuration: .init(
windowSize: numericCast(configuration.receiveMaxWindow ?? 15)
)
).decompressor
)
)
self.compressor = try .init(
CompressionAlgorithm.deflate(
Expand All @@ -286,7 +286,7 @@ struct PerMessageDeflateExtension: WebSocketExtension {
compressionLevel: configuration.compressionLevel.map { numericCast($0) } ?? -1,
memoryLevel: configuration.memoryLevel.map { numericCast($0) } ?? 8
)
).compressor,
),
minFrameSizeToCompress: self.configuration.minFrameSizeToCompress
)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/HummingbirdWSCore/WebSocketExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import NIOCore
import NIOWebSocket

/// Basic context implementation of ``WebSocketContext``.
public struct WebSocketExtensionContext {
public struct WebSocketExtensionContext: Sendable {
public let logger: Logger

init(logger: Logger) {
Expand Down
11 changes: 10 additions & 1 deletion Sources/HummingbirdWSCore/WebSocketHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public struct AutoPingSetup: Sendable {
}

/// Close frame that caused WebSocket close
public struct WebSocketCloseFrame {
public struct WebSocketCloseFrame: Sendable {
// status code indicating a reason for closure
public let closeCode: WebSocketErrorCode
// close reason
Expand Down Expand Up @@ -179,12 +179,21 @@ package actor WebSocketHandler {
try await self.close(code: closeCode)
if case .closing = self.closeState {
// Close handshake. Wait for responding close or until inbound ends
#if compiler(>=6.0)
while let frame = try await inboundIterator.next(isolation: self) {
if case .connectionClose = frame.opcode {
try await self.receivedClose(frame)
break
}
}
#else
while let frame = try await inboundIterator.next() {
if case .connectionClose = frame.opcode {
try await self.receivedClose(frame)
break
}
}
#endif
}
// don't propagate error if channel is already closed
} catch ChannelError.ioOnClosedChannel {}
Expand Down
4 changes: 2 additions & 2 deletions Tests/HummingbirdWebSocketTests/WebSocketExtensionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ struct XorWebSocketExtension: WebSocketExtension {
}

struct XorWebSocketExtensionBuilder: WebSocketExtensionBuilder {
static var name = "permessage-xor"
static let name = "permessage-xor"
let value: UInt8?

init(value: UInt8? = nil) {
Expand Down Expand Up @@ -377,7 +377,7 @@ struct CheckDeflateWebSocketExtension: WebSocketExtension {
}

struct CheckDeflateWebSocketExtensionBuilder: WebSocketExtensionBuilder {
static var name = "check-deflate"
static let name = "check-deflate"

func clientRequestHeader() -> String {
return Self.name
Expand Down
2 changes: 1 addition & 1 deletion Tests/HummingbirdWebSocketTests/WebSocketTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import ServiceLifecycle
import XCTest

/// Promise type.
actor Promise<Value> {
actor Promise<Value: Sendable> {
enum State {
case blocked([CheckedContinuation<Value, Never>])
case unblocked(Value)
Expand Down

0 comments on commit 2d6404a

Please sign in to comment.