소스 검색

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 2 년 전
부모
커밋
a70e9ad757
3개의 변경된 파일15개의 추가작업 그리고 8개의 파일을 삭제
  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(