From c56948ce1309bf0be55473a5bf13e2e4905820fc Mon Sep 17 00:00:00 2001 From: Peter Adams Date: Wed, 23 Oct 2024 13:55:58 +0100 Subject: [PATCH] GitHub Actions to parity with existing CI Motivation: Want to move away from legacy CI. Modifications: Add configuration and update code to use GitHub actions. Result: GitHub Actions can be used for basic CI. --- .github/workflows/main.yml | 20 +++ .github/workflows/pull_request.yml | 30 ++++ .github/workflows/pull_request_label.yml | 18 +++ .github/workflows/scheduled.yml | 20 +++ .gitmodules | 0 .licenseignore | 46 ++++++ .unacceptablelanguageignore | 3 + Package.swift | 1 - Sources/NIOHPACK/HPACKDecoder.swift | 10 +- Sources/NIOHPACK/HPACKEncoder.swift | 1 + Sources/NIOHPACK/HPACKHeader.swift | 9 +- Sources/NIOHPACK/IndexedHeaderTable.swift | 1 - .../ConcurrentStreamBuffer.swift | 4 +- .../Frame Buffers/ControlFrameBuffer.swift | 2 +- Sources/NIOHTTP2/HTTP2Error.swift | 146 ++++++++++++++++++ Sources/NIOHTTP2/HTTP2FrameParser.swift | 2 +- Sources/NIOHTTP2/HTTP2PipelineHelpers.swift | 6 +- Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift | 2 +- ...utput => alloc-limits-from-test-output.sh} | 0 ...lloc-limits-to-last-completed-ci-build.sh} | 0 scripts/check-docs.sh | 23 --- scripts/check_no_api_breakages.sh | 54 ------- scripts/soundness.sh | 142 ----------------- 23 files changed, 305 insertions(+), 235 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/pull_request.yml create mode 100644 .github/workflows/pull_request_label.yml create mode 100644 .github/workflows/scheduled.yml delete mode 100644 .gitmodules create mode 100644 .licenseignore create mode 100644 .unacceptablelanguageignore rename dev/{alloc-limits-from-test-output => alloc-limits-from-test-output.sh} (100%) rename dev/{update-alloc-limits-to-last-completed-ci-build => update-alloc-limits-to-last-completed-ci-build.sh} (100%) delete mode 100755 scripts/check-docs.sh delete mode 100755 scripts/check_no_api_breakages.sh delete mode 100755 scripts/soundness.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..63411c2b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,20 @@ +name: Main + +on: + push: + branches: [main] + +jobs: + unit-tests: + name: Unit tests + uses: apple/swift-nio/.github/workflows/unit_tests.yml@main + with: + linux_5_9_arguments_override: "--explicit-target-dependency-import-check error" + linux_5_10_arguments_override: "--explicit-target-dependency-import-check error" + linux_6_0_arguments_override: "--explicit-target-dependency-import-check error" + linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" + linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + + cxx-interop: + name: Cxx interop + uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 00000000..04893270 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,30 @@ +name: PR + +on: + pull_request: + types: [opened, reopened, synchronize] + +jobs: + soundness: + name: Soundness + uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main + with: + license_header_check_project_name: "SwiftNIO" + format_check_enabled: false + unacceptable_language_check_enabled: true + shell_check_enabled: false + python_lint_check_enabled: false + + unit-tests: + name: Unit tests + uses: apple/swift-nio/.github/workflows/unit_tests.yml@main + with: + linux_5_9_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_5_10_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" + linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + + cxx-interop: + name: Cxx interop + uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml new file mode 100644 index 00000000..86f199f3 --- /dev/null +++ b/.github/workflows/pull_request_label.yml @@ -0,0 +1,18 @@ +name: PR label + +on: + pull_request: + types: [labeled, unlabeled, opened, reopened, synchronize] + +jobs: + semver-label-check: + name: Semantic Version label check + runs-on: ubuntu-latest + timeout-minutes: 1 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Check for Semantic Version label + uses: apple/swift-nio/.github/actions/pull_request_semver_label_checker@main diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml new file mode 100644 index 00000000..2e233df3 --- /dev/null +++ b/.github/workflows/scheduled.yml @@ -0,0 +1,20 @@ +name: Scheduled + +on: + schedule: + - cron: "0 8,20 * * *" + +jobs: + unit-tests: + name: Unit tests + uses: apple/swift-nio/.github/workflows/unit_tests.yml@main + with: + linux_5_9_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_5_10_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" + linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + + cxx-interop: + name: Cxx interop + uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29b..00000000 diff --git a/.licenseignore b/.licenseignore new file mode 100644 index 00000000..6688dca0 --- /dev/null +++ b/.licenseignore @@ -0,0 +1,46 @@ +.gitignore +**/.gitignore +.licenseignore +.unacceptablelanguageignore +.gitattributes +.git-blame-ignore-revs +.mailfilter +.mailmap +.spi.yml +.swift-format +.editorconfig +.github/* +*.md +*.txt +*.yml +*.yaml +*.json +Package.swift +**/Package.swift +Package@-*.swift +**/Package@-*.swift +Package.resolved +**/Package.resolved +Makefile +*.modulemap +**/*.modulemap +**/*.docc/* +*.xcprivacy +**/*.xcprivacy +*.symlink +**/*.symlink +Dockerfile +**/Dockerfile +Snippets/* +dev/git.commit.template +dev/update-benchmark-thresholds +*.crt +**/*.crt +*.pem +**/*.pem +*.der +**/*.der +.swiftformat +.gitmodules +FuzzTesting/FailCases/* +Tests/hpack-test-case/* diff --git a/.unacceptablelanguageignore b/.unacceptablelanguageignore new file mode 100644 index 00000000..6a0dabfa --- /dev/null +++ b/.unacceptablelanguageignore @@ -0,0 +1,3 @@ +IntegrationTests/run-tests.sh +Tests/hpack-test-case/*/story_20.json +scripts/test_h2spec.sh diff --git a/Package.swift b/Package.swift index cd039870..8bc3e58e 100644 --- a/Package.swift +++ b/Package.swift @@ -23,7 +23,6 @@ let package = Package( dependencies: [ .package(url: "https://github.com/apple/swift-nio.git", from: "2.60.0"), .package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"), - .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), ], targets: [ .executableTarget( diff --git a/Sources/NIOHPACK/HPACKDecoder.swift b/Sources/NIOHPACK/HPACKDecoder.swift index ce474a86..f7e0ab03 100644 --- a/Sources/NIOHPACK/HPACKDecoder.swift +++ b/Sources/NIOHPACK/HPACKDecoder.swift @@ -82,15 +82,19 @@ public struct HPACKDecoder: Sendable { /// Creates a new decoder /// - /// - Parameter maxDynamicTableSize: Maximum allowed size of the dynamic header table. + /// - Parameters: + /// - allocator: Allocator for headers view byte buffer (which is deprecated) + /// - maxDynamicTableSize: Maximum allowed size of the dynamic header table. public init(allocator: ByteBufferAllocator, maxDynamicTableSize: Int = HPACKDecoder.maxDynamicTableSize) { self.init(allocator: allocator, maxDynamicTableSize: maxDynamicTableSize, maxHeaderListSize: HPACKDecoder.defaultMaxHeaderListSize) } /// Creates a new decoder /// - /// - Parameter maxDynamicTableSize: Maximum allowed size of the dynamic header table. - /// - Parameter maxHeaderListSize: Maximum allowed size of a decoded header list. + /// - Parameters: + /// - allocator: Allocator for headers view byte buffer (which is deprecated) + /// - maxDynamicTableSize: Maximum allowed size of the dynamic header table. + /// - maxHeaderListSize: Maximum allowed size of a decoded header list. public init(allocator: ByteBufferAllocator, maxDynamicTableSize: Int, maxHeaderListSize: Int) { precondition(maxHeaderListSize > 0, "Max header list size must be positive!") self.headerTable = IndexedHeaderTable(allocator: allocator, maxDynamicTableSize: maxDynamicTableSize) diff --git a/Sources/NIOHPACK/HPACKEncoder.swift b/Sources/NIOHPACK/HPACKEncoder.swift index bc2bd2e6..e0c5d418 100644 --- a/Sources/NIOHPACK/HPACKEncoder.swift +++ b/Sources/NIOHPACK/HPACKEncoder.swift @@ -106,6 +106,7 @@ public struct HPACKEncoder { /// /// - Parameters: /// - allocator: An allocator for `ByteBuffer`s. + /// - useHuffmanEncoding: Should huffman enccoding be used. /// - maxDynamicTableSize: An initial maximum size for the encoder's dynamic header table. public init(allocator: ByteBufferAllocator, useHuffmanEncoding: Bool = true, maxDynamicTableSize: Int = HPACKEncoder.defaultDynamicTableSize) { self.headerIndexTable = IndexedHeaderTable(allocator: allocator, maxDynamicTableSize: maxDynamicTableSize) diff --git a/Sources/NIOHPACK/HPACKHeader.swift b/Sources/NIOHPACK/HPACKHeader.swift index c985220f..e4a7cd47 100644 --- a/Sources/NIOHPACK/HPACKHeader.swift +++ b/Sources/NIOHPACK/HPACKHeader.swift @@ -147,8 +147,11 @@ public struct HPACKHeaders: ExpressibleByDictionaryLiteral, Sendable { /// This method is strictly additive: if there are other entries with the same header /// name already in the block, this will add new entries. /// - /// - Parameter contentsOf: The sequence of header name/value pairs. Header names must be ASCII + /// - Parameters: + /// - other: The sequence of header name/value pairs. Header names must be ASCII /// strings. For HTTP/2 lowercase header names are strongly recommended. + /// - indexing: The types of indexing and rewriting operations a decoder may take with + /// regard to this header. @inlinable public mutating func add(contentsOf other: S, indexing: HPACKIndexing = .indexable) where S.Element == (String, String) { self.reserveCapacity(self.headers.count + other.underestimatedCount) @@ -162,7 +165,7 @@ public struct HPACKHeaders: ExpressibleByDictionaryLiteral, Sendable { /// This method is strictly additive: if there are other entries with the same header /// name already in the block, this will add new entries. /// - /// - Parameter contentsOf: The sequence of header name/value/indexing triplets. Header names + /// - Parameter other: The sequence of header name/value/indexing triplets. Header names /// must be ASCII strings. For HTTP/2 lowercase header names are strongly recommended. @inlinable public mutating func add(contentsOf other: S) where S.Element == HPACKHeaders.Element { @@ -198,7 +201,7 @@ public struct HPACKHeaders: ExpressibleByDictionaryLiteral, Sendable { /// /// This method uses case-insensitive comparisons for the header field name. /// - /// - Parameter name: The name of the header field to remove from the block. + /// - Parameter nameToRemove: The name of the header field to remove from the block. @inlinable public mutating func remove(name nameToRemove: String) { self.headers.removeAll { header in diff --git a/Sources/NIOHPACK/IndexedHeaderTable.swift b/Sources/NIOHPACK/IndexedHeaderTable.swift index 2a0440d9..dbc6ce82 100644 --- a/Sources/NIOHPACK/IndexedHeaderTable.swift +++ b/Sources/NIOHPACK/IndexedHeaderTable.swift @@ -138,7 +138,6 @@ public struct IndexedHeaderTable { /// - Parameters: /// - name: The name of the header to insert. /// - value: The value of the header to insert. - /// - Returns: `true` if the header was added to the table, `false` if not. public mutating func add(headerNamed name: String, value: String) throws { // This function is unnecessarily marked throws, but none of its underlying functions throw anymore. self.dynamicTable.addHeader(named: name, value: value) diff --git a/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift b/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift index 92047f14..7b15044e 100644 --- a/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift +++ b/Sources/NIOHTTP2/Frame Buffers/ConcurrentStreamBuffer.swift @@ -215,13 +215,13 @@ struct ConcurrentStreamBuffer { // Ok, we need to buffer this frame, and we know we have the index for it. What we do here depends on this frame type. For // almost all frames, we just append them to the buffer. For RST_STREAM, however, we're in a different spot. RST_STREAM is a // request to drop all resources for a given stream. We know we have some, but we shouldn't wait to unblock them, we should - // just kill them now and immediately free the resources. + // just remove them now and immediately free the resources. if case .rstStream(let reason) = frame.payload { // We're going to remove the buffer and fail all the writes. let writeBuffer = self.bufferedFrames.remove(at: index) // If we're currently unbuffering this stream, we need to pass the RST_STREAM frame on for correctness. If we aren't, just - // kill it. + // drop it. if writeBuffer.currentlyUnblocking { return .forwardAndDrop(writeBuffer.frames, NIOHTTP2Errors.streamClosed(streamID: frame.streamID, errorCode: reason)) } else { diff --git a/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift b/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift index 2d74ea09..4bec20e2 100644 --- a/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift +++ b/Sources/NIOHTTP2/Frame Buffers/ControlFrameBuffer.swift @@ -31,7 +31,7 @@ struct ControlFrameBuffer { private var pendingControlFrames: MarkedCircularBuffer /// The maximum size of the buffer. If we have to buffer more frames than this, - /// we'll kill the connection. + /// we'll close the connection. internal var maximumBufferSize: Int } diff --git a/Sources/NIOHTTP2/HTTP2Error.swift b/Sources/NIOHTTP2/HTTP2Error.swift index e41d096b..48cf26b9 100644 --- a/Sources/NIOHTTP2/HTTP2Error.swift +++ b/Sources/NIOHTTP2/HTTP2Error.swift @@ -37,6 +37,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - streamID: The ``HTTP2StreamID`` for the stream that does not exist. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func noSuchStream(streamID: HTTP2StreamID, file: String = #fileID, line: UInt = #line) -> NoSuchStream { return NoSuchStream(streamID: streamID, file: file, line: line) } @@ -46,11 +48,17 @@ public enum NIOHTTP2Errors { /// - Parameters: /// - streamID: The ``HTTP2StreamID`` for the stream that is or has been closed /// - errorCode: The ``HTTP2ErrorCode`` representing the reason for closure of the stream. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func streamClosed(streamID: HTTP2StreamID, errorCode: HTTP2ErrorCode, file: String = #fileID, line: UInt = #line) -> StreamClosed { return StreamClosed(streamID: streamID, errorCode: errorCode, file: file, line: line) } /// Creates a ``BadClientMagic`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func badClientMagic(file: String = #fileID, line: UInt = #line) -> BadClientMagic { return BadClientMagic(file: file, line: line) } @@ -59,6 +67,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - state: The ``NIOHTTP2StreamState`` representing the state of the stream from which we were trying to transition + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func badStreamStateTransition(from state: NIOHTTP2StreamState? = nil, file: String = #fileID, line: UInt = #line) -> BadStreamStateTransition { return BadStreamStateTransition(from: state, file: file, line: line) } @@ -68,11 +78,17 @@ public enum NIOHTTP2Errors { /// - Parameters: /// - delta: The change in the window size that was proposed in error /// - currentWindowSize: The current size of the stream flow control window + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidFlowControlWindowSize(delta: Int, currentWindowSize: Int, file: String = #fileID, line: UInt = #line) -> InvalidFlowControlWindowSize { return InvalidFlowControlWindowSize(delta: delta, currentWindowSize: currentWindowSize, file: file, line: line) } /// Creates a ``FlowControlViolation`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func flowControlViolation(file: String = #fileID, line: UInt = #line) -> FlowControlViolation { return FlowControlViolation(file: file, line: line) } @@ -81,56 +97,98 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - setting: The invalid setting in question + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidSetting(setting: HTTP2Setting, file: String = #fileID, line: UInt = #line) -> InvalidSetting { return InvalidSetting(setting: setting, file: file, line: line) } /// Creates an ``IOOnClosedConnection`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func ioOnClosedConnection(file: String = #fileID, line: UInt = #line) -> IOOnClosedConnection { return IOOnClosedConnection(file: file, line: line) } /// Creates a ``ReceivedBadSettings`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func receivedBadSettings(file: String = #fileID, line: UInt = #line) -> ReceivedBadSettings { return ReceivedBadSettings(file: file, line: line) } /// Creates a ``MaxStreamsViolation`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func maxStreamsViolation(file: String = #fileID, line: UInt = #line) -> MaxStreamsViolation { return MaxStreamsViolation(file: file, line: line) } /// Creates a ``StreamIDTooSmall`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func streamIDTooSmall(file: String = #fileID, line: UInt = #line) -> StreamIDTooSmall { return StreamIDTooSmall(file: file, line: line) } /// Creates a ``MissingPreface`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func missingPreface(file: String = #fileID, line: UInt = #line) -> MissingPreface { return MissingPreface(file: file, line: line) } /// Creates a ``CreatedStreamAfterGoaway`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func createdStreamAfterGoaway(file: String = #fileID, line: UInt = #line) -> CreatedStreamAfterGoaway { return CreatedStreamAfterGoaway(file: file, line: line) } /// Creates a ``InvalidStreamIDForPeer`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidStreamIDForPeer(file: String = #fileID, line: UInt = #line) -> InvalidStreamIDForPeer { return InvalidStreamIDForPeer(file: file, line: line) } /// Creates a ``RaisedGoawayLastStreamID`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func raisedGoawayLastStreamID(file: String = #fileID, line: UInt = #line) -> RaisedGoawayLastStreamID { return RaisedGoawayLastStreamID(file: file, line: line) } /// Creates a ``InvalidWindowIncrementSize`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidWindowIncrementSize(file: String = #fileID, line: UInt = #line) -> InvalidWindowIncrementSize { return InvalidWindowIncrementSize(file: file, line: line) } /// Creates a ``PushInViolationOfSetting`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func pushInViolationOfSetting(file: String = #fileID, line: UInt = #line) -> PushInViolationOfSetting { return PushInViolationOfSetting(file: file, line: line) } @@ -139,16 +197,26 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - info: Human-readable information describing _what_ is unsupported. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func unsupported(info: String, file: String = #fileID, line: UInt = #line) -> Unsupported { return Unsupported(info: info, file: file, line: line) } /// Creates a ``UnableToSerializeFrame`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func unableToSerializeFrame(file: String = #fileID, line: UInt = #line) -> UnableToSerializeFrame { return UnableToSerializeFrame(file: file, line: line) } /// Creates a ``UnableToParseFrame`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func unableToParseFrame(file: String = #fileID, line: UInt = #line) -> UnableToParseFrame { return UnableToParseFrame(file: file, line: line) } @@ -157,6 +225,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - name: The name of the pseudo-header that was missing from the header block. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func missingPseudoHeader(_ name: String, file: String = #fileID, line: UInt = #line) -> MissingPseudoHeader { return MissingPseudoHeader(name, file: file, line: line) } @@ -165,6 +235,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - name: The name of the pseudo-header that was duplicated within the header block. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func duplicatePseudoHeader(_ name: String, file: String = #fileID, line: UInt = #line) -> DuplicatePseudoHeader { return DuplicatePseudoHeader(name, file: file, line: line) } @@ -173,6 +245,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - name: The name of the pseudo-header that appeared after a regular header in the header block. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func pseudoHeaderAfterRegularHeader(_ name: String, file: String = #fileID, line: UInt = #line) -> PseudoHeaderAfterRegularHeader { return PseudoHeaderAfterRegularHeader(name, file: file, line: line) } @@ -181,10 +255,18 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - name: The name of the pseudo-header that was not recognised by ``NIOHTTP2``. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func unknownPseudoHeader(_ name: String, file: String = #fileID, line: UInt = #line) -> UnknownPseudoHeader { return UnknownPseudoHeader(name, file: file, line: line) } + /// Creates a ``UnsupportedPseudoHeader`` with with appropriate source context. + /// + /// - Parameters: + /// - name: The name of the pseudo-header that was not supported by ``NIOHTTP2``. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func unsupportedPseudoHeader(_ name: String, file: String = #fileID, line: UInt = #line) -> UnsupportedPseudoHeader { return UnsupportedPseudoHeader(name, file: file, line: line) } @@ -193,21 +275,35 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - block: The block of `HPACKHeaders` that contain the invalid pseudo headers. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidPseudoHeaders(_ block: HPACKHeaders, file: String = #fileID, line: UInt = #line) -> InvalidPseudoHeaders { return InvalidPseudoHeaders(block, file: file, line: line) } /// Creates a ``MissingHostHeader`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func missingHostHeader(file: String = #fileID, line: UInt = #line) -> MissingHostHeader { return MissingHostHeader(file: file, line: line) } /// Creates a ``DuplicateHostHeader`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func duplicateHostHeader(file: String = #fileID, line: UInt = #line) -> DuplicateHostHeader { return DuplicateHostHeader(file: file, line: line) } /// Creates a ``EmptyPathHeader`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func emptyPathHeader(file: String = #fileID, line: UInt = #line) -> EmptyPathHeader { return EmptyPathHeader(file: file, line: line) } @@ -216,6 +312,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - value: The value of the `:status` header that is invalid. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidStatusValue(_ value: String, file: String = #fileID, line: UInt = #line) -> InvalidStatusValue { return InvalidStatusValue(value, file: file, line: line) } @@ -224,6 +322,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - streamID: The ``HTTP2StreamID`` representing the stream that created the priority cycle. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func priorityCycle(streamID: HTTP2StreamID, file: String = #fileID, line: UInt = #line) -> PriorityCycle { return PriorityCycle(streamID: streamID, file: file, line: line) } @@ -232,6 +332,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - streamID: The ``HTTP2StreamID`` on which the `HEADERS` frame without `END_STREAM` was received. + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func trailersWithoutEndStream(streamID: HTTP2StreamID, file: String = #fileID, line: UInt = #line) -> TrailersWithoutEndStream { return TrailersWithoutEndStream(streamID: streamID, file: file, line: line) } @@ -240,6 +342,8 @@ public enum NIOHTTP2Errors { /// /// - Parameters: /// - fieldName: The invalid HTTP/2 header field name + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func invalidHTTP2HeaderFieldName(_ fieldName: String, file: String = #fileID, line: UInt = #line) -> InvalidHTTP2HeaderFieldName { return InvalidHTTP2HeaderFieldName(fieldName, file: file, line: line) } @@ -249,56 +353,98 @@ public enum NIOHTTP2Errors { /// - Parameters: /// - name: The field name for the forbidden header field /// - value: The field value for the forbidden header field + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func forbiddenHeaderField(name: String, value: String, file: String = #fileID, line: UInt = #line) -> ForbiddenHeaderField { return ForbiddenHeaderField(name: name, value: value, file: file, line: line) } /// Creates a ``ContentLengthViolated`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func contentLengthViolated(file: String = #fileID, line: UInt = #line) -> ContentLengthViolated { return ContentLengthViolated(file: file, line: line) } /// Creates a ``ContentLengthHeadersMismatch`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func contentLengthHeadersMismatch(file: String = #fileID, line: UInt = #line) -> ContentLengthHeadersMismatch { return ContentLengthHeadersMismatch(file: file, line: line) } /// Creates a ``ContentLengthHeaderNegative`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func contentLengthHeaderNegative(file: String = #fileID, line: UInt = #line) -> ContentLengthHeaderNegative { return ContentLengthHeaderNegative(file: file, line: line) } /// Creates a ``ContentLengthHeaderMalformedValue`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func contentLengthHeaderMalformedValue(file: String = #fileID, line: UInt = #line) -> ContentLengthHeaderMalformedValue { return ContentLengthHeaderMalformedValue(file: file, line: line) } /// Creates a ``ExcessiveEmptyDataFrames`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func excessiveEmptyDataFrames(file: String = #fileID, line: UInt = #line) -> ExcessiveEmptyDataFrames { return ExcessiveEmptyDataFrames(file: file, line: line) } /// Creates a ``ExcessivelyLargeHeaderBlock`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func excessivelyLargeHeaderBlock(file: String = #fileID, line: UInt = #line) -> ExcessivelyLargeHeaderBlock { return ExcessivelyLargeHeaderBlock(file: file, line: line) } /// Creates a ``NoStreamIDAvailable`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func noStreamIDAvailable(file: String = #fileID, line: UInt = #line) -> NoStreamIDAvailable { return NoStreamIDAvailable(file: file, line: line) } /// Creates a ``MissingMultiplexer`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func missingMultiplexer(file: String = #fileID, line: UInt = #line) -> MissingMultiplexer { return MissingMultiplexer(file: file, line: line) } /// Creates a ``ExcessiveRSTFrames`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func excessiveRSTFrames(file: String = #fileID, line: UInt = #line) -> ExcessiveRSTFrames { return ExcessiveRSTFrames(file: file, line: line) } /// Creates an ``ExcessiveContinuationFrames`` error with appropriate source context. + /// + /// - Parameters: + /// - file: Source file of the caller. + /// - line: Source line number of the caller. public static func excessiveContinuationFrames(file: String = #fileID, line: UInt = #line) -> ExcessiveContinuationFrames { return ExcessiveContinuationFrames(file: file, line: line) } diff --git a/Sources/NIOHTTP2/HTTP2FrameParser.swift b/Sources/NIOHTTP2/HTTP2FrameParser.swift index 90f52f2c..15905c49 100644 --- a/Sources/NIOHTTP2/HTTP2FrameParser.swift +++ b/Sources/NIOHTTP2/HTTP2FrameParser.swift @@ -624,7 +624,7 @@ struct HTTP2FrameDecoder { } // Check whether there is any possibility of this payload decompressing and fitting in max header list size. - // If there isn't, kill it. + // If there isn't, drop it. guard self.header.length + header.length <= maxHeaderListSize else { throw NIOHTTP2Errors.excessivelyLargeHeaderBlock() } diff --git a/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift b/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift index 70087a3a..e66f9377 100644 --- a/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift +++ b/Sources/NIOHTTP2/HTTP2PipelineHelpers.swift @@ -613,11 +613,11 @@ extension Channel { /// - http1ConnectionInitializer: An optional callback that will be invoked only when the negotiated protocol /// is HTTP/1.1 to configure the connection channel. /// - http2ConnectionInitializer: An optional callback that will be invoked only when the negotiated protocol - /// is HTTP/2 to configure the connection channel. The channel has an ``ChannelOutboundHandler/OutboundIn`` type of ``HTTP2Frame``. + /// is HTTP/2 to configure the connection channel. The channel has an `ChannelOutboundHandler/OutboundIn` type of ``HTTP2Frame``. /// - http2StreamInitializer: A closure that will be called whenever the remote peer initiates a new stream. /// The output of this closure is the element type of the returned multiplexer - /// - Returns: An `EventLoopFuture` containing a ``NIOTypedApplicationProtocolNegotiationHandler`` that completes when the channel - /// is ready to negotiate. This can then be used to access the ``NIOProtocolNegotiationResult`` which may itself + /// - Returns: An `EventLoopFuture` containing a `NIOTypedApplicationProtocolNegotiationHandler` that completes when the channel + /// is ready to negotiate. This can then be used to access the `NIOProtocolNegotiationResult` which may itself /// be waited on to retrieve the result of the negotiation. @inlinable @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) diff --git a/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift b/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift index c4d946ae..cccd2fc1 100644 --- a/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift +++ b/Sources/NIOHTTP2/HTTP2StreamMultiplexer.swift @@ -268,7 +268,7 @@ extension HTTP2StreamMultiplexer { /// > Note: Resources for the stream will be freed after it has been closed. /// /// - Parameters: - /// - streamStateInitializer: A callback that will be invoked to allow you to configure the + /// - initializer: A callback that will be invoked to allow you to configure the /// `ChannelPipeline` for the newly created channel. /// - Returns: A future for the initialized `Channel`. public func createStreamChannel(_ initializer: @escaping NIOChannelInitializer) -> EventLoopFuture { diff --git a/dev/alloc-limits-from-test-output b/dev/alloc-limits-from-test-output.sh similarity index 100% rename from dev/alloc-limits-from-test-output rename to dev/alloc-limits-from-test-output.sh diff --git a/dev/update-alloc-limits-to-last-completed-ci-build b/dev/update-alloc-limits-to-last-completed-ci-build.sh similarity index 100% rename from dev/update-alloc-limits-to-last-completed-ci-build rename to dev/update-alloc-limits-to-last-completed-ci-build.sh diff --git a/scripts/check-docs.sh b/scripts/check-docs.sh deleted file mode 100755 index 9405b7eb..00000000 --- a/scripts/check-docs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2023 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 -## -##===----------------------------------------------------------------------===## - -set -eu - -raw_targets=$(sed -E -n -e 's/^.* - documentation_targets: \[(.*)\].*$/\1/p' .spi.yml) -targets=(${raw_targets//,/ }) - -for target in "${targets[@]}"; do - swift package plugin generate-documentation --target "$target" --warnings-as-errors --analyze --level detailed -done diff --git a/scripts/check_no_api_breakages.sh b/scripts/check_no_api_breakages.sh deleted file mode 100755 index 83c6fd44..00000000 --- a/scripts/check_no_api_breakages.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2017-2020 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 -## -##===----------------------------------------------------------------------===## - -set -eu - -function usage() { - echo >&2 "Usage: $0 REPO-GITHUB-URL NEW-VERSION OLD-VERSIONS..." - echo >&2 - echo >&2 "This script requires a Swift 5.6+ toolchain." - echo >&2 - echo >&2 "Examples:" - echo >&2 - echo >&2 "Check between main and tag 2.1.1 of swift-nio:" - echo >&2 " $0 https://github.com/apple/swift-nio main 2.1.1" - echo >&2 - echo >&2 "Check between HEAD and commit 64cf63d7 using the provided toolchain:" - echo >&2 " xcrun --toolchain org.swift.5120190702a $0 ../some-local-repo HEAD 64cf63d7" -} - -if [[ $# -lt 3 ]]; then - usage - exit 1 -fi - -tmpdir=$(mktemp -d /tmp/.check-api_XXXXXX) -repo_url=$1 -new_tag=$2 -shift 2 - -repodir="$tmpdir/repo" -git clone "$repo_url" "$repodir" -git -C "$repodir" fetch -q origin '+refs/pull/*:refs/remotes/origin/pr/*' -cd "$repodir" -git checkout -q "$new_tag" - -for old_tag in "$@"; do - echo "Checking public API breakages from $old_tag to $new_tag" - - swift package diagnose-api-breaking-changes "$old_tag" -done - -echo done diff --git a/scripts/soundness.sh b/scripts/soundness.sh deleted file mode 100755 index fd8a06ad..00000000 --- a/scripts/soundness.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2017-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 -## -##===----------------------------------------------------------------------===## - -set -eu -here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -function replace_acceptable_years() { - # this needs to replace all acceptable forms with 'YEARS' - sed -e 's/20[12][7890123]-20[12][8901234]/YEARS/' -e 's/20[12][8901234]/YEARS/' -} - -printf "=> Checking for unacceptable language... " -# This greps for unacceptable terminology. The square bracket[s] are so that -# "git grep" doesn't find the lines that greps :). -unacceptable_terms=( - -e blacklis[t] - -e whitelis[t] - -e slav[e] - -e sanit[y] -) - -# We have to exclude the code of conduct as it gives examples of unacceptable -# language. -if git grep --color=never -i "${unacceptable_terms[@]}" -- . ":(exclude)CODE_OF_CONDUCT.md" > /dev/null; then - printf "\033[0;31mUnacceptable language found.\033[0m\n" - git grep -i "${unacceptable_terms[@]}" -- . ":(exclude)CODE_OF_CONDUCT.md" - exit 1 -fi -printf "\033[0;32mokay.\033[0m\n" - -# This checks for the umbrella NIO module. -printf "=> Checking for imports of umbrella NIO module... " -if git grep --color=never -i "^[ \t]*import \+NIO[ \t]*$" > /dev/null; then - printf "\033[0;31mUmbrella imports found.\033[0m\n" - git grep -i "^[ \t]*import \+NIO[ \t]*$" - exit 1 -fi -printf "\033[0;32mokay.\033[0m\n" - -printf "=> Checking license headers... " -tmp=$(mktemp /tmp/.swift-nio-soundness_XXXXXX) - -for language in swift-or-c bash dtrace; do - declare -a matching_files - declare -a exceptions - expections=( ) - matching_files=( -name '*' ) - case "$language" in - swift-or-c) - exceptions=( -name c_nio_http_parser.c -o -name c_nio_http_parser.h -o -name cpp_magic.h -o -name Package.swift -o -name c_nio_sha1.h -o -name c_nio_sha1.c -o -name 'Package@swift*.swift') - matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' ) - cat > "$tmp" <<"EOF" -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) YEARS 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 -// -//===----------------------------------------------------------------------===// -EOF - ;; - bash) - matching_files=( -name '*.sh' ) - cat > "$tmp" <<"EOF" -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) YEARS 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 -## -##===----------------------------------------------------------------------===## -EOF - ;; - dtrace) - matching_files=( -name '*.d' ) - cat > "$tmp" <<"EOF" -#!/usr/sbin/dtrace -q -s -/*===----------------------------------------------------------------------===* - * - * This source file is part of the SwiftNIO open source project - * - * Copyright (c) YEARS 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 - * - *===----------------------------------------------------------------------===*/ -EOF - ;; - *) - echo >&2 "ERROR: unknown language '$language'" - ;; - esac - - expected_lines=$(cat "$tmp" | wc -l) - expected_sha=$(cat "$tmp" | shasum) - - ( - cd "$here/.." - find . \ - \( \! -path './.build/*' -a \ - \( "${matching_files[@]}" \) -a \ - \( \! \( "${exceptions[@]}" \) \) \) | while read line; do - if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then - printf "\033[0;31mmissing headers in file '$line'!\033[0m\n" - diff -u <(cat "$line" | replace_acceptable_years | head -n $expected_lines) "$tmp" - exit 1 - fi - done - printf "\033[0;32mokay.\033[0m\n" - ) -done - -rm "$tmp"