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
56struct census_context;
57struct grpc_call;
58
59namespace grpc {
60
61class ChannelInterface;
62
63namespace internal {
64class RpcMethod;
65template <class InputMessage, class OutputMessage>
66class BlockingUnaryCallImpl;
67class CallOpClientRecvStatus;
68class CallOpRecvInitialMetadata;
69class ServerContextImpl;
70} // namespace internal
71
72namespace testing {
73class InteropClientContextInspector;
74} // namespace testing
75} // namespace grpc
76namespace grpc_impl {
77
78namespace internal {
79template <class InputMessage, class OutputMessage>
80class CallbackUnaryCallImpl;
81template <class Request, class Response>
82class ClientCallbackReaderWriterImpl;
83template <class Response>
84class ClientCallbackReaderImpl;
85template <class Request>
86class ClientCallbackWriterImpl;
87class ClientCallbackUnaryImpl;
88class ClientContextAccessor;
89} // namespace internal
90
91class CallCredentials;
92class Channel;
93class CompletionQueue;
94class ServerContext;
95template <class R>
96class ClientReader;
97template <class W>
98class ClientWriter;
99template <class W, class R>
100class ClientReaderWriter;
101template <class R>
102class ClientAsyncReader;
103template <class W>
104class ClientAsyncWriter;
105template <class W, class R>
106class ClientAsyncReaderWriter;
107template <class R>
108class ClientAsyncResponseReader;
109
110class ServerContextBase;
111class 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
118class PropagationOptions {
119 public:
120 PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
121
122 PropagationOptions& enable_deadline_propagation() {
123 propagate_ |= GRPC_PROPAGATE_DEADLINE;
124 return *this;
125 }
126
127 PropagationOptions& disable_deadline_propagation() {
128 propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
129 return *this;
130 }
131
132 PropagationOptions& enable_census_stats_propagation() {
133 propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
134 return *this;
135 }
136
137 PropagationOptions& disable_census_stats_propagation() {
138 propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
139 return *this;
140 }
141
142 PropagationOptions& enable_census_tracing_propagation() {
143 propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
144 return *this;
145 }
146
147 PropagationOptions& disable_census_tracing_propagation() {
148 propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
149 return *this;
150 }
151
152 PropagationOptions& enable_cancellation_propagation() {
153 propagate_ |= GRPC_PROPAGATE_CANCELLATION;
154 return *this;
155 }
156
157 PropagationOptions& disable_cancellation_propagation() {
158 propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
159 return *this;
160 }
161
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.
184class 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 grpc::string& meta_key,
224 const grpc::string& meta_value);
225
226 /// Return a collection of initial metadata key-value pairs. Note that keys
227 /// may happen more than once (ie, a \a std::multimap is returned).
228 ///
229 /// \warning This method should only be called after initial metadata has been
230 /// received. For streaming calls, see \a
231 /// ClientReaderInterface::WaitForInitialMetadata().
232 ///
233 /// \return A multimap of initial metadata key-value pairs from the server.
234 const std::multimap<grpc::string_ref, grpc::string_ref>&
235 GetServerInitialMetadata() const {
236 GPR_CODEGEN_ASSERT(initial_metadata_received_);
237 return *recv_initial_metadata_.map();
238 }
239
240 /// Return a collection of trailing 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 is only callable once the stream has finished.
244 ///
245 /// \return A multimap of metadata trailing key-value pairs from the server.
246 const std::multimap<grpc::string_ref, grpc::string_ref>&
247 GetServerTrailingMetadata() const {
248 // TODO(yangg) check finished
249 return *trailing_metadata_.map();
250 }
251
252 /// Set the deadline for the client call.
253 ///
254 /// \warning This method should only be called before invoking the rpc.
255 ///
256 /// \param deadline the deadline for the client call. Units are determined by
257 /// the type used. The deadline is an absolute (not relative) time.
258 template <typename T>
259 void set_deadline(const T& deadline) {
260 grpc::TimePoint<T> deadline_tp(deadline);
261 deadline_ = deadline_tp.raw_time();
262 }
263
264 /// EXPERIMENTAL: Indicate that this request is idempotent.
265 /// By default, RPCs are assumed to <i>not</i> be idempotent.
266 ///
267 /// If true, the gRPC library assumes that it's safe to initiate
268 /// this RPC multiple times.
269 void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
270
271 /// EXPERIMENTAL: Set this request to be cacheable.
272 /// If set, grpc is free to use the HTTP GET verb for sending the request,
273 /// with the possibility of receiving a cached response.
274 void set_cacheable(bool cacheable) { cacheable_ = cacheable; }
275
276 /// EXPERIMENTAL: Trigger wait-for-ready or not on this request.
277 /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
278 /// If set, if an RPC is made when a channel's connectivity state is
279 /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast",
280 /// and the channel will wait until the channel is READY before making the
281 /// call.
282 void set_wait_for_ready(bool wait_for_ready) {
283 wait_for_ready_ = wait_for_ready;
284 wait_for_ready_explicitly_set_ = true;
285 }
286
287 /// DEPRECATED: Use set_wait_for_ready() instead.
288 void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); }
289
290 /// Return the deadline for the client call.
291 std::chrono::system_clock::time_point deadline() const {
292 return grpc::Timespec2Timepoint(t: deadline_);
293 }
294
295 /// Return a \a gpr_timespec representation of the client call's deadline.
296 gpr_timespec raw_deadline() const { return deadline_; }
297
298 /// Set the per call authority header (see
299 /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
300 void set_authority(const grpc::string& authority) { authority_ = authority; }
301
302 /// Return the authentication context for the associated client call.
303 /// It is only valid to call this during the lifetime of the client call.
304 ///
305 /// \see grpc::AuthContext.
306 std::shared_ptr<const grpc::AuthContext> auth_context() const {
307 if (auth_context_.get() == nullptr) {
308 auth_context_ = grpc::CreateAuthContext(call: call_);
309 }
310 return auth_context_;
311 }
312
313 /// Set credentials for the client call.
314 ///
315 /// A credentials object encapsulates all the state needed by a client to
316 /// authenticate with a server and make various assertions, e.g., about the
317 /// client’s identity, role, or whether it is authorized to make a particular
318 /// call.
319 ///
320 /// It is legal to call this only before initial metadata is sent.
321 ///
322 /// \see https://grpc.io/docs/guides/auth.html
323 void set_credentials(
324 const std::shared_ptr<grpc_impl::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.
331 std::shared_ptr<grpc_impl::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.
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.
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 grpc::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.
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.
376 struct census_context* census_context() const {
377 return census_context_;
378 }
379
380 /// Send a best-effort out-of-band cancel on the call associated with
381 /// this client context. The call could be in any stage; e.g., if it is
382 /// already finished, it may still return success.
383 ///
384 /// There is no guarantee the call will be cancelled.
385 ///
386 /// Note that TryCancel() does not change any of the tags that are pending
387 /// on the completion queue. All pending tags will still be delivered
388 /// (though their ok result may reflect the effect of cancellation).
389 void TryCancel();
390
391 /// Global Callbacks
392 ///
393 /// Can be set exactly once per application to install hooks whenever
394 /// a client context is constructed and destructed.
395 class GlobalCallbacks {
396 public:
397 virtual ~GlobalCallbacks() {}
398 virtual void DefaultConstructor(ClientContext* context) = 0;
399 virtual void Destructor(ClientContext* context) = 0;
400 };
401 static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
402
403 /// Should be used for framework-level extensions only.
404 /// Applications never need to call this method.
405 grpc_call* c_call() { return call_; }
406
407 /// EXPERIMENTAL debugging API
408 ///
409 /// if status is not ok() for an RPC, this will return a detailed string
410 /// of the gRPC Core error that led to the failure. It should not be relied
411 /// upon for anything other than gaining more debug data in failure cases.
412 grpc::string debug_error_string() const { return debug_error_string_; }
413
414 private:
415 // Disallow copy and assign.
416 ClientContext(const ClientContext&);
417 ClientContext& operator=(const ClientContext&);
418
419 friend class ::grpc::testing::InteropClientContextInspector;
420 friend class ::grpc::internal::CallOpClientRecvStatus;
421 friend class ::grpc::internal::CallOpRecvInitialMetadata;
422 friend class ::grpc_impl::Channel;
423 template <class R>
424 friend class ::grpc_impl::ClientReader;
425 template <class W>
426 friend class ::grpc_impl::ClientWriter;
427 template <class W, class R>
428 friend class ::grpc_impl::ClientReaderWriter;
429 template <class R>
430 friend class ::grpc_impl::ClientAsyncReader;
431 template <class W>
432 friend class ::grpc_impl::ClientAsyncWriter;
433 template <class W, class R>
434 friend class ::grpc_impl::ClientAsyncReaderWriter;
435 template <class R>
436 friend class ::grpc_impl::ClientAsyncResponseReader;
437 template <class InputMessage, class OutputMessage>
438 friend class ::grpc::internal::BlockingUnaryCallImpl;
439 template <class InputMessage, class OutputMessage>
440 friend class ::grpc_impl::internal::CallbackUnaryCallImpl;
441 template <class Request, class Response>
442 friend class ::grpc_impl::internal::ClientCallbackReaderWriterImpl;
443 template <class Response>
444 friend class ::grpc_impl::internal::ClientCallbackReaderImpl;
445 template <class Request>
446 friend class ::grpc_impl::internal::ClientCallbackWriterImpl;
447 friend class ::grpc_impl::internal::ClientCallbackUnaryImpl;
448 friend class ::grpc_impl::internal::ClientContextAccessor;
449
450 // Used by friend class CallOpClientRecvStatus
451 void set_debug_error_string(const grpc::string& debug_error_string) {
452 debug_error_string_ = debug_error_string;
453 }
454
455 grpc_call* call() const { return call_; }
456 void set_call(grpc_call* call,
457 const std::shared_ptr<::grpc_impl::Channel>& channel);
458
459 grpc::experimental::ClientRpcInfo* set_client_rpc_info(
460 const char* method, grpc::internal::RpcMethod::RpcType type,
461 grpc::ChannelInterface* channel,
462 const std::vector<std::unique_ptr<
463 grpc::experimental::ClientInterceptorFactoryInterface>>& creators,
464 size_t interceptor_pos) {
465 rpc_info_ = grpc::experimental::ClientRpcInfo(this, type, method, channel);
466 rpc_info_.RegisterInterceptors(creators, interceptor_pos);
467 return &rpc_info_;
468 }
469
470 uint32_t initial_metadata_flags() const {
471 return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
472 (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) |
473 (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) |
474 (wait_for_ready_explicitly_set_
475 ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET
476 : 0) |
477 (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0);
478 }
479
480 grpc::string authority() { return authority_; }
481
482 void SendCancelToInterceptors();
483
484 static std::unique_ptr<ClientContext> FromInternalServerContext(
485 const grpc_impl::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 bool idempotent_;
492 bool cacheable_;
493 std::shared_ptr<::grpc_impl::Channel> channel_;
494 grpc::internal::Mutex mu_;
495 grpc_call* call_;
496 bool call_canceled_;
497 gpr_timespec deadline_;
498 grpc::string authority_;
499 std::shared_ptr<grpc_impl::CallCredentials> creds_;
500 mutable std::shared_ptr<const grpc::AuthContext> auth_context_;
501 struct census_context* census_context_;
502 std::multimap<grpc::string, grpc::string> send_initial_metadata_;
503 mutable grpc::internal::MetadataMap recv_initial_metadata_;
504 mutable grpc::internal::MetadataMap trailing_metadata_;
505
506 grpc_call* propagate_from_call_;
507 PropagationOptions propagation_options_;
508
509 grpc_compression_algorithm compression_algorithm_;
510 bool initial_metadata_corked_;
511
512 grpc::string debug_error_string_;
513
514 grpc::experimental::ClientRpcInfo rpc_info_;
515};
516
517} // namespace grpc_impl
518
519#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_IMPL_H
520

source code of include/grpcpp/impl/codegen/client_context_impl.h