Quellcode durchsuchen

":path" should have a leading "/" (#1910)

Motivation:

The value of the ":path" header field should be absolute. Currently the
fully qualified method descriptor is used which doesn't contain a
leading slash.

Modifications:

- Add a leading slash
- Rename paramet
- Update tests

Result:

":path" is correct
George Barnett vor 1 Jahr
Ursprung
Commit
87b18f8460

+ 10 - 4
Sources/GRPCHTTP2Core/GRPCStreamStateMachine.swift

@@ -542,7 +542,7 @@ extension GRPCStreamStateMachine {
     // must come before all other headers.
     headers.add("POST", forKey: .method)
     headers.add(scheme.rawValue, forKey: .scheme)
-    headers.add(methodDescriptor.fullyQualifiedMethod, forKey: .path)
+    headers.add(methodDescriptor.path, forKey: .path)
 
     // Add required gRPC headers.
     headers.add(ContentType.grpc.canonicalValue, forKey: .contentType)
@@ -1243,7 +1243,7 @@ extension GRPCStreamStateMachine {
         )
       }
 
-      guard let path = MethodDescriptor(fullyQualifiedMethod: pathHeader) else {
+      guard let path = MethodDescriptor(path: pathHeader) else {
         return self.closeServerAndBuildRejectRPCAction(
           currentState: state,
           endStream: endStream,
@@ -1507,8 +1507,8 @@ extension GRPCStreamStateMachine {
 }
 
 extension MethodDescriptor {
-  init?(fullyQualifiedMethod: String) {
-    let split = fullyQualifiedMethod.split(separator: "/")
+  init?(path: String) {
+    let split = path.split(separator: "/")
     guard split.count == 2 else {
       return nil
     }
@@ -1596,3 +1596,9 @@ extension Status.Code {
     }
   }
 }
+
+extension MethodDescriptor {
+  var path: String {
+    return "/\(self.service)/\(self.method)"
+  }
+}

+ 7 - 7
Tests/GRPCHTTP2CoreTests/Client/GRPCClientStreamHandlerTests.swift

@@ -220,7 +220,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
       [
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.scheme.rawValue: "http",
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
         GRPCHTTP2Keys.te.rawValue: "trailers",
         GRPCHTTP2Keys.encoding.rawValue: "deflate",
@@ -279,7 +279,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
       [
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.scheme.rawValue: "http",
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
         GRPCHTTP2Keys.te.rawValue: "trailers",
       ]
@@ -349,7 +349,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
       [
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.scheme.rawValue: "http",
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
         GRPCHTTP2Keys.te.rawValue: "trailers",
       ]
@@ -407,7 +407,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
     // Write client's initial metadata
     XCTAssertNoThrow(try channel.writeOutbound(RPCRequestPart.metadata(Metadata())))
     let clientInitialMetadata: HPACKHeaders = [
-      GRPCHTTP2Keys.path.rawValue: "test/test",
+      GRPCHTTP2Keys.path.rawValue: "/test/test",
       GRPCHTTP2Keys.scheme.rawValue: "http",
       GRPCHTTP2Keys.method.rawValue: "POST",
       GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
@@ -481,7 +481,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
       [
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.scheme.rawValue: "http",
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
         GRPCHTTP2Keys.te.rawValue: "trailers",
 
@@ -599,7 +599,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
       [
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.scheme.rawValue: "http",
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
         GRPCHTTP2Keys.te.rawValue: "trailers",
 
@@ -704,7 +704,7 @@ final class GRPCClientStreamHandlerTests: XCTestCase {
       [
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.scheme.rawValue: "http",
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
         GRPCHTTP2Keys.te.rawValue: "trailers",
 

+ 19 - 19
Tests/GRPCHTTP2CoreTests/GRPCStreamStateMachineTests.swift

@@ -35,14 +35,14 @@ private enum TargetStateMachineState: CaseIterable {
 extension HPACKHeaders {
   // Client
   fileprivate static let clientInitialMetadata: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.scheme.rawValue: "http",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.te.rawValue: "trailers",
   ]
   fileprivate static let clientInitialMetadataWithDeflateCompression: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.scheme.rawValue: "https",
@@ -51,7 +51,7 @@ extension HPACKHeaders {
     GRPCHTTP2Keys.encoding.rawValue: "deflate",
   ]
   fileprivate static let clientInitialMetadataWithGzipCompression: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.scheme.rawValue: "https",
@@ -60,10 +60,10 @@ extension HPACKHeaders {
     GRPCHTTP2Keys.encoding.rawValue: "gzip",
   ]
   fileprivate static let receivedWithoutContentType: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test"
+    GRPCHTTP2Keys.path.rawValue: "/test/test"
   ]
   fileprivate static let receivedWithInvalidContentType: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.contentType.rawValue: "invalid/invalid",
   ]
   fileprivate static let receivedWithInvalidPath: Self = [
@@ -74,39 +74,39 @@ extension HPACKHeaders {
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc"
   ]
   fileprivate static let receivedWithoutTE: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.scheme.rawValue: "http",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
   ]
   fileprivate static let receivedWithInvalidTE: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.scheme.rawValue: "http",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.te.rawValue: "invalidte",
   ]
   fileprivate static let receivedWithoutMethod: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.scheme.rawValue: "http",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.te.rawValue: "trailers",
   ]
   fileprivate static let receivedWithInvalidMethod: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.scheme.rawValue: "http",
     GRPCHTTP2Keys.method.rawValue: "GET",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.te.rawValue: "trailers",
   ]
   fileprivate static let receivedWithoutScheme: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
     GRPCHTTP2Keys.te.rawValue: "trailers",
   ]
   fileprivate static let receivedWithInvalidScheme: Self = [
-    GRPCHTTP2Keys.path.rawValue: "test/test",
+    GRPCHTTP2Keys.path.rawValue: "/test/test",
     GRPCHTTP2Keys.scheme.rawValue: "invalidscheme",
     GRPCHTTP2Keys.method.rawValue: "POST",
     GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
@@ -986,7 +986,7 @@ final class GRPCStreamClientStateMachineTests: XCTestCase {
     XCTAssertEqual(
       clientInitialMetadata,
       [
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.scheme.rawValue: "http",
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
@@ -1075,7 +1075,7 @@ final class GRPCStreamClientStateMachineTests: XCTestCase {
     XCTAssertEqual(
       clientInitialMetadata,
       [
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.scheme.rawValue: "http",
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
@@ -1162,7 +1162,7 @@ final class GRPCStreamClientStateMachineTests: XCTestCase {
     XCTAssertEqual(
       clientInitialMetadata,
       [
-        GRPCHTTP2Keys.path.rawValue: "test/test",
+        GRPCHTTP2Keys.path.rawValue: "/test/test",
         GRPCHTTP2Keys.scheme.rawValue: "http",
         GRPCHTTP2Keys.method.rawValue: "POST",
         GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
@@ -1666,7 +1666,7 @@ final class GRPCStreamServerStateMachineTests: XCTestCase {
       action,
       .receivedMetadata(
         Metadata(headers: .clientInitialMetadata),
-        MethodDescriptor(fullyQualifiedMethod: "test/test")
+        MethodDescriptor(path: "/test/test")
       )
     )
   }
@@ -1679,7 +1679,7 @@ final class GRPCStreamServerStateMachineTests: XCTestCase {
       action,
       .receivedMetadata(
         Metadata(headers: .clientInitialMetadata),
-        MethodDescriptor(fullyQualifiedMethod: "test/test")
+        MethodDescriptor(path: "/test/test")
       )
     )
   }
@@ -2447,7 +2447,7 @@ final class GRPCStreamServerStateMachineTests: XCTestCase {
       receiveMetadataAction,
       .receivedMetadata(
         Metadata(headers: .clientInitialMetadata),
-        MethodDescriptor(fullyQualifiedMethod: "test/test")
+        MethodDescriptor(path: "/test/test")
       )
     )
 
@@ -2543,7 +2543,7 @@ final class GRPCStreamServerStateMachineTests: XCTestCase {
       receiveMetadataAction,
       .receivedMetadata(
         Metadata(headers: .clientInitialMetadata),
-        MethodDescriptor(fullyQualifiedMethod: "test/test")
+        MethodDescriptor(path: "/test/test")
       )
     )
 
@@ -2622,7 +2622,7 @@ final class GRPCStreamServerStateMachineTests: XCTestCase {
       receiveMetadataAction,
       .receivedMetadata(
         Metadata(headers: .clientInitialMetadata),
-        MethodDescriptor(fullyQualifiedMethod: "test/test")
+        MethodDescriptor(path: "/test/test")
       )
     )
 

+ 2 - 2
Tests/GRPCHTTP2CoreTests/Server/GRPCServerStreamHandlerTests.swift

@@ -798,7 +798,7 @@ final class GRPCServerStreamHandlerTests: XCTestCase {
 
     // Receive client's initial metadata
     let clientInitialMetadata: HPACKHeaders = [
-      GRPCHTTP2Keys.path.rawValue: "SomeService/SomeMethod",
+      GRPCHTTP2Keys.path.rawValue: "/SomeService/SomeMethod",
       GRPCHTTP2Keys.scheme.rawValue: "http",
       GRPCHTTP2Keys.method.rawValue: "POST",
       GRPCHTTP2Keys.contentType.rawValue: "application/grpc",
@@ -819,7 +819,7 @@ final class GRPCServerStreamHandlerTests: XCTestCase {
 
     XCTAssertEqual(
       try promise.futureResult.wait(),
-      MethodDescriptor(fullyQualifiedMethod: "SomeService/SomeMethod")
+      MethodDescriptor(path: "/SomeService/SomeMethod")
     )
   }