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_CLIENT_CONTEXT_H 35 #define GRPCPP_CLIENT_CONTEXT_H 36 37 #include <map> 38 #include <memory> 39 #include <string> 40 41 #include <grpc/impl/compression_types.h> 42 #include <grpc/impl/propagation_bits.h> 43 #include <grpc/support/log.h> 44 #include <grpcpp/impl/create_auth_context.h> 45 #include <grpcpp/impl/metadata_map.h> 46 #include <grpcpp/impl/rpc_method.h> 47 #include <grpcpp/impl/sync.h> 48 #include <grpcpp/security/auth_context.h> 49 #include <grpcpp/support/client_interceptor.h> 50 #include <grpcpp/support/config.h> 51 #include <grpcpp/support/slice.h> 52 #include <grpcpp/support/status.h> 53 #include <grpcpp/support/string_ref.h> 54 #include <grpcpp/support/time.h> 55 56 struct census_context; 57 struct grpc_call; 58 59 namespace grpc { 60 class ServerContext; 61 class ServerContextBase; 62 class CallbackServerContext; 63 64 namespace internal { 65 template <class InputMessage, class OutputMessage> 66 class CallbackUnaryCallImpl; 67 template <class Request, class Response> 68 class ClientCallbackReaderWriterImpl; 69 template <class Response> 70 class ClientCallbackReaderImpl; 71 template <class Request> 72 class ClientCallbackWriterImpl; 73 class ClientCallbackUnaryImpl; 74 class ClientContextAccessor; 75 class ClientAsyncResponseReaderHelper; 76 } // namespace internal 77 78 template <class R> 79 class ClientReader; 80 template <class W> 81 class ClientWriter; 82 template <class W, class R> 83 class ClientReaderWriter; 84 template <class R> 85 class ClientAsyncReader; 86 template <class W> 87 class ClientAsyncWriter; 88 template <class W, class R> 89 class ClientAsyncReaderWriter; 90 template <class R> 91 class ClientAsyncResponseReader; 92 93 namespace testing { 94 class InteropClientContextInspector; 95 class ClientContextTestPeer; 96 } // namespace testing 97 98 namespace internal { 99 class RpcMethod; 100 template <class InputMessage, class OutputMessage> 101 class BlockingUnaryCallImpl; 102 class CallOpClientRecvStatus; 103 class CallOpRecvInitialMetadata; 104 class ServerContextImpl; 105 template <class InputMessage, class OutputMessage> 106 class CallbackUnaryCallImpl; 107 template <class Request, class Response> 108 class ClientCallbackReaderWriterImpl; 109 template <class Response> 110 class ClientCallbackReaderImpl; 111 template <class Request> 112 class ClientCallbackWriterImpl; 113 class ClientCallbackUnaryImpl; 114 class ClientContextAccessor; 115 } // namespace internal 116 117 class CallCredentials; 118 class Channel; 119 class ChannelInterface; 120 class CompletionQueue; 121 122 /// Options for \a ClientContext::FromServerContext specifying which traits from 123 /// the \a ServerContext to propagate (copy) from it into a new \a 124 /// ClientContext. 125 /// 126 /// \see ClientContext::FromServerContext 127 class PropagationOptions { 128 public: PropagationOptions()129 PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} 130 enable_deadline_propagation()131 PropagationOptions& enable_deadline_propagation() { 132 propagate_ |= GRPC_PROPAGATE_DEADLINE; 133 return *this; 134 } 135 disable_deadline_propagation()136 PropagationOptions& disable_deadline_propagation() { 137 propagate_ &= ~GRPC_PROPAGATE_DEADLINE; 138 return *this; 139 } 140 enable_census_stats_propagation()141 PropagationOptions& enable_census_stats_propagation() { 142 propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; 143 return *this; 144 } 145 disable_census_stats_propagation()146 PropagationOptions& disable_census_stats_propagation() { 147 propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; 148 return *this; 149 } 150 enable_census_tracing_propagation()151 PropagationOptions& enable_census_tracing_propagation() { 152 propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; 153 return *this; 154 } 155 disable_census_tracing_propagation()156 PropagationOptions& disable_census_tracing_propagation() { 157 propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; 158 return *this; 159 } 160 enable_cancellation_propagation()161 PropagationOptions& enable_cancellation_propagation() { 162 propagate_ |= GRPC_PROPAGATE_CANCELLATION; 163 return *this; 164 } 165 disable_cancellation_propagation()166 PropagationOptions& disable_cancellation_propagation() { 167 propagate_ &= ~GRPC_PROPAGATE_CANCELLATION; 168 return *this; 169 } 170 c_bitmask()171 uint32_t c_bitmask() const { return propagate_; } 172 173 private: 174 uint32_t propagate_; 175 }; 176 177 /// A ClientContext allows the person implementing a service client to: 178 /// 179 /// - Add custom metadata key-value pairs that will propagated to the server 180 /// side. 181 /// - Control call settings such as compression and authentication. 182 /// - Initial and trailing metadata coming from the server. 183 /// - Get performance metrics (ie, census). 184 /// 185 /// Context settings are only relevant to the call they are invoked with, that 186 /// is to say, they aren't sticky. Some of these settings, such as the 187 /// compression options, can be made persistent at channel construction time 188 /// (see \a grpc::CreateCustomChannel). 189 /// 190 /// \warning ClientContext instances should \em not be reused across rpcs. 191 /// \warning The ClientContext instance used for creating an rpc must remain 192 /// alive and valid for the lifetime of the rpc. 193 class ClientContext { 194 public: 195 ClientContext(); 196 ~ClientContext(); 197 198 /// Create a new \a ClientContext as a child of an incoming server call, 199 /// according to \a options (\see PropagationOptions). 200 /// 201 /// \param server_context The source server context to use as the basis for 202 /// constructing the client context. 203 /// \param options The options controlling what to copy from the \a 204 /// server_context. 205 /// 206 /// \return A newly constructed \a ClientContext instance based on \a 207 /// server_context, with traits propagated (copied) according to \a options. 208 static std::unique_ptr<ClientContext> FromServerContext( 209 const grpc::ServerContextBase& server_context, 210 PropagationOptions options = PropagationOptions()); 211 static std::unique_ptr<ClientContext> FromCallbackServerContext( 212 const grpc::CallbackServerContext& server_context, 213 PropagationOptions options = PropagationOptions()); 214 215 /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with 216 /// a client call. These are made available at the server side by the \a 217 /// grpc::ServerContext::client_metadata() method. 218 /// 219 /// \warning This method should only be called before invoking the rpc. 220 /// 221 /// \param meta_key The metadata key. If \a meta_value is binary data, it must 222 /// end in "-bin". 223 /// \param meta_value The metadata value. If its value is binary, the key name 224 /// must end in "-bin". 225 /// 226 /// Metadata must conform to the following format: 227 /// 228 ///\verbatim 229 /// Custom-Metadata -> Binary-Header / ASCII-Header 230 /// Binary-Header -> {Header-Name "-bin" } {binary value} 231 /// ASCII-Header -> Header-Name ASCII-Value 232 /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . 233 /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII 234 /// Custom-Metadata -> Binary-Header / ASCII-Header 235 ///\endverbatim 236 /// 237 void AddMetadata(const std::string& meta_key, const std::string& meta_value); 238 239 /// Return a collection of initial metadata key-value pairs. Note that keys 240 /// may happen more than once (ie, a \a std::multimap is returned). 241 /// 242 /// \warning This method should only be called after initial metadata has been 243 /// received. For streaming calls, see \a 244 /// ClientReaderInterface::WaitForInitialMetadata(). 245 /// 246 /// \return A multimap of initial metadata key-value pairs from the server. 247 const std::multimap<grpc::string_ref, grpc::string_ref>& GetServerInitialMetadata()248 GetServerInitialMetadata() const { 249 GPR_ASSERT(initial_metadata_received_); 250 return *recv_initial_metadata_.map(); 251 } 252 253 /// Return a collection of trailing metadata key-value pairs. Note that keys 254 /// may happen more than once (ie, a \a std::multimap is returned). 255 /// 256 /// \warning This method is only callable once the stream has finished. 257 /// 258 /// \return A multimap of metadata trailing key-value pairs from the server. 259 const std::multimap<grpc::string_ref, grpc::string_ref>& GetServerTrailingMetadata()260 GetServerTrailingMetadata() const { 261 // TODO(yangg) check finished 262 return *trailing_metadata_.map(); 263 } 264 265 /// Set the deadline for the client call. 266 /// 267 /// \warning This method should only be called before invoking the rpc. 268 /// 269 /// \param deadline the deadline for the client call. Units are determined by 270 /// the type used. The deadline is an absolute (not relative) time. 271 template <typename T> set_deadline(const T & deadline)272 void set_deadline(const T& deadline) { 273 grpc::TimePoint<T> deadline_tp(deadline); 274 deadline_ = deadline_tp.raw_time(); 275 } 276 277 /// Trigger wait-for-ready or not on this request. 278 /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. 279 /// If set, if an RPC is made when a channel's connectivity state is 280 /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", 281 /// and the channel will wait until the channel is READY before making the 282 /// call. set_wait_for_ready(bool wait_for_ready)283 void set_wait_for_ready(bool wait_for_ready) { 284 wait_for_ready_ = wait_for_ready; 285 wait_for_ready_explicitly_set_ = true; 286 } 287 288 /// DEPRECATED: Use set_wait_for_ready() instead. set_fail_fast(bool fail_fast)289 void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); } 290 291 /// Return the deadline for the client call. deadline()292 std::chrono::system_clock::time_point deadline() const { 293 return grpc::Timespec2Timepoint(deadline_); 294 } 295 296 /// Return a \a gpr_timespec representation of the client call's deadline. raw_deadline()297 gpr_timespec raw_deadline() const { return deadline_; } 298 299 /// Set the per call authority header (see 300 /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). set_authority(const std::string & authority)301 void set_authority(const std::string& authority) { authority_ = authority; } 302 303 /// Return the authentication context for the associated client call. 304 /// It is only valid to call this during the lifetime of the client call. 305 /// 306 /// \see grpc::AuthContext. auth_context()307 std::shared_ptr<const grpc::AuthContext> auth_context() const { 308 if (auth_context_ == nullptr) { 309 auth_context_ = grpc::CreateAuthContext(call_); 310 } 311 return auth_context_; 312 } 313 314 /// Set credentials for the client call. 315 /// 316 /// A credentials object encapsulates all the state needed by a client to 317 /// authenticate with a server and make various assertions, e.g., about the 318 /// client’s identity, role, or whether it is authorized to make a particular 319 /// call. 320 /// 321 /// It is legal to call this only before initial metadata is sent. 322 /// 323 /// \see https://grpc.io/docs/guides/auth.html 324 void set_credentials(const std::shared_ptr<grpc::CallCredentials>& creds); 325 326 /// EXPERIMENTAL debugging API 327 /// 328 /// Returns the credentials for the client call. This should be used only in 329 /// tests and for diagnostic purposes, and should not be used by application 330 /// logic. credentials()331 std::shared_ptr<grpc::CallCredentials> credentials() { return creds_; } 332 333 /// Return the compression algorithm the client call will request be used. 334 /// Note that the gRPC runtime may decide to ignore this request, for example, 335 /// due to resource constraints. compression_algorithm()336 grpc_compression_algorithm compression_algorithm() const { 337 return compression_algorithm_; 338 } 339 340 /// Set \a algorithm to be the compression algorithm used for the client call. 341 /// 342 /// \param algorithm The compression algorithm used for the client call. 343 void set_compression_algorithm(grpc_compression_algorithm algorithm); 344 345 /// Flag whether the initial metadata should be \a corked 346 /// 347 /// If \a corked is true, then the initial metadata will be coalesced with the 348 /// write of first message in the stream. As a result, any tag set for the 349 /// initial metadata operation (starting a client-streaming or bidi-streaming 350 /// RPC) will not actually be sent to the completion queue or delivered 351 /// via Next. 352 /// 353 /// \param corked The flag indicating whether the initial metadata is to be 354 /// corked or not. set_initial_metadata_corked(bool corked)355 void set_initial_metadata_corked(bool corked) { 356 initial_metadata_corked_ = corked; 357 } 358 359 /// Return the peer uri in a string. 360 /// It is only valid to call this during the lifetime of the client call. 361 /// 362 /// \warning This value is never authenticated or subject to any security 363 /// related code. It must not be used for any authentication related 364 /// functionality. Instead, use auth_context. 365 /// 366 /// \return The call's peer URI. 367 std::string peer() const; 368 369 /// Sets the census context. 370 /// It is only valid to call this before the client call is created. A common 371 /// place of setting census context is from within the DefaultConstructor 372 /// method of GlobalCallbacks. set_census_context(struct census_context * ccp)373 void set_census_context(struct census_context* ccp) { census_context_ = ccp; } 374 375 /// Returns the census context that has been set, or nullptr if not set. census_context()376 struct census_context* census_context() const { return census_context_; } 377 378 /// Send a best-effort out-of-band cancel on the call associated with 379 /// this client context. The call could be in any stage; e.g., if it is 380 /// already finished, it may still return success. 381 /// 382 /// There is no guarantee the call will be cancelled. 383 /// 384 /// Note that TryCancel() does not change any of the tags that are pending 385 /// on the completion queue. All pending tags will still be delivered 386 /// (though their ok result may reflect the effect of cancellation). 387 /// 388 /// This method is thread-safe, and can be called multiple times from any 389 /// thread. 390 void TryCancel(); 391 392 /// Global Callbacks 393 /// 394 /// Can be set exactly once per application to install hooks whenever 395 /// a client context is constructed and destructed. 396 class GlobalCallbacks { 397 public: ~GlobalCallbacks()398 virtual ~GlobalCallbacks() {} 399 virtual void DefaultConstructor(ClientContext* context) = 0; 400 virtual void Destructor(ClientContext* context) = 0; 401 }; 402 static void SetGlobalCallbacks(GlobalCallbacks* callbacks); 403 404 /// Should be used for framework-level extensions only. 405 /// Applications never need to call this method. c_call()406 grpc_call* c_call() { return call_; } 407 408 /// EXPERIMENTAL debugging API 409 /// 410 /// if status is not ok() for an RPC, this will return a detailed string 411 /// of the gRPC Core error that led to the failure. It should not be relied 412 /// upon for anything other than gaining more debug data in failure cases. debug_error_string()413 std::string debug_error_string() const { return debug_error_string_; } 414 415 private: 416 // Disallow copy and assign. 417 ClientContext(const ClientContext&); 418 ClientContext& operator=(const ClientContext&); 419 420 friend class grpc::testing::InteropClientContextInspector; 421 friend class grpc::testing::ClientContextTestPeer; 422 friend class grpc::internal::CallOpClientRecvStatus; 423 friend class grpc::internal::CallOpRecvInitialMetadata; 424 friend class grpc::Channel; 425 template <class R> 426 friend class grpc::ClientReader; 427 template <class W> 428 friend class grpc::ClientWriter; 429 template <class W, class R> 430 friend class grpc::ClientReaderWriter; 431 template <class R> 432 friend class grpc::ClientAsyncReader; 433 template <class W> 434 friend class grpc::ClientAsyncWriter; 435 template <class W, class R> 436 friend class grpc::ClientAsyncReaderWriter; 437 template <class R> 438 friend class grpc::ClientAsyncResponseReader; 439 friend class grpc::internal::ClientAsyncResponseReaderHelper; 440 template <class InputMessage, class OutputMessage> 441 friend class grpc::internal::BlockingUnaryCallImpl; 442 template <class InputMessage, class OutputMessage> 443 friend class grpc::internal::CallbackUnaryCallImpl; 444 template <class Request, class Response> 445 friend class grpc::internal::ClientCallbackReaderWriterImpl; 446 template <class Response> 447 friend class grpc::internal::ClientCallbackReaderImpl; 448 template <class Request> 449 friend class grpc::internal::ClientCallbackWriterImpl; 450 friend class grpc::internal::ClientCallbackUnaryImpl; 451 friend class grpc::internal::ClientContextAccessor; 452 453 // Used by friend class CallOpClientRecvStatus set_debug_error_string(const std::string & debug_error_string)454 void set_debug_error_string(const std::string& debug_error_string) { 455 debug_error_string_ = debug_error_string; 456 } 457 call()458 grpc_call* call() const { return call_; } 459 void set_call(grpc_call* call, const std::shared_ptr<grpc::Channel>& channel); 460 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)461 grpc::experimental::ClientRpcInfo* set_client_rpc_info( 462 const char* method, const char* suffix_for_stats, 463 grpc::internal::RpcMethod::RpcType type, grpc::ChannelInterface* channel, 464 const std::vector<std::unique_ptr< 465 grpc::experimental::ClientInterceptorFactoryInterface>>& creators, 466 size_t interceptor_pos) { 467 rpc_info_ = grpc::experimental::ClientRpcInfo(this, type, method, 468 suffix_for_stats, channel); 469 rpc_info_.RegisterInterceptors(creators, interceptor_pos); 470 return &rpc_info_; 471 } 472 initial_metadata_flags()473 uint32_t initial_metadata_flags() const { 474 return (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) | 475 (wait_for_ready_explicitly_set_ 476 ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET 477 : 0); 478 } 479 authority()480 std::string authority() { return authority_; } 481 482 void SendCancelToInterceptors(); 483 484 static std::unique_ptr<ClientContext> FromInternalServerContext( 485 const grpc::ServerContextBase& server_context, 486 PropagationOptions options); 487 488 bool initial_metadata_received_; 489 bool wait_for_ready_; 490 bool wait_for_ready_explicitly_set_; 491 std::shared_ptr<grpc::Channel> channel_; 492 grpc::internal::Mutex mu_; 493 grpc_call* call_; 494 bool call_canceled_; 495 gpr_timespec deadline_; 496 grpc::string authority_; 497 std::shared_ptr<grpc::CallCredentials> creds_; 498 mutable std::shared_ptr<const grpc::AuthContext> auth_context_; 499 struct census_context* census_context_; 500 std::multimap<std::string, std::string> send_initial_metadata_; 501 mutable grpc::internal::MetadataMap recv_initial_metadata_; 502 mutable grpc::internal::MetadataMap trailing_metadata_; 503 504 grpc_call* propagate_from_call_; 505 PropagationOptions propagation_options_; 506 507 grpc_compression_algorithm compression_algorithm_; 508 bool initial_metadata_corked_; 509 510 std::string debug_error_string_; 511 512 grpc::experimental::ClientRpcInfo rpc_info_; 513 }; 514 515 } // namespace grpc 516 517 #endif // GRPCPP_CLIENT_CONTEXT_H 518