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