1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
|
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
#define GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
#include <map>
#include <memory>
#include <vector>
#include <grpc/impl/codegen/compression_types.h>
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/create_auth_context.h>
#include <grpcpp/impl/codegen/metadata_map.h>
#include <grpcpp/impl/codegen/security/auth_context.h>
#include <grpcpp/impl/codegen/string_ref.h>
#include <grpcpp/impl/codegen/time.h>
struct grpc_metadata;
struct grpc_call;
struct census_context;
namespace grpc {
class ClientContext;
template <class W, class R>
class ServerAsyncReader;
template <class W>
class ServerAsyncWriter;
template <class W>
class ServerAsyncResponseWriter;
template <class W, class R>
class ServerAsyncReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
class Call;
} // namespace internal
class CompletionQueue;
class Server;
class ServerInterface;
namespace testing {
class InteropServerContextInspector;
class ServerContextTestSpouse;
} // namespace testing
/// A ServerContext allows the person implementing a service handler to:
///
/// - Add custom initial and trailing metadata key-value pairs that will
/// propagated to the client side.
/// - Control call settings such as compression and authentication.
/// - Access metadata coming from the client.
/// - Get performance metrics (ie, census).
///
/// Context settings are only relevant to the call handler they are supplied to,
/// that is to say, they aren't sticky across multiple calls. Some of these
/// settings, such as the compression options, can be made persistent at server
/// construction time by specifying the appropriate \a ChannelArguments
/// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument.
///
/// \warning ServerContext instances should \em not be reused across rpcs.
class ServerContext {
public:
ServerContext(); // for async calls
~ServerContext();
/// Return the deadline for the server call.
std::chrono::system_clock::time_point deadline() const {
return Timespec2Timepoint(deadline_);
}
/// Return a \a gpr_timespec representation of the server call's deadline.
gpr_timespec raw_deadline() const { return deadline_; }
/// Add the (\a meta_key, \a meta_value) pair to the initial metadata
/// associated with a server call. These are made available at the client side
/// by the \a grpc::ClientContext::GetServerInitialMetadata() method.
///
/// \warning This method should only be called before sending initial metadata
/// to the client (which can happen explicitly, or implicitly when sending a
/// a response message or status to the client).
///
/// \param meta_key The metadata key. If \a meta_value is binary data, it must
/// end in "-bin".
/// \param meta_value The metadata value. If its value is binary, the key name
/// must end in "-bin".
void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
/// Add the (\a meta_key, \a meta_value) pair to the initial metadata
/// associated with a server call. These are made available at the client
/// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method.
///
/// \warning This method should only be called before sending trailing
/// metadata to the client (which happens when the call is finished and a
/// status is sent to the client).
///
/// \param meta_key The metadata key. If \a meta_value is binary data,
/// it must end in "-bin".
/// \param meta_value The metadata value. If its value is binary, the key name
/// must end in "-bin".
void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
/// IsCancelled is always safe to call when using sync API.
/// When using async API, it is only safe to call IsCancelled after
/// the AsyncNotifyWhenDone tag has been delivered.
bool IsCancelled() const;
/// Cancel the Call from the server. This is a best-effort API and
/// depending on when it is called, the RPC may still appear successful to
/// the client.
/// For example, if TryCancel() is called on a separate thread, it might race
/// with the server handler which might return success to the client before
/// TryCancel() was even started by the thread.
///
/// It is the caller's responsibility to prevent such races and ensure that if
/// TryCancel() is called, the serverhandler must return Status::CANCELLED.
/// The only exception is that if the serverhandler is already returning an
/// error status code, it is ok to not return Status::CANCELLED even if
/// TryCancel() was called.
///
/// Note that TryCancel() does not change any of the tags that are pending
/// on the completion queue. All pending tags will still be delivered
/// (though their ok result may reflect the effect of cancellation).
void TryCancel() const;
/// Return a collection of initial metadata key-value pairs sent from the
/// client. Note that keys may happen more than
/// once (ie, a \a std::multimap is returned).
///
/// It is safe to use this method after initial metadata has been received,
/// Calls always begin with the client sending initial metadata, so this is
/// safe to access as soon as the call has begun on the server side.
///
/// \return A multimap of initial metadata key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata()
const {
return *client_metadata_.map();
}
/// Return the compression algorithm to be used by the server call.
grpc_compression_level compression_level() const {
return compression_level_;
}
/// Set \a algorithm to be the compression algorithm used for the server call.
///
/// \param algorithm The compression algorithm used for the server call.
void set_compression_level(grpc_compression_level level) {
compression_level_set_ = true;
compression_level_ = level;
}
/// Return a bool indicating whether the compression level for this call
/// has been set (either implicitly or through a previous call to
/// \a set_compression_level.
bool compression_level_set() const { return compression_level_set_; }
/// Return the compression algorithm the server call will request be used.
/// Note that the gRPC runtime may decide to ignore this request, for example,
/// due to resource constraints, or if the server is aware the client doesn't
/// support the requested algorithm.
grpc_compression_algorithm compression_algorithm() const {
return compression_algorithm_;
}
/// Set \a algorithm to be the compression algorithm used for the server call.
///
/// \param algorithm The compression algorithm used for the server call.
void set_compression_algorithm(grpc_compression_algorithm algorithm);
/// Set the serialized load reporting costs in \a cost_data for the call.
void SetLoadReportingCosts(const std::vector<grpc::string>& cost_data);
/// Return the authentication context for this server call.
///
/// \see grpc::AuthContext.
std::shared_ptr<const AuthContext> auth_context() const {
if (auth_context_.get() == nullptr) {
auth_context_ = CreateAuthContext(call_);
}
return auth_context_;
}
/// Return the peer uri in a string.
/// WARNING: this value is never authenticated or subject to any security
/// related code. It must not be used for any authentication related
/// functionality. Instead, use auth_context.
grpc::string peer() const;
/// Get the census context associated with this server call.
const struct census_context* census_context() const;
/// Async only. Has to be called before the rpc starts.
/// Returns the tag in completion queue when the rpc finishes.
/// IsCancelled() can then be called to check whether the rpc was cancelled.
void AsyncNotifyWhenDone(void* tag) {
has_notify_when_done_tag_ = true;
async_notify_when_done_tag_ = tag;
}
/// Should be used for framework-level extensions only.
/// Applications never need to call this method.
grpc_call* c_call() { return call_; }
private:
friend class ::grpc::testing::InteropServerContextInspector;
friend class ::grpc::testing::ServerContextTestSpouse;
friend class ::grpc::ServerInterface;
friend class ::grpc::Server;
template <class W, class R>
friend class ::grpc::ServerAsyncReader;
template <class W>
friend class ::grpc::ServerAsyncWriter;
template <class W>
friend class ::grpc::ServerAsyncResponseWriter;
template <class W, class R>
friend class ::grpc::ServerAsyncReaderWriter;
template <class R>
friend class ::grpc::ServerReader;
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class ::grpc::internal::TemplatedBidiStreamingHandler;
friend class ::grpc::internal::UnknownMethodHandler;
friend class ::grpc::ClientContext;
/// Prevent copying.
ServerContext(const ServerContext&);
ServerContext& operator=(const ServerContext&);
class CompletionOp;
void BeginCompletionOp(internal::Call* call);
/// Return the tag queued by BeginCompletionOp()
internal::CompletionQueueTag* GetCompletionOpTag();
ServerContext(gpr_timespec deadline, grpc_metadata_array* arr);
void set_call(grpc_call* call) { call_ = call; }
uint32_t initial_metadata_flags() const { return 0; }
CompletionOp* completion_op_;
bool has_notify_when_done_tag_;
void* async_notify_when_done_tag_;
gpr_timespec deadline_;
grpc_call* call_;
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
internal::MetadataMap client_metadata_;
std::multimap<grpc::string, grpc::string> initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_;
bool compression_level_set_;
grpc_compression_level compression_level_;
grpc_compression_algorithm compression_algorithm_;
internal::CallOpSet<internal::CallOpSendInitialMetadata,
internal::CallOpSendMessage>
pending_ops_;
bool has_pending_ops_;
};
} // namespace grpc
#endif // GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
|