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