| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /*
- * Copyright 2021, gRPC Authors All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- import Logging
- import NIOConcurrencyHelpers
- import NIOHPACK
- @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
- public struct GRPCAsyncServerCallContext: Sendable {
- @usableFromInline
- let contextProvider: AsyncServerCallContextProvider
- /// Details of the request, including request headers and a logger.
- public var request: Request
- /// A response context which may be used to set response headers and trailers.
- public var response: Response {
- Response(contextProvider: self.contextProvider)
- }
- /// Notifies the client that the RPC has been accepted for processing by the server.
- ///
- /// On accepting the RPC the server will send the given headers (which may be empty) along with
- /// any transport specific headers (such the ":status" pseudo header) to the client.
- ///
- /// It is not necessary to call this function: the RPC is implicitly accepted when the first
- /// response message is sent, however this may be useful when clients require an early indication
- /// that the RPC has been accepted.
- ///
- /// If the RPC has already been accepted (either implicitly or explicitly) then this function is
- /// a no-op.
- public func acceptRPC(headers: HPACKHeaders) async {
- await self.contextProvider.acceptRPC(headers)
- }
- /// Access the ``UserInfo`` dictionary which is shared with the interceptor contexts for this RPC.
- ///
- /// - Important: While ``UserInfo`` has value-semantics, this function accesses a reference
- /// wrapped ``UserInfo``. The contexts passed to interceptors provide the same reference. As such
- /// this may be used as a mechanism to pass information between interceptors and service
- /// providers.
- public func withUserInfo<Result: Sendable>(
- _ body: @Sendable @escaping (UserInfo) throws -> Result
- ) async throws -> Result {
- return try await self.contextProvider.withUserInfo(body)
- }
- /// Modify the ``UserInfo`` dictionary which is shared with the interceptor contexts for this RPC.
- ///
- /// - Important: While ``UserInfo`` has value-semantics, this function accesses a reference
- /// wrapped ``UserInfo``. The contexts passed to interceptors provide the same reference. As such
- /// this may be used as a mechanism to pass information between interceptors and service
- /// providers.
- public func withMutableUserInfo<Result: Sendable>(
- _ modify: @Sendable @escaping (inout UserInfo) -> Result
- ) async throws -> Result {
- return try await self.contextProvider.withMutableUserInfo(modify)
- }
- @inlinable
- internal init(
- headers: HPACKHeaders,
- logger: Logger,
- contextProvider: AsyncServerCallContextProvider
- ) {
- self.request = Request(headers: headers, logger: logger)
- self.contextProvider = contextProvider
- }
- }
- @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
- extension GRPCAsyncServerCallContext {
- public struct Request: Sendable {
- /// The request headers received from the client at the start of the RPC.
- public var headers: HPACKHeaders
- /// A logger.
- public var logger: Logger
- @usableFromInline
- init(headers: HPACKHeaders, logger: Logger) {
- self.headers = headers
- self.logger = logger
- }
- }
- public struct Response: Sendable {
- private let contextProvider: AsyncServerCallContextProvider
- /// Set the metadata to return at the start of the RPC.
- ///
- /// - Important: If this is required it should be updated _before_ the first response is sent
- /// via the response stream writer. Updates must not be made after the RPC has been accepted
- /// or the first response has been sent otherwise this method will throw an error.
- public func setHeaders(_ headers: HPACKHeaders) async throws {
- try await self.contextProvider.setResponseHeaders(headers)
- }
- /// Set the metadata to return at the end of the RPC.
- ///
- /// If this is required it must be updated before returning from the handler.
- public func setTrailers(_ trailers: HPACKHeaders) async throws {
- try await self.contextProvider.setResponseTrailers(trailers)
- }
- /// Whether compression should be enabled for responses, defaulting to `true`. Note that for
- /// this value to take effect compression must have been enabled on the server and a compression
- /// algorithm must have been negotiated with the client.
- public func compressResponses(_ compress: Bool) async throws {
- try await self.contextProvider.setResponseCompression(compress)
- }
- @usableFromInline
- internal init(contextProvider: AsyncServerCallContextProvider) {
- self.contextProvider = contextProvider
- }
- }
- }
|