ServerInterceptor.swift 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright 2023, 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. /// A type that intercepts requests and response for server.
  17. ///
  18. /// Interceptors allow you to inspect and modify requests and responses. Requests are intercepted
  19. /// after they have been received by the transport and responses are intercepted after they have
  20. /// been returned from a service. They are typically used for cross-cutting concerns like filtering
  21. /// requests, validating messages, logging additional data, and tracing.
  22. ///
  23. /// Interceptors are registered with the server apply to all RPCs. If you need to modify the
  24. /// behavior of an interceptor on a per-RPC basis then you can use the
  25. /// ``ServerContext/descriptor`` to determine which RPC is being called and
  26. /// conditionalise behavior accordingly.
  27. ///
  28. /// ## RPC filtering
  29. ///
  30. /// A common use of server-side interceptors is to filter requests from clients. Interceptors can
  31. /// reject requests which are invalid without service code being called. The following example
  32. /// demonstrates this.
  33. ///
  34. /// ```swift
  35. /// struct AuthServerInterceptor: Sendable {
  36. /// let isAuthorized: @Sendable (String, MethodDescriptor) async throws -> Void
  37. ///
  38. /// func intercept<Input: Sendable, Output: Sendable>(
  39. /// request: StreamingServerRequest<Input>,
  40. /// context: ServerInterceptorContext,
  41. /// next: @Sendable (
  42. /// _ request: StreamingServerRequest<Input>,
  43. /// _ context: ServerInterceptorContext
  44. /// ) async throws -> StreamingServerResponse<Output>
  45. /// ) async throws -> StreamingServerResponse<Output> {
  46. /// // Extract the auth token.
  47. /// guard let token = request.metadata["authorization"] else {
  48. /// throw RPCError(code: .unauthenticated, message: "Not authenticated")
  49. /// }
  50. ///
  51. /// // Check whether it's valid.
  52. /// try await self.isAuthorized(token, context.descriptor)
  53. ///
  54. /// // Forward the request.
  55. /// return try await next(request, context)
  56. /// }
  57. /// }
  58. /// ```
  59. ///
  60. /// For client-side interceptors see ``ClientInterceptor``.
  61. public protocol ServerInterceptor: Sendable {
  62. /// Intercept a request object.
  63. ///
  64. /// - Parameters:
  65. /// - request: The request object.
  66. /// - context: Additional context about the request, including a descriptor
  67. /// of the method being called.
  68. /// - next: A closure to invoke to hand off the request and context to the next
  69. /// interceptor in the chain.
  70. /// - Returns: A response object.
  71. func intercept<Input: Sendable, Output: Sendable>(
  72. request: StreamingServerRequest<Input>,
  73. context: ServerContext,
  74. next: @Sendable (
  75. _ request: StreamingServerRequest<Input>,
  76. _ context: ServerContext
  77. ) async throws -> StreamingServerResponse<Output>
  78. ) async throws -> StreamingServerResponse<Output>
  79. }