client_context.h 18 KB

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