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