| // | |
| // | |
| // Copyright 2015 gRPC authors. | |
| // | |
| // 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. | |
| // | |
| // | |
| /// A ClientContext allows the person implementing a service client to: | |
| /// | |
| /// - Add custom metadata key-value pairs that will propagated to the server | |
| /// side. | |
| /// - Control call settings such as compression and authentication. | |
| /// - Initial and trailing metadata coming from the server. | |
| /// - Get performance metrics (ie, census). | |
| /// | |
| /// Context settings are only relevant to the call they are invoked with, that | |
| /// is to say, they aren't sticky. Some of these settings, such as the | |
| /// compression options, can be made persistent at channel construction time | |
| /// (see \a grpc::CreateCustomChannel). | |
| /// | |
| /// \warning ClientContext instances should \em not be reused across rpcs. | |
| #ifndef GRPCPP_CLIENT_CONTEXT_H | |
| #define GRPCPP_CLIENT_CONTEXT_H | |
| #include <map> | |
| #include <memory> | |
| #include <string> | |
| #include <grpc/impl/compression_types.h> | |
| #include <grpc/impl/propagation_bits.h> | |
| #include <grpc/support/log.h> | |
| #include <grpcpp/impl/create_auth_context.h> | |
| #include <grpcpp/impl/metadata_map.h> | |
| #include <grpcpp/impl/rpc_method.h> | |
| #include <grpcpp/impl/sync.h> | |
| #include <grpcpp/security/auth_context.h> | |
| #include <grpcpp/support/client_interceptor.h> | |
| #include <grpcpp/support/config.h> | |
| #include <grpcpp/support/slice.h> | |
| #include <grpcpp/support/status.h> | |
| #include <grpcpp/support/string_ref.h> | |
| #include <grpcpp/support/time.h> | |
| struct census_context; | |
| struct grpc_call; | |
| namespace grpc { | |
| class ServerContext; | |
| class ServerContextBase; | |
| class CallbackServerContext; | |
| namespace internal { | |
| template <class InputMessage, class OutputMessage> | |
| class CallbackUnaryCallImpl; | |
| template <class Request, class Response> | |
| class ClientCallbackReaderWriterImpl; | |
| template <class Response> | |
| class ClientCallbackReaderImpl; | |
| template <class Request> | |
| class ClientCallbackWriterImpl; | |
| class ClientCallbackUnaryImpl; | |
| class ClientContextAccessor; | |
| class ClientAsyncResponseReaderHelper; | |
| } // namespace internal | |
| template <class R> | |
| class ClientReader; | |
| template <class W> | |
| class ClientWriter; | |
| template <class W, class R> | |
| class ClientReaderWriter; | |
| template <class R> | |
| class ClientAsyncReader; | |
| template <class W> | |
| class ClientAsyncWriter; | |
| template <class W, class R> | |
| class ClientAsyncReaderWriter; | |
| template <class R> | |
| class ClientAsyncResponseReader; | |
| namespace testing { | |
| class InteropClientContextInspector; | |
| class ClientContextTestPeer; | |
| } // namespace testing | |
| namespace internal { | |
| class RpcMethod; | |
| template <class InputMessage, class OutputMessage> | |
| class BlockingUnaryCallImpl; | |
| class CallOpClientRecvStatus; | |
| class CallOpRecvInitialMetadata; | |
| class ServerContextImpl; | |
| template <class InputMessage, class OutputMessage> | |
| class CallbackUnaryCallImpl; | |
| template <class Request, class Response> | |
| class ClientCallbackReaderWriterImpl; | |
| template <class Response> | |
| class ClientCallbackReaderImpl; | |
| template <class Request> | |
| class ClientCallbackWriterImpl; | |
| class ClientCallbackUnaryImpl; | |
| class ClientContextAccessor; | |
| } // namespace internal | |
| class CallCredentials; | |
| class Channel; | |
| class ChannelInterface; | |
| class CompletionQueue; | |
| /// Options for \a ClientContext::FromServerContext specifying which traits from | |
| /// the \a ServerContext to propagate (copy) from it into a new \a | |
| /// ClientContext. | |
| /// | |
| /// \see ClientContext::FromServerContext | |
| class PropagationOptions { | |
| public: | |
| PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} | |
| PropagationOptions& enable_deadline_propagation() { | |
| propagate_ |= GRPC_PROPAGATE_DEADLINE; | |
| return *this; | |
| } | |
| PropagationOptions& disable_deadline_propagation() { | |
| propagate_ &= ~GRPC_PROPAGATE_DEADLINE; | |
| return *this; | |
| } | |
| PropagationOptions& enable_census_stats_propagation() { | |
| propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; | |
| return *this; | |
| } | |
| PropagationOptions& disable_census_stats_propagation() { | |
| propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; | |
| return *this; | |
| } | |
| PropagationOptions& enable_census_tracing_propagation() { | |
| propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; | |
| return *this; | |
| } | |
| PropagationOptions& disable_census_tracing_propagation() { | |
| propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; | |
| return *this; | |
| } | |
| PropagationOptions& enable_cancellation_propagation() { | |
| propagate_ |= GRPC_PROPAGATE_CANCELLATION; | |
| return *this; | |
| } | |
| PropagationOptions& disable_cancellation_propagation() { | |
| propagate_ &= ~GRPC_PROPAGATE_CANCELLATION; | |
| return *this; | |
| } | |
| uint32_t c_bitmask() const { return propagate_; } | |
| private: | |
| uint32_t propagate_; | |
| }; | |
| /// A ClientContext allows the person implementing a service client to: | |
| /// | |
| /// - Add custom metadata key-value pairs that will propagated to the server | |
| /// side. | |
| /// - Control call settings such as compression and authentication. | |
| /// - Initial and trailing metadata coming from the server. | |
| /// - Get performance metrics (ie, census). | |
| /// | |
| /// Context settings are only relevant to the call they are invoked with, that | |
| /// is to say, they aren't sticky. Some of these settings, such as the | |
| /// compression options, can be made persistent at channel construction time | |
| /// (see \a grpc::CreateCustomChannel). | |
| /// | |
| /// \warning ClientContext instances should \em not be reused across rpcs. | |
| /// \warning The ClientContext instance used for creating an rpc must remain | |
| /// alive and valid for the lifetime of the rpc. | |
| class ClientContext { | |
| public: | |
| ClientContext(); | |
| ~ClientContext(); | |
| /// Create a new \a ClientContext as a child of an incoming server call, | |
| /// according to \a options (\see PropagationOptions). | |
| /// | |
| /// \param server_context The source server context to use as the basis for | |
| /// constructing the client context. | |
| /// \param options The options controlling what to copy from the \a | |
| /// server_context. | |
| /// | |
| /// \return A newly constructed \a ClientContext instance based on \a | |
| /// server_context, with traits propagated (copied) according to \a options. | |
| static std::unique_ptr<ClientContext> FromServerContext( | |
| const grpc::ServerContextBase& server_context, | |
| PropagationOptions options = PropagationOptions()); | |
| static std::unique_ptr<ClientContext> FromCallbackServerContext( | |
| const grpc::CallbackServerContext& server_context, | |
| PropagationOptions options = PropagationOptions()); | |
| /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with | |
| /// a client call. These are made available at the server side by the \a | |
| /// grpc::ServerContext::client_metadata() method. | |
| /// | |
| /// \warning This method should only be called before invoking the rpc. | |
| /// | |
| /// \param meta_key The metadata key. If \a meta_value is binary data, it must | |
| /// end in "-bin". | |
| /// \param meta_value The metadata value. If its value is binary, the key name | |
| /// must end in "-bin". | |
| /// | |
| /// Metadata must conform to the following format: | |
| /// | |
| ///\verbatim | |
| /// Custom-Metadata -> Binary-Header / ASCII-Header | |
| /// Binary-Header -> {Header-Name "-bin" } {binary value} | |
| /// ASCII-Header -> Header-Name ASCII-Value | |
| /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . | |
| /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII | |
| /// Custom-Metadata -> Binary-Header / ASCII-Header | |
| ///\endverbatim | |
| /// | |
| void AddMetadata(const std::string& meta_key, const std::string& meta_value); | |
| /// Return a collection of initial metadata key-value pairs. Note that keys | |
| /// may happen more than once (ie, a \a std::multimap is returned). | |
| /// | |
| /// \warning This method should only be called after initial metadata has been | |
| /// received. For streaming calls, see \a | |
| /// ClientReaderInterface::WaitForInitialMetadata(). | |
| /// | |
| /// \return A multimap of initial metadata key-value pairs from the server. | |
| const std::multimap<grpc::string_ref, grpc::string_ref>& | |
| GetServerInitialMetadata() const { | |
| GPR_ASSERT(initial_metadata_received_); | |
| return *recv_initial_metadata_.map(); | |
| } | |
| /// Return a collection of trailing metadata key-value pairs. Note that keys | |
| /// may happen more than once (ie, a \a std::multimap is returned). | |
| /// | |
| /// \warning This method is only callable once the stream has finished. | |
| /// | |
| /// \return A multimap of metadata trailing key-value pairs from the server. | |
| const std::multimap<grpc::string_ref, grpc::string_ref>& | |
| GetServerTrailingMetadata() const { | |
| // TODO(yangg) check finished | |
| return *trailing_metadata_.map(); | |
| } | |
| /// Set the deadline for the client call. | |
| /// | |
| /// \warning This method should only be called before invoking the rpc. | |
| /// | |
| /// \param deadline the deadline for the client call. Units are determined by | |
| /// the type used. The deadline is an absolute (not relative) time. | |
| template <typename T> | |
| void set_deadline(const T& deadline) { | |
| grpc::TimePoint<T> deadline_tp(deadline); | |
| deadline_ = deadline_tp.raw_time(); | |
| } | |
| /// Trigger wait-for-ready or not on this request. | |
| /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. | |
| /// If set, if an RPC is made when a channel's connectivity state is | |
| /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", | |
| /// and the channel will wait until the channel is READY before making the | |
| /// call. | |
| void set_wait_for_ready(bool wait_for_ready) { | |
| wait_for_ready_ = wait_for_ready; | |
| wait_for_ready_explicitly_set_ = true; | |
| } | |
| /// DEPRECATED: Use set_wait_for_ready() instead. | |
| void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); } | |
| /// Return the deadline for the client call. | |
| std::chrono::system_clock::time_point deadline() const { | |
| return grpc::Timespec2Timepoint(deadline_); | |
| } | |
| /// Return a \a gpr_timespec representation of the client call's deadline. | |
| gpr_timespec raw_deadline() const { return deadline_; } | |
| /// Set the per call authority header (see | |
| /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). | |
| void set_authority(const std::string& authority) { authority_ = authority; } | |
| /// Return the authentication context for the associated client call. | |
| /// It is only valid to call this during the lifetime of the client call. | |
| /// | |
| /// \see grpc::AuthContext. | |
| std::shared_ptr<const grpc::AuthContext> auth_context() const { | |
| if (auth_context_ == nullptr) { | |
| auth_context_ = grpc::CreateAuthContext(call_); | |
| } | |
| return auth_context_; | |
| } | |
| /// Set credentials for the client call. | |
| /// | |
| /// A credentials object encapsulates all the state needed by a client to | |
| /// authenticate with a server and make various assertions, e.g., about the | |
| /// client’s identity, role, or whether it is authorized to make a particular | |
| /// call. | |
| /// | |
| /// It is legal to call this only before initial metadata is sent. | |
| /// | |
| /// \see https://grpc.io/docs/guides/auth.html | |
| void set_credentials(const std::shared_ptr<grpc::CallCredentials>& creds); | |
| /// EXPERIMENTAL debugging API | |
| /// | |
| /// Returns the credentials for the client call. This should be used only in | |
| /// tests and for diagnostic purposes, and should not be used by application | |
| /// logic. | |
| std::shared_ptr<grpc::CallCredentials> credentials() { return creds_; } | |
| /// Return the compression algorithm the client call will request be used. | |
| /// Note that the gRPC runtime may decide to ignore this request, for example, | |
| /// due to resource constraints. | |
| grpc_compression_algorithm compression_algorithm() const { | |
| return compression_algorithm_; | |
| } | |
| /// Set \a algorithm to be the compression algorithm used for the client call. | |
| /// | |
| /// \param algorithm The compression algorithm used for the client call. | |
| void set_compression_algorithm(grpc_compression_algorithm algorithm); | |
| /// Flag whether the initial metadata should be \a corked | |
| /// | |
| /// If \a corked is true, then the initial metadata will be coalesced with the | |
| /// write of first message in the stream. As a result, any tag set for the | |
| /// initial metadata operation (starting a client-streaming or bidi-streaming | |
| /// RPC) will not actually be sent to the completion queue or delivered | |
| /// via Next. | |
| /// | |
| /// \param corked The flag indicating whether the initial metadata is to be | |
| /// corked or not. | |
| void set_initial_metadata_corked(bool corked) { | |
| initial_metadata_corked_ = corked; | |
| } | |
| /// Return the peer uri in a string. | |
| /// It is only valid to call this during the lifetime of the client call. | |
| /// | |
| /// \warning This value is never authenticated or subject to any security | |
| /// related code. It must not be used for any authentication related | |
| /// functionality. Instead, use auth_context. | |
| /// | |
| /// \return The call's peer URI. | |
| std::string peer() const; | |
| /// Sets the census context. | |
| /// It is only valid to call this before the client call is created. A common | |
| /// place of setting census context is from within the DefaultConstructor | |
| /// method of GlobalCallbacks. | |
| void set_census_context(struct census_context* ccp) { census_context_ = ccp; } | |
| /// Returns the census context that has been set, or nullptr if not set. | |
| struct census_context* census_context() const { return census_context_; } | |
| /// Send a best-effort out-of-band cancel on the call associated with | |
| /// this client context. The call could be in any stage; e.g., if it is | |
| /// already finished, it may still return success. | |
| /// | |
| /// There is no guarantee the call will be cancelled. | |
| /// | |
| /// Note that TryCancel() does not change any of the tags that are pending | |
| /// on the completion queue. All pending tags will still be delivered | |
| /// (though their ok result may reflect the effect of cancellation). | |
| /// | |
| /// This method is thread-safe, and can be called multiple times from any | |
| /// thread. | |
| void TryCancel(); | |
| /// Global Callbacks | |
| /// | |
| /// Can be set exactly once per application to install hooks whenever | |
| /// a client context is constructed and destructed. | |
| class GlobalCallbacks { | |
| public: | |
| virtual ~GlobalCallbacks() {} | |
| virtual void DefaultConstructor(ClientContext* context) = 0; | |
| virtual void Destructor(ClientContext* context) = 0; | |
| }; | |
| static void SetGlobalCallbacks(GlobalCallbacks* callbacks); | |
| /// Should be used for framework-level extensions only. | |
| /// Applications never need to call this method. | |
| grpc_call* c_call() { return call_; } | |
| /// EXPERIMENTAL debugging API | |
| /// | |
| /// if status is not ok() for an RPC, this will return a detailed string | |
| /// of the gRPC Core error that led to the failure. It should not be relied | |
| /// upon for anything other than gaining more debug data in failure cases. | |
| std::string debug_error_string() const { return debug_error_string_; } | |
| private: | |
| // Disallow copy and assign. | |
| ClientContext(const ClientContext&); | |
| ClientContext& operator=(const ClientContext&); | |
| friend class grpc::testing::InteropClientContextInspector; | |
| friend class grpc::testing::ClientContextTestPeer; | |
| friend class grpc::internal::CallOpClientRecvStatus; | |
| friend class grpc::internal::CallOpRecvInitialMetadata; | |
| friend class grpc::Channel; | |
| template <class R> | |
| friend class grpc::ClientReader; | |
| template <class W> | |
| friend class grpc::ClientWriter; | |
| template <class W, class R> | |
| friend class grpc::ClientReaderWriter; | |
| template <class R> | |
| friend class grpc::ClientAsyncReader; | |
| template <class W> | |
| friend class grpc::ClientAsyncWriter; | |
| template <class W, class R> | |
| friend class grpc::ClientAsyncReaderWriter; | |
| template <class R> | |
| friend class grpc::ClientAsyncResponseReader; | |
| friend class grpc::internal::ClientAsyncResponseReaderHelper; | |
| template <class InputMessage, class OutputMessage> | |
| friend class grpc::internal::BlockingUnaryCallImpl; | |
| template <class InputMessage, class OutputMessage> | |
| friend class grpc::internal::CallbackUnaryCallImpl; | |
| template <class Request, class Response> | |
| friend class grpc::internal::ClientCallbackReaderWriterImpl; | |
| template <class Response> | |
| friend class grpc::internal::ClientCallbackReaderImpl; | |
| template <class Request> | |
| friend class grpc::internal::ClientCallbackWriterImpl; | |
| friend class grpc::internal::ClientCallbackUnaryImpl; | |
| friend class grpc::internal::ClientContextAccessor; | |
| // Used by friend class CallOpClientRecvStatus | |
| void set_debug_error_string(const std::string& debug_error_string) { | |
| debug_error_string_ = debug_error_string; | |
| } | |
| grpc_call* call() const { return call_; } | |
| void set_call(grpc_call* call, const std::shared_ptr<grpc::Channel>& channel); | |
| grpc::experimental::ClientRpcInfo* set_client_rpc_info( | |
| const char* method, const char* suffix_for_stats, | |
| grpc::internal::RpcMethod::RpcType type, grpc::ChannelInterface* channel, | |
| const std::vector<std::unique_ptr< | |
| grpc::experimental::ClientInterceptorFactoryInterface>>& creators, | |
| size_t interceptor_pos) { | |
| rpc_info_ = grpc::experimental::ClientRpcInfo(this, type, method, | |
| suffix_for_stats, channel); | |
| rpc_info_.RegisterInterceptors(creators, interceptor_pos); | |
| return &rpc_info_; | |
| } | |
| uint32_t initial_metadata_flags() const { | |
| return (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) | | |
| (wait_for_ready_explicitly_set_ | |
| ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET | |
| : 0); | |
| } | |
| std::string authority() { return authority_; } | |
| void SendCancelToInterceptors(); | |
| static std::unique_ptr<ClientContext> FromInternalServerContext( | |
| const grpc::ServerContextBase& server_context, | |
| PropagationOptions options); | |
| bool initial_metadata_received_; | |
| bool wait_for_ready_; | |
| bool wait_for_ready_explicitly_set_; | |
| std::shared_ptr<grpc::Channel> channel_; | |
| grpc::internal::Mutex mu_; | |
| grpc_call* call_; | |
| bool call_canceled_; | |
| gpr_timespec deadline_; | |
| grpc::string authority_; | |
| std::shared_ptr<grpc::CallCredentials> creds_; | |
| mutable std::shared_ptr<const grpc::AuthContext> auth_context_; | |
| struct census_context* census_context_; | |
| std::multimap<std::string, std::string> send_initial_metadata_; | |
| mutable grpc::internal::MetadataMap recv_initial_metadata_; | |
| mutable grpc::internal::MetadataMap trailing_metadata_; | |
| grpc_call* propagate_from_call_; | |
| PropagationOptions propagation_options_; | |
| grpc_compression_algorithm compression_algorithm_; | |
| bool initial_metadata_corked_; | |
| std::string debug_error_string_; | |
| grpc::experimental::ClientRpcInfo rpc_info_; | |
| }; | |
| } // namespace grpc | |
| #endif // GRPCPP_CLIENT_CONTEXT_H |