• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_H
16 #define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include "src/core/lib/transport/metadata_batch.h"
21 
22 namespace grpc_core {
23 
24 // Server metadata type
25 // TODO(ctiller): This should be a bespoke instance of MetadataMap<>
26 using ServerMetadata = grpc_metadata_batch;
27 using ServerMetadataHandle = Arena::PoolPtr<ServerMetadata>;
28 
29 // Client initial metadata type
30 // TODO(ctiller): This should be a bespoke instance of MetadataMap<>
31 using ClientMetadata = grpc_metadata_batch;
32 using ClientMetadataHandle = Arena::PoolPtr<ClientMetadata>;
33 
34 // TODO(ctiller): separate when we have different types for client/server
35 // metadata.
36 template <typename Sink>
AbslStringify(Sink & sink,const Arena::PoolPtr<grpc_metadata_batch> & md)37 void AbslStringify(Sink& sink, const Arena::PoolPtr<grpc_metadata_batch>& md) {
38   if (md == nullptr) {
39     sink.Append("nullptr");
40     return;
41   }
42   sink.Append("ServerMetadata{");
43   sink.Append(md->DebugString());
44   sink.Append("}");
45 }
46 
47 // Ok/not-ok check for trailing metadata, so that it can be used as result types
48 // for TrySeq.
IsStatusOk(const ServerMetadataHandle & m)49 inline bool IsStatusOk(const ServerMetadataHandle& m) {
50   return m->get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN) ==
51          GRPC_STATUS_OK;
52 }
53 
54 // Convert absl::Status to ServerMetadata
55 ServerMetadataHandle ServerMetadataFromStatus(const absl::Status& status);
56 // Convert absl::Status to ServerMetadata, and set GrpcCallWasCancelled() to
57 // true
58 ServerMetadataHandle CancelledServerMetadataFromStatus(
59     const absl::Status& status);
60 // Server metadata with status code set
ServerMetadataFromStatus(grpc_status_code code)61 inline ServerMetadataHandle ServerMetadataFromStatus(grpc_status_code code) {
62   auto hdl = Arena::MakePooledForOverwrite<ServerMetadata>();
63   hdl->Set(GrpcStatusMetadata(), code);
64   return hdl;
65 }
CancelledServerMetadataFromStatus(grpc_status_code code)66 inline ServerMetadataHandle CancelledServerMetadataFromStatus(
67     grpc_status_code code) {
68   auto hdl = Arena::MakePooledForOverwrite<ServerMetadata>();
69   hdl->Set(GrpcStatusMetadata(), code);
70   hdl->Set(GrpcCallWasCancelled(), true);
71   return hdl;
72 }
73 // The same, but with an error string
74 ServerMetadataHandle ServerMetadataFromStatus(grpc_status_code code,
75                                               absl::string_view message);
76 ServerMetadataHandle CancelledServerMetadataFromStatus(
77     grpc_status_code code, absl::string_view message);
78 
79 template <>
80 struct StatusCastImpl<ServerMetadataHandle, absl::Status> {
81   static ServerMetadataHandle Cast(const absl::Status& m) {
82     return ServerMetadataFromStatus(m);
83   }
84 };
85 
86 template <>
87 struct StatusCastImpl<ServerMetadataHandle, const absl::Status&> {
88   static ServerMetadataHandle Cast(const absl::Status& m) {
89     return ServerMetadataFromStatus(m);
90   }
91 };
92 
93 template <>
94 struct StatusCastImpl<ServerMetadataHandle, absl::Status&> {
95   static ServerMetadataHandle Cast(const absl::Status& m) {
96     return ServerMetadataFromStatus(m);
97   }
98 };
99 
100 // Anything that can be first cast to absl::Status can then be cast to
101 // ServerMetadataHandle.
102 template <typename T>
103 struct StatusCastImpl<
104     ServerMetadataHandle, T,
105     absl::void_t<decltype(&StatusCastImpl<absl::Status, T>::Cast)>> {
106   static ServerMetadataHandle Cast(const T& m) {
107     return ServerMetadataFromStatus(StatusCast<absl::Status>(m));
108   }
109 };
110 
111 }  // namespace grpc_core
112 
113 #endif  // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_H
114