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