Parcourir la source

Use iterator when checking encoding headers (#1563)

Motivation:

SwiftNIO HTTP/2 1.24.0 added a method for retrieving a sequence of
header values rather than directly returning an array of values. We can
use it when checking the encoding header as there should only be at most
one value.

Modifications:

- Update HTTP/2 to be min 1.24.0
- Use the iterator API

Result:

Fewer allocations.
George Barnett il y a 2 ans
Parent
commit
a70e9ad757
3 fichiers modifiés avec 15 ajouts et 8 suppressions
  1. 2 2
      .github/workflows/ci.yaml
  2. 1 1
      Package.swift
  3. 12 5
      Sources/GRPC/HTTP2ToRawGRPCStateMachine.swift

+ 2 - 2
.github/workflows/ci.yaml

@@ -16,8 +16,8 @@ jobs:
       run: |
         SWIFTFORMAT_VERSION=0.49.4
         git clone --depth 1 --branch "$SWIFTFORMAT_VERSION" "https://github.com/nicklockwood/SwiftFormat" "$HOME/SwiftFormat"
-        swift build --package-path "$HOME/SwiftFormat" --product swiftformat
-        export PATH=$PATH:"$(swift build --package-path "$HOME/SwiftFormat" --show-bin-path)"
+        swift build -c release --package-path "$HOME/SwiftFormat" --product swiftformat
+        export PATH=$PATH:"$(swift build -c release --package-path "$HOME/SwiftFormat" --show-bin-path)"
         ./scripts/sanity.sh
   unit-tests:
     strategy:

+ 1 - 1
Package.swift

@@ -36,7 +36,7 @@ let packageDependencies: [Package.Dependency] = [
   ),
   .package(
     url: "https://github.com/apple/swift-nio-http2.git",
-    from: "1.22.0"
+    from: "1.24.1"
   ),
   .package(
     url: "https://github.com/apple/swift-nio-transport-services.git",

+ 12 - 5
Sources/GRPC/HTTP2ToRawGRPCStateMachine.swift

@@ -447,10 +447,19 @@ extension HTTP2ToRawGRPCStateMachine.State {
     from headers: HPACKHeaders,
     encoding: ServerMessageEncoding
   ) -> RequestEncodingValidation {
-    let encodings = headers[canonicalForm: GRPCHeaderName.encoding]
+    let encodingValues = headers.values(forHeader: GRPCHeaderName.encoding, canonicalForm: true)
+    var encodingIterator = encodingValues.makeIterator()
+    let encodingHeader = encodingIterator.next()
 
     // Fail if there's more than one encoding header.
-    if encodings.count > 1 {
+    if let first = encodingHeader, let second = encodingIterator.next() {
+      var encodings: [Substring] = []
+      encodings.reserveCapacity(8)
+      encodings.append(first)
+      encodings.append(second)
+      while let next = encodingIterator.next() {
+        encodings.append(next)
+      }
       let status = GRPCStatus(
         code: .invalidArgument,
         message: "'\(GRPCHeaderName.encoding)' must contain no more than one value but was '\(encodings.joined(separator: ", "))'"
@@ -458,12 +467,10 @@ extension HTTP2ToRawGRPCStateMachine.State {
       return .invalid(status: status, acceptEncoding: nil)
     }
 
-    let encodingHeader = encodings.first
     let result: RequestEncodingValidation
-
     let validator = MessageEncodingHeaderValidator(encoding: encoding)
 
-    switch validator.validate(requestEncoding: encodingHeader) {
+    switch validator.validate(requestEncoding: encodingHeader.map { String($0) }) {
     case let .supported(algorithm, decompressionLimit, acceptEncoding):
       // Request message encoding is valid and supported.
       result = .valid(