GRPCServerRequestRoutingHandler.swift 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright 2019, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Logging
  17. import NIO
  18. import NIOHPACK
  19. import NIOHTTP1
  20. import NIOHTTP2
  21. import SwiftProtobuf
  22. /// Processes individual gRPC messages and stream-close events on an HTTP2 channel.
  23. public protocol GRPCCallHandler: ChannelHandler {}
  24. /// Provides `GRPCCallHandler` objects for the methods on a particular service name.
  25. ///
  26. /// Implemented by the generated code.
  27. public protocol CallHandlerProvider: AnyObject {
  28. /// The name of the service this object is providing methods for, including the package path.
  29. ///
  30. /// - Example: "io.grpc.Echo.EchoService"
  31. var serviceName: Substring { get }
  32. /// Determines, calls and returns the appropriate request handler (`GRPCCallHandler`), depending on the request's
  33. /// method. Returns nil for methods not handled by this service.
  34. func handleMethod(_ methodName: Substring, callHandlerContext: CallHandlerContext)
  35. -> GRPCCallHandler?
  36. /// Returns a call handler for the method with the given name, if this service provider implements
  37. /// the given method. Returns `nil` if the method is not handled by this provider.
  38. /// - Parameters:
  39. /// - name: The name of the method to handle.
  40. /// - context: An opaque context providing components to construct the handler with.
  41. func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol?
  42. }
  43. extension CallHandlerProvider {
  44. // TODO: remove this once we've removed 'handleMethod(_:callHandlerContext:)'.
  45. public func handle(
  46. method name: Substring,
  47. context: CallHandlerContext
  48. ) -> GRPCServerHandlerProtocol? {
  49. return nil
  50. }
  51. // TODO: remove this once we've removed 'handleMethod(_:callHandlerContext:)'.
  52. public func handleMethod(
  53. _ methodName: Substring,
  54. callHandlerContext: CallHandlerContext
  55. ) -> GRPCCallHandler? {
  56. return nil
  57. }
  58. }
  59. // This is public because it will be passed into generated code, all members are `internal` because
  60. // the context will get passed from generated code back into gRPC library code and all members should
  61. // be considered an implementation detail to the user.
  62. public struct CallHandlerContext {
  63. @usableFromInline
  64. internal var errorDelegate: ServerErrorDelegate?
  65. @usableFromInline
  66. internal var logger: Logger
  67. @usableFromInline
  68. internal var encoding: ServerMessageEncoding
  69. @usableFromInline
  70. internal var eventLoop: EventLoop
  71. @usableFromInline
  72. internal var path: String
  73. @usableFromInline
  74. internal var remoteAddress: SocketAddress?
  75. @usableFromInline
  76. internal var responseWriter: GRPCServerResponseWriter
  77. @usableFromInline
  78. internal var allocator: ByteBufferAllocator
  79. }
  80. /// A call URI split into components.
  81. struct CallPath {
  82. /// The name of the service to call.
  83. var service: String.UTF8View.SubSequence
  84. /// The name of the method to call.
  85. var method: String.UTF8View.SubSequence
  86. /// Character used to split the path into components.
  87. private let pathSplitDelimiter = UInt8(ascii: "/")
  88. /// Split a path into service and method.
  89. /// Split is done in UTF8 as this turns out to be approximately 10x faster than a simple split.
  90. /// URI format: "/package.Servicename/MethodName"
  91. init?(requestURI: String) {
  92. var utf8View = requestURI.utf8[...]
  93. // Check and remove the split character at the beginning.
  94. guard let prefix = utf8View.trimPrefix(to: self.pathSplitDelimiter), prefix.isEmpty else {
  95. return nil
  96. }
  97. guard let service = utf8View.trimPrefix(to: pathSplitDelimiter) else {
  98. return nil
  99. }
  100. guard let method = utf8View.trimPrefix(to: pathSplitDelimiter) else {
  101. return nil
  102. }
  103. self.service = service
  104. self.method = method
  105. }
  106. }
  107. extension Collection where Self == Self.SubSequence, Self.Element: Equatable {
  108. /// Trims out the prefix up to `separator`, and returns it.
  109. /// Sets self to the subsequence after the separator, and returns the subsequence before the separator.
  110. /// If self is empty returns `nil`
  111. /// - parameters:
  112. /// - separator : The Element between the head which is returned and the rest which is left in self.
  113. /// - returns: SubSequence containing everything between the beginning and the first occurrence of
  114. /// `separator`. If `separator` is not found this will be the entire Collection. If the collection is empty
  115. /// returns `nil`
  116. mutating func trimPrefix(to separator: Element) -> SubSequence? {
  117. guard !self.isEmpty else {
  118. return nil
  119. }
  120. if let separatorIndex = self.firstIndex(of: separator) {
  121. let indexAfterSeparator = self.index(after: separatorIndex)
  122. defer { self = self[indexAfterSeparator...] }
  123. return self[..<separatorIndex]
  124. } else {
  125. defer { self = self[self.endIndex...] }
  126. return self[...]
  127. }
  128. }
  129. }