1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 /// A ClientContext allows the person implementing a service client to: 20 /// 21 /// - Add custom metadata key-value pairs that will propagated to the server 22 /// side. 23 /// - Control call settings such as compression and authentication. 24 /// - Initial and trailing metadata coming from the server. 25 /// - Get performance metrics (ie, census). 26 /// 27 /// Context settings are only relevant to the call they are invoked with, that 28 /// is to say, they aren't sticky. Some of these settings, such as the 29 /// compression options, can be made persistent at channel construction time 30 /// (see \a grpc::CreateCustomChannel). 31 /// 32 /// \warning ClientContext instances should \em not be reused across rpcs. 33 34 #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H 35 #define GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H 36 37 #include <map> 38 #include <memory> 39 #include <mutex> 40 #include <string> 41 42 #include <grpc/impl/codegen/compression_types.h> 43 #include <grpc/impl/codegen/propagation_bits.h> 44 #include <grpcpp/impl/codegen/config.h> 45 #include <grpcpp/impl/codegen/core_codegen_interface.h> 46 #include <grpcpp/impl/codegen/create_auth_context.h> 47 #include <grpcpp/impl/codegen/metadata_map.h> 48 #include <grpcpp/impl/codegen/security/auth_context.h> 49 #include <grpcpp/impl/codegen/slice.h> 50 #include <grpcpp/impl/codegen/status.h> 51 #include <grpcpp/impl/codegen/string_ref.h> 52 #include <grpcpp/impl/codegen/time.h> 53 54 struct census_context; 55 struct grpc_call; 56 57 namespace grpc { 58 59 class Channel; 60 class ChannelInterface; 61 class CompletionQueue; 62 class CallCredentials; 63 class ClientContext; 64 65 namespace internal { 66 class RpcMethod; 67 class CallOpClientRecvStatus; 68 class CallOpRecvInitialMetadata; 69 template <class InputMessage, class OutputMessage> 70 class BlockingUnaryCallImpl; 71 template <class InputMessage, class OutputMessage> 72 class CallbackUnaryCallImpl; 73 } // namespace internal 74 75 template <class R> 76 class ClientReader; 77 template <class W> 78 class ClientWriter; 79 template <class W, class R> 80 class ClientReaderWriter; 81 template <class R> 82 class ClientAsyncReader; 83 template <class W> 84 class ClientAsyncWriter; 85 template <class W, class R> 86 class ClientAsyncReaderWriter; 87 template <class R> 88 class ClientAsyncResponseReader; 89 class ServerContext; 90 91 /// Options for \a ClientContext::FromServerContext specifying which traits from 92 /// the \a ServerContext to propagate (copy) from it into a new \a 93 /// ClientContext. 94 /// 95 /// \see ClientContext::FromServerContext 96 class PropagationOptions { 97 public: PropagationOptions()98 PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} 99 enable_deadline_propagation()100 PropagationOptions& enable_deadline_propagation() { 101 propagate_ |= GRPC_PROPAGATE_DEADLINE; 102 return *this; 103 } 104 disable_deadline_propagation()105 PropagationOptions& disable_deadline_propagation() { 106 propagate_ &= ~GRPC_PROPAGATE_DEADLINE; 107 return *this; 108 } 109 enable_census_stats_propagation()110 PropagationOptions& enable_census_stats_propagation() { 111 propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; 112 return *this; 113 } 114 disable_census_stats_propagation()115 PropagationOptions& disable_census_stats_propagation() { 116 propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; 117 return *this; 118 } 119 enable_census_tracing_propagation()120 PropagationOptions& enable_census_tracing_propagation() { 121 propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; 122 return *this; 123 } 124 disable_census_tracing_propagation()125 PropagationOptions& disable_census_tracing_propagation() { 126 propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; 127 return *this; 128 } 129 enable_cancellation_propagation()130 PropagationOptions& enable_cancellation_propagation() { 131 propagate_ |= GRPC_PROPAGATE_CANCELLATION; 132 return *this; 133 } 134 disable_cancellation_propagation()135 PropagationOptions& disable_cancellation_propagation() { 136 propagate_ &= ~GRPC_PROPAGATE_CANCELLATION; 137 return *this; 138 } 139 c_bitmask()140 uint32_t c_bitmask() const { return propagate_; } 141 142 private: 143 uint32_t propagate_; 144 }; 145 146 namespace testing { 147 class InteropClientContextInspector; 148 } // namespace testing 149 150 /// A ClientContext allows the person implementing a service client to: 151 /// 152 /// - Add custom metadata key-value pairs that will propagated to the server 153 /// side. 154 /// - Control call settings such as compression and authentication. 155 /// - Initial and trailing metadata coming from the server. 156 /// - Get performance metrics (ie, census). 157 /// 158 /// Context settings are only relevant to the call they are invoked with, that 159 /// is to say, they aren't sticky. Some of these settings, such as the 160 /// compression options, can be made persistent at channel construction time 161 /// (see \a grpc::CreateCustomChannel). 162 /// 163 /// \warning ClientContext instances should \em not be reused across rpcs. 164 class ClientContext { 165 public: 166 ClientContext(); 167 ~ClientContext(); 168 169 /// Create a new \a ClientContext as a child of an incoming server call, 170 /// according to \a options (\see PropagationOptions). 171 /// 172 /// \param server_context The source server context to use as the basis for 173 /// constructing the client context. 174 /// \param options The options controlling what to copy from the \a 175 /// server_context. 176 /// 177 /// \return A newly constructed \a ClientContext instance based on \a 178 /// server_context, with traits propagated (copied) according to \a options. 179 static std::unique_ptr<ClientContext> FromServerContext( 180 const ServerContext& server_context, 181 PropagationOptions options = PropagationOptions()); 182 183 /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with 184 /// a client call. These are made available at the server side by the \a 185 /// grpc::ServerContext::client_metadata() method. 186 /// 187 /// \warning This method should only be called before invoking the rpc. 188 /// 189 /// \param meta_key The metadata key. If \a meta_value is binary data, it must 190 /// end in "-bin". 191 /// \param meta_value The metadata value. If its value is binary, the key name 192 /// must end in "-bin". 193 void AddMetadata(const grpc::string& meta_key, 194 const grpc::string& meta_value); 195 196 /// Return a collection of initial metadata key-value pairs. Note that keys 197 /// may happen more than once (ie, a \a std::multimap is returned). 198 /// 199 /// \warning This method should only be called after initial metadata has been 200 /// received. For streaming calls, see \a 201 /// ClientReaderInterface::WaitForInitialMetadata(). 202 /// 203 /// \return A multimap of initial metadata key-value pairs from the server. 204 const std::multimap<grpc::string_ref, grpc::string_ref>& GetServerInitialMetadata()205 GetServerInitialMetadata() const { 206 GPR_CODEGEN_ASSERT(initial_metadata_received_); 207 return *recv_initial_metadata_.map(); 208 } 209 210 /// Return a collection of trailing metadata key-value pairs. Note that keys 211 /// may happen more than once (ie, a \a std::multimap is returned). 212 /// 213 /// \warning This method is only callable once the stream has finished. 214 /// 215 /// \return A multimap of metadata trailing key-value pairs from the server. 216 const std::multimap<grpc::string_ref, grpc::string_ref>& GetServerTrailingMetadata()217 GetServerTrailingMetadata() const { 218 // TODO(yangg) check finished 219 return *trailing_metadata_.map(); 220 } 221 222 /// Set the deadline for the client call. 223 /// 224 /// \warning This method should only be called before invoking the rpc. 225 /// 226 /// \param deadline the deadline for the client call. Units are determined by 227 /// the type used. 228 template <typename T> set_deadline(const T & deadline)229 void set_deadline(const T& deadline) { 230 TimePoint<T> deadline_tp(deadline); 231 deadline_ = deadline_tp.raw_time(); 232 } 233 234 /// EXPERIMENTAL: Indicate that this request is idempotent. 235 /// By default, RPCs are assumed to <i>not</i> be idempotent. 236 /// 237 /// If true, the gRPC library assumes that it's safe to initiate 238 /// this RPC multiple times. set_idempotent(bool idempotent)239 void set_idempotent(bool idempotent) { idempotent_ = idempotent; } 240 241 /// EXPERIMENTAL: Set this request to be cacheable. 242 /// If set, grpc is free to use the HTTP GET verb for sending the request, 243 /// with the possibility of receiving a cached response. set_cacheable(bool cacheable)244 void set_cacheable(bool cacheable) { cacheable_ = cacheable; } 245 246 /// EXPERIMENTAL: Trigger wait-for-ready or not on this request. 247 /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. 248 /// If set, if an RPC is made when a channel's connectivity state is 249 /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", 250 /// and the channel will wait until the channel is READY before making the 251 /// call. set_wait_for_ready(bool wait_for_ready)252 void set_wait_for_ready(bool wait_for_ready) { 253 wait_for_ready_ = wait_for_ready; 254 wait_for_ready_explicitly_set_ = true; 255 } 256 257 /// DEPRECATED: Use set_wait_for_ready() instead. set_fail_fast(bool fail_fast)258 void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); } 259 260 /// Return the deadline for the client call. deadline()261 std::chrono::system_clock::time_point deadline() const { 262 return Timespec2Timepoint(deadline_); 263 } 264 265 /// Return a \a gpr_timespec representation of the client call's deadline. raw_deadline()266 gpr_timespec raw_deadline() const { return deadline_; } 267 268 /// Set the per call authority header (see 269 /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). set_authority(const grpc::string & authority)270 void set_authority(const grpc::string& authority) { authority_ = authority; } 271 272 /// Return the authentication context for this client call. 273 /// 274 /// \see grpc::AuthContext. auth_context()275 std::shared_ptr<const AuthContext> auth_context() const { 276 if (auth_context_.get() == nullptr) { 277 auth_context_ = CreateAuthContext(call_); 278 } 279 return auth_context_; 280 } 281 282 /// Set credentials for the client call. 283 /// 284 /// A credentials object encapsulates all the state needed by a client to 285 /// authenticate with a server and make various assertions, e.g., about the 286 /// client’s identity, role, or whether it is authorized to make a particular 287 /// call. 288 /// 289 /// \see https://grpc.io/docs/guides/auth.html set_credentials(const std::shared_ptr<CallCredentials> & creds)290 void set_credentials(const std::shared_ptr<CallCredentials>& creds) { 291 creds_ = creds; 292 } 293 294 /// Return the compression algorithm the client call will request be used. 295 /// Note that the gRPC runtime may decide to ignore this request, for example, 296 /// due to resource constraints. compression_algorithm()297 grpc_compression_algorithm compression_algorithm() const { 298 return compression_algorithm_; 299 } 300 301 /// Set \a algorithm to be the compression algorithm used for the client call. 302 /// 303 /// \param algorithm The compression algorithm used for the client call. 304 void set_compression_algorithm(grpc_compression_algorithm algorithm); 305 306 /// Flag whether the initial metadata should be \a corked 307 /// 308 /// If \a corked is true, then the initial metadata will be coalesced with the 309 /// write of first message in the stream. As a result, any tag set for the 310 /// initial metadata operation (starting a client-streaming or bidi-streaming 311 /// RPC) will not actually be sent to the completion queue or delivered 312 /// via Next. 313 /// 314 /// \param corked The flag indicating whether the initial metadata is to be 315 /// corked or not. set_initial_metadata_corked(bool corked)316 void set_initial_metadata_corked(bool corked) { 317 initial_metadata_corked_ = corked; 318 } 319 320 /// Return the peer uri in a string. 321 /// 322 /// \warning This value is never authenticated or subject to any security 323 /// related code. It must not be used for any authentication related 324 /// functionality. Instead, use auth_context. 325 /// 326 /// \return The call's peer URI. 327 grpc::string peer() const; 328 329 /// Get and set census context. set_census_context(struct census_context * ccp)330 void set_census_context(struct census_context* ccp) { census_context_ = ccp; } census_context()331 struct census_context* census_context() const { 332 return census_context_; 333 } 334 335 /// Send a best-effort out-of-band cancel on the call associated with 336 /// this client context. The call could be in any stage; e.g., if it is 337 /// already finished, it may still return success. 338 /// 339 /// There is no guarantee the call will be cancelled. 340 /// 341 /// Note that TryCancel() does not change any of the tags that are pending 342 /// on the completion queue. All pending tags will still be delivered 343 /// (though their ok result may reflect the effect of cancellation). 344 void TryCancel(); 345 346 /// Global Callbacks 347 /// 348 /// Can be set exactly once per application to install hooks whenever 349 /// a client context is constructed and destructed. 350 class GlobalCallbacks { 351 public: ~GlobalCallbacks()352 virtual ~GlobalCallbacks() {} 353 virtual void DefaultConstructor(ClientContext* context) = 0; 354 virtual void Destructor(ClientContext* context) = 0; 355 }; 356 static void SetGlobalCallbacks(GlobalCallbacks* callbacks); 357 358 /// Should be used for framework-level extensions only. 359 /// Applications never need to call this method. c_call()360 grpc_call* c_call() { return call_; } 361 362 /// EXPERIMENTAL debugging API 363 /// 364 /// if status is not ok() for an RPC, this will return a detailed string 365 /// of the gRPC Core error that led to the failure. It should not be relied 366 /// upon for anything other than gaining more debug data in failure cases. debug_error_string()367 grpc::string debug_error_string() const { return debug_error_string_; } 368 369 private: 370 // Disallow copy and assign. 371 ClientContext(const ClientContext&); 372 ClientContext& operator=(const ClientContext&); 373 374 friend class ::grpc::testing::InteropClientContextInspector; 375 friend class ::grpc::internal::CallOpClientRecvStatus; 376 friend class ::grpc::internal::CallOpRecvInitialMetadata; 377 friend class Channel; 378 template <class R> 379 friend class ::grpc::ClientReader; 380 template <class W> 381 friend class ::grpc::ClientWriter; 382 template <class W, class R> 383 friend class ::grpc::ClientReaderWriter; 384 template <class R> 385 friend class ::grpc::ClientAsyncReader; 386 template <class W> 387 friend class ::grpc::ClientAsyncWriter; 388 template <class W, class R> 389 friend class ::grpc::ClientAsyncReaderWriter; 390 template <class R> 391 friend class ::grpc::ClientAsyncResponseReader; 392 template <class InputMessage, class OutputMessage> 393 friend class ::grpc::internal::BlockingUnaryCallImpl; 394 template <class InputMessage, class OutputMessage> 395 friend class ::grpc::internal::CallbackUnaryCallImpl; 396 397 // Used by friend class CallOpClientRecvStatus set_debug_error_string(const grpc::string & debug_error_string)398 void set_debug_error_string(const grpc::string& debug_error_string) { 399 debug_error_string_ = debug_error_string; 400 } 401 call()402 grpc_call* call() const { return call_; } 403 void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel); 404 initial_metadata_flags()405 uint32_t initial_metadata_flags() const { 406 return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) | 407 (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) | 408 (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) | 409 (wait_for_ready_explicitly_set_ 410 ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET 411 : 0) | 412 (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0); 413 } 414 authority()415 grpc::string authority() { return authority_; } 416 417 bool initial_metadata_received_; 418 bool wait_for_ready_; 419 bool wait_for_ready_explicitly_set_; 420 bool idempotent_; 421 bool cacheable_; 422 std::shared_ptr<Channel> channel_; 423 std::mutex mu_; 424 grpc_call* call_; 425 bool call_canceled_; 426 gpr_timespec deadline_; 427 grpc::string authority_; 428 std::shared_ptr<CallCredentials> creds_; 429 mutable std::shared_ptr<const AuthContext> auth_context_; 430 struct census_context* census_context_; 431 std::multimap<grpc::string, grpc::string> send_initial_metadata_; 432 mutable internal::MetadataMap recv_initial_metadata_; 433 mutable internal::MetadataMap trailing_metadata_; 434 435 grpc_call* propagate_from_call_; 436 PropagationOptions propagation_options_; 437 438 grpc_compression_algorithm compression_algorithm_; 439 bool initial_metadata_corked_; 440 441 grpc::string debug_error_string_; 442 }; 443 444 } // namespace grpc 445 446 #endif // GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H 447