diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a430eb7..60f0b9b0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,7 +72,7 @@ For this reason, whenever you add new tests **you have to run a script** that ge ### Make sure your patch works for all supported versions of swift -The CI will do this for you. You can use the docker-compose files included if you wish to check locally. Currently all versions of swift >= 5.4 are supported. For example usage of docker compose see the main [README](./README.md#an-alternative-using-docker-compose) +The CI will do this for you. You can use the docker-compose files included if you wish to check locally. Currently all versions of swift >= 5.5 are supported. For example usage of docker compose see the main [README](./README.md#an-alternative-using-docker-compose) ### Make sure your code is performant diff --git a/IntegrationTests/tests_02_syscall_wrappers/defines.sh b/IntegrationTests/tests_02_syscall_wrappers/defines.sh index debbfe9a..84fcde30 100644 --- a/IntegrationTests/tests_02_syscall_wrappers/defines.sh +++ b/IntegrationTests/tests_02_syscall_wrappers/defines.sh @@ -17,7 +17,7 @@ set -eu function make_package() { cat > "$tmpdir/syscallwrapper/Package.swift" <<"EOF" -// swift-tools-version:5.4 +// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Package@swift-5.4.swift b/Package@swift-5.4.swift deleted file mode 100644 index 73c1eeae..00000000 --- a/Package@swift-5.4.swift +++ /dev/null @@ -1,150 +0,0 @@ -// swift-tools-version:5.4 -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) 2017-2021 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 -// -//===----------------------------------------------------------------------===// - -import PackageDescription - -let swiftAtomics: PackageDescription.Target.Dependency = .product(name: "Atomics", package: "swift-atomics") -let swiftCollections: PackageDescription.Target.Dependency = .product(name: "DequeModule", package: "swift-collections") - -var targets: [PackageDescription.Target] = [ - .target(name: "NIOCore", - dependencies: ["NIOConcurrencyHelpers", "CNIOLinux", "CNIOWindows", swiftCollections, swiftAtomics]), - .target(name: "_NIODataStructures"), - .target(name: "NIOEmbedded", - dependencies: ["NIOCore", - "NIOConcurrencyHelpers", - "_NIODataStructures", - swiftAtomics]), - .target(name: "NIOPosix", - dependencies: ["CNIOLinux", - "CNIODarwin", - "CNIOWindows", - "NIOConcurrencyHelpers", - "NIOCore", - "_NIODataStructures", - swiftAtomics]), - .target(name: "NIO", - dependencies: ["NIOCore", - "NIOEmbedded", - "NIOPosix"]), - .target(name: "_NIOConcurrency", - dependencies: ["NIO", "NIOCore"]), - .target(name: "_NIOBeta", - dependencies: ["NIOCore"]), - .target(name: "NIOFoundationCompat", dependencies: ["NIO", "NIOCore"]), - .target(name: "CNIOAtomics", dependencies: []), - .target(name: "CNIOSHA1", dependencies: []), - .target(name: "CNIOLinux", dependencies: []), - .target(name: "CNIODarwin", dependencies: [], cSettings: [.define("__APPLE_USE_RFC_3542")]), - .target(name: "CNIOWindows", dependencies: []), - .target(name: "NIOConcurrencyHelpers", - dependencies: ["CNIOAtomics"]), - .target(name: "NIOHTTP1", - dependencies: ["NIO", "NIOCore", "NIOConcurrencyHelpers", "CNIOLLHTTP"]), - .executableTarget(name: "NIOEchoServer", - dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"], - exclude: ["README.md"]), - .executableTarget(name: "NIOEchoClient", - dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"], - exclude: ["README.md"]), - .executableTarget(name: "NIOHTTP1Server", - dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOConcurrencyHelpers"], - exclude: ["README.md"]), - .executableTarget(name: "NIOHTTP1Client", - dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOConcurrencyHelpers"], - exclude: ["README.md"]), - .target( - name: "CNIOLLHTTP", - cSettings: [.define("LLHTTP_STRICT_MODE")] - ), - .target(name: "NIOTLS", dependencies: ["NIO", "NIOCore"]), - .executableTarget(name: "NIOChatServer", - dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"], - exclude: ["README.md"]), - .executableTarget(name: "NIOChatClient", - dependencies: ["NIOPosix", "NIOCore", "NIOConcurrencyHelpers"], - exclude: ["README.md"]), - .target(name: "NIOWebSocket", - dependencies: ["NIO", "NIOCore", "NIOHTTP1", "CNIOSHA1"]), - .executableTarget(name: "NIOWebSocketServer", - dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOWebSocket"], - exclude: ["README.md"]), - .executableTarget(name: "NIOWebSocketClient", - dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1", "NIOWebSocket"], - exclude: ["README.md"]), - .executableTarget(name: "NIOPerformanceTester", - dependencies: ["NIOPosix", "NIOCore", "NIOEmbedded", "NIOHTTP1", "NIOFoundationCompat", "NIOWebSocket"]), - .executableTarget(name: "NIOMulticastChat", - dependencies: ["NIOPosix", "NIOCore"]), - .executableTarget(name: "NIOUDPEchoServer", - dependencies: ["NIOPosix", "NIOCore"], - exclude: ["README.md"]), - .executableTarget(name: "NIOUDPEchoClient", - dependencies: ["NIOPosix", "NIOCore"], - exclude: ["README.md"]), - .target(name: "NIOTestUtils", - dependencies: ["NIOPosix", "NIOCore", "NIOEmbedded", "NIOHTTP1", swiftAtomics]), - .executableTarget(name: "NIOCrashTester", - dependencies: ["NIOPosix", "NIOCore", "NIOEmbedded", "NIOHTTP1", "NIOWebSocket", "NIOFoundationCompat"]), - .executableTarget(name: "NIOAsyncAwaitDemo", - dependencies: ["NIOPosix", "NIOCore", "NIOHTTP1"]), - .testTarget(name: "NIOCoreTests", - dependencies: ["NIOCore", "NIOEmbedded", "NIOFoundationCompat"]), - .testTarget(name: "NIOBetaTests", - dependencies: ["_NIOBeta"]), - .testTarget(name: "NIOEmbeddedTests", - dependencies: ["NIOConcurrencyHelpers", "NIOCore", "NIOEmbedded"]), - .testTarget(name: "NIOPosixTests", - dependencies: ["NIOPosix", "NIOCore", "NIOFoundationCompat", "NIOTestUtils", "NIOConcurrencyHelpers", "NIOEmbedded"]), - .testTarget(name: "NIOConcurrencyHelpersTests", - dependencies: ["NIOConcurrencyHelpers", "NIOCore"]), - .testTarget(name: "NIODataStructuresTests", - dependencies: ["_NIODataStructures"]), - .testTarget(name: "NIOHTTP1Tests", - dependencies: ["NIOCore", "NIOEmbedded", "NIOPosix", "NIOHTTP1", "NIOFoundationCompat", "NIOTestUtils"]), - .testTarget(name: "NIOTLSTests", - dependencies: ["NIOCore", "NIOEmbedded", "NIOTLS", "NIOFoundationCompat"]), - .testTarget(name: "NIOWebSocketTests", - dependencies: ["NIOCore", "NIOEmbedded", "NIOWebSocket"]), - .testTarget(name: "NIOTestUtilsTests", - dependencies: ["NIOTestUtils", "NIOCore", "NIOEmbedded", "NIOPosix"]), - .testTarget(name: "NIOFoundationCompatTests", - dependencies: ["NIOCore", "NIOFoundationCompat"]), - .testTarget(name: "NIOTests", - dependencies: ["NIO"]), -] - -let package = Package( - name: "swift-nio", - products: [ - .library(name: "NIOCore", targets: ["NIOCore"]), - .library(name: "NIO", targets: ["NIO"]), - .library(name: "NIOEmbedded", targets: ["NIOEmbedded"]), - .library(name: "NIOPosix", targets: ["NIOPosix"]), - .library(name: "_NIOConcurrency", targets: ["_NIOConcurrency"]), - .library(name: "_NIOBeta", targets: ["_NIOBeta"]), - .library(name: "NIOTLS", targets: ["NIOTLS"]), - .library(name: "NIOHTTP1", targets: ["NIOHTTP1"]), - .library(name: "NIOConcurrencyHelpers", targets: ["NIOConcurrencyHelpers"]), - .library(name: "NIOFoundationCompat", targets: ["NIOFoundationCompat"]), - .library(name: "NIOWebSocket", targets: ["NIOWebSocket"]), - .library(name: "NIOTestUtils", targets: ["NIOTestUtils"]), - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"), - .package(url: "https://github.com/apple/swift-collections.git", from: "1.0.2"), - ], - targets: targets -) diff --git a/README.md b/README.md index 4beaf494..c87be607 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ It's like [Netty](https://netty.io), but written for Swift. The SwiftNIO project is split across multiple repositories: -Repository | NIO 2 (Swift 5.4+) +Repository | NIO 2 (Swift 5.5+) --- | --- [https://github.com/apple/swift-nio][repo-nio]
SwiftNIO core | `from: "2.0.0"` [https://github.com/apple/swift-nio-ssl][repo-nio-ssl]
TLS (SSL) support | `from: "2.0.0"` @@ -67,9 +67,17 @@ Redis | ✅ | ❌ | [mordil/swift-redi-stack](https://gitlab.com/Mordil/swift-re ### Supported Versions ### SwiftNIO 2 + This is the current version of SwiftNIO and will be supported for the foreseeable future. -The latest released SwiftNIO 2 version supports Swift 5.4+. NIO 2.29.0 and older support Swift 5.0+, NIO 2.39.0 and older support Swift 5.2+. +The most recent versions of SwiftNIO support Swift 5.5 and newer. The minimum Swift version supported by SwiftNIO releases are detailed below: + +SwiftNIO | Minimum Swift Version +--------------------|---------------------- +`2.0.0 ..< 2.30.0` | 5.0 +`2.30.0 ..< 2.40.0` | 5.2 +`2.40.0 ..< 2.43.0` | 5.4 +`2.43.0 ...` | 5.5 ### SwiftNIO 1 SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022. @@ -243,7 +251,7 @@ dependencies: [ and then adding the appropriate SwiftNIO module(s) to your target dependencies. The syntax for adding target dependencies differs slightly between Swift -versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and +versions. For example, if you want to depend on the `NIOCore`, `NIOPosix` and `NIOHTTP1` modules, specify the following dependencies: #### Swift 5.4 and newer (`swift-tools-version:5.4`) @@ -305,9 +313,9 @@ First make sure you have [Docker](https://www.docker.com/community-edition) inst Will create a base image, compile SwiftNIO, and run a sample `NIOHTTP1Server` on `localhost:8888`. Test it by `curl http://localhost:8888` -- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2004.54.yaml run test` +- `docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.2204.57.yaml run test` - Will create a base image using Ubuntu 20.04 and swift 5.4, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. + Will create a base image using Ubuntu 22.04 and Swift 5.7, compile SwiftNIO and run the unit and integration tests. Files exist for other ubuntu and swift versions in the docker directory. ## Developing SwiftNIO @@ -329,7 +337,7 @@ have a few prerequisites installed on your system. ### Linux -- Swift 5.2, 5.3, or 5.4 from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. +- Swift 5.5 or newer from [swift.org/download](https://swift.org/download/#releases). We always recommend to use the latest released version. - netcat (for integration tests only) - lsof (for integration tests only) - shasum (for integration tests only) diff --git a/SECURITY.md b/SECURITY.md index 5ef13842..639b4e82 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,19 +4,21 @@ This document specifies the security process for the SwiftNIO project. ## Versions -The SwiftNIO core team will address security vulnerabilities in all SwiftNIO 2.x -versions. Since support for some Swift versions was dropped during the lifetime of +The SwiftNIO core team will address security vulnerabilities in all SwiftNIO 2.x +versions. Since support for some Swift versions was dropped during the lifetime of SwiftNIO 2, patch releases will be created for the last supported SwiftNIO versions -that supported older Swift versions. -If a hypothetical security vulnerability was introduced in 2.10.0, then SwiftNIO core +that supported older Swift versions. +If a hypothetical security vulnerability was introduced in 2.10.0, then SwiftNIO core team would create the following patch releases: * NIO 2.29. + plus next patch release to address the issue for projects that support Swift 5.0 and 5.1 -* NIO 2.39. + plus next patch release to address the issue for projects that support +* NIO 2.39. + plus next patch release to address the issue for projects that support Swift 5.2 and 5.3 -* mainline + plus next patch release to address the issue for projects that support +* NIO 2.42. + plus next patch release to address the issue for projects that support Swift 5.4 and later +* mainline + plus next patch release to address the issue for projects that support + Swift 5.5 and later SwiftNIO 1.x is considered end of life and will not receive any security patches. diff --git a/Sources/NIOWebSocket/Base64.swift b/Sources/NIOWebSocket/Base64.swift index f2eb5da7..d331f175 100644 --- a/Sources/NIOWebSocket/Base64.swift +++ b/Sources/NIOWebSocket/Base64.swift @@ -40,14 +40,14 @@ internal struct Base64 { // nearest multiple of four. let base64StringLength = ((bytes.count + 2) / 3) * 4 let alphabet = Base64.encodeBase64 - + return String(customUnsafeUninitializedCapacity: base64StringLength) { backingStorage in var input = bytes.makeIterator() var offset = 0 while let firstByte = input.next() { let secondByte = input.next() let thirdByte = input.next() - + backingStorage[offset] = Base64.encode(alphabet: alphabet, firstByte: firstByte) backingStorage[offset + 1] = Base64.encode(alphabet: alphabet, firstByte: firstByte, secondByte: secondByte) backingStorage[offset + 2] = Base64.encode(alphabet: alphabet, secondByte: secondByte, thirdByte: thirdByte) @@ -57,9 +57,9 @@ internal struct Base64 { return offset } } - + // MARK: Internal - + // The base64 unicode table. @usableFromInline static let encodeBase64: [UInt8] = [ @@ -80,7 +80,7 @@ internal struct Base64 { UInt8(ascii: "4"), UInt8(ascii: "5"), UInt8(ascii: "6"), UInt8(ascii: "7"), UInt8(ascii: "8"), UInt8(ascii: "9"), UInt8(ascii: "+"), UInt8(ascii: "/"), ] - + static let encodePaddingCharacter: UInt8 = UInt8(ascii: "=") @usableFromInline @@ -150,7 +150,7 @@ extension String { // enhancement on Apple platforms. #if (compiler(>=5.3) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS))) || compiler(>=5.4) extension String { - + @inlinable init(customUnsafeUninitializedCapacity capacity: Int, initializingUTF8With initializer: (_ buffer: UnsafeMutableBufferPointer) throws -> Int) rethrows { diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 66629248..f4633f20 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -37,14 +37,11 @@ import XCTest @testable import NIOTests @testable import NIOWebSocketTests -// This protocol is necessary so we can call the 'run' method (on an existential of this protocol) -// without the compiler noticing that we're calling a deprecated function. -// This hack exists so we can deprecate individual tests which test deprecated functionality without -// getting a compiler warning... -protocol LinuxMainRunner { func run() } -class LinuxMainRunnerImpl: LinuxMainRunner { +@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings") +@main +class LinuxMainRunner { @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings") - func run() { + static func main() { XCTMain([ testCase(AcceptBackoffHandlerTest.allTests), testCase(AdaptiveRecvByteBufferAllocatorTest.allTests), @@ -146,7 +143,6 @@ class LinuxMainRunnerImpl: LinuxMainRunner { ]) } } -(LinuxMainRunnerImpl() as LinuxMainRunner).run() #endif #else #error("on Swift 5.5 and newer, --enable-test-discovery is required") diff --git a/docker/Dockerfile b/docker/Dockerfile index dd62c17f..86bb2bfb 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -ARG swift_version=5.4 +ARG swift_version=5.7 ARG ubuntu_version=bionic ARG base_image=swift:$swift_version-$ubuntu_version FROM $base_image @@ -22,10 +22,3 @@ RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev build-esse # tools RUN mkdir -p $HOME/.tools RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile - -# swiftformat (until part of the toolchain) - -ARG swiftformat_version=0.40.12 -RUN git clone --branch $swiftformat_version --depth 1 https://github.com/nicklockwood/SwiftFormat $HOME/.tools/swift-format -RUN cd $HOME/.tools/swift-format && swift build -c release -RUN ln -s $HOME/.tools/swift-format/.build/release/swiftformat $HOME/.tools/swiftformat diff --git a/docker/docker-compose.2204.57.yaml b/docker/docker-compose.2204.57.yaml index ced422ad..05ad72d5 100644 --- a/docker/docker-compose.2204.57.yaml +++ b/docker/docker-compose.2204.57.yaml @@ -3,20 +3,20 @@ version: "3" services: runtime-setup: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 build: args: ubuntu_version: "jammy" swift_version: "5.7" unit-tests: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 integration-tests: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 test: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 environment: - MAX_ALLOCS_ALLOWED_1000_addHandlers=47050 - MAX_ALLOCS_ALLOWED_1000_addHandlers_sync=40050 @@ -64,13 +64,13 @@ services: # - SANITIZER_ARG=--sanitize=thread # TSan broken still performance-test: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 shell: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 echo: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 http: - image: swift-nio:20.04-5.7 + image: swift-nio:22.04-5.7 diff --git a/scripts/generate_linux_tests.rb b/scripts/generate_linux_tests.rb index 7bc60109..4794f984 100755 --- a/scripts/generate_linux_tests.rb +++ b/scripts/generate_linux_tests.rb @@ -148,14 +148,11 @@ def createLinuxMain(testsDirectory, allTestSubDirectories, files) file.write ' @testable import ' + testSubDirectory + "\n" end file.write "\n" - file.write "// This protocol is necessary so we can call the 'run' method (on an existential of this protocol)\n" - file.write "// without the compiler noticing that we're calling a deprecated function.\n" - file.write "// This hack exists so we can deprecate individual tests which test deprecated functionality without\n" - file.write "// getting a compiler warning...\n" - file.write "protocol LinuxMainRunner { func run() }\n" - file.write "class LinuxMainRunnerImpl: LinuxMainRunner {\n" + file.write '@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' + "\n" + file.write "@main\n" + file.write "class LinuxMainRunner {\n" file.write ' @available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")' + "\n" - file.write " func run() {\n" + file.write " static func main() {\n" file.write " XCTMain([\n" testCases = [] @@ -171,7 +168,6 @@ def createLinuxMain(testsDirectory, allTestSubDirectories, files) file.write " ])\n" file.write " }\n" file.write "}\n" - file.write "(LinuxMainRunnerImpl() as LinuxMainRunner).run()\n" file.write "#endif\n" file.write "#else\n" file.write "#error(\"on Swift 5.5 and newer, --enable-test-discovery is required\")\n"