CCF
Loading...
Searching...
No Matches
grpc_status.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "ccf/http_consts.h"
7
8#include <string>
9
10#define GRPC_STATUS_MAP(XX) \
11 XX(0, OK, "Ok") \
12 XX(1, CANCELLED, "Cancelled") \
13 XX(2, UNKNOWN, "Unknown") \
14 XX(3, INVALID_ARGUMENT, "Invalid Argument") \
15 XX(4, DEADLINE_EXCEEDED, "Deadline Exceeded") \
16 XX(5, NOT_FOUND, "Not Found") \
17 XX(6, ALREADY_EXISTS, "Already Exists") \
18 XX(7, PERMISSION_DENIED, "Permission Denied") \
19 XX(8, RESOURCE_EXHAUSTED, "Resource Exhausted") \
20 XX(9, FAILED_PRECONDITION, "Failed Precondition") \
21 XX(10, ABORTED, "Aborted") \
22 XX(11, OUT_OF_RANGE, "Out Of Range") \
23 XX(12, UNIMPLEMENTED, "Unimplemented") \
24 XX(13, INTERNAL, "Internal") \
25 XX(14, UNAVAILABLE, "Unavailable") \
26 XX(15, DATA_LOSS, "Data Loss") \
27 XX(16, UNAUTHENTICATED, "Unauthenticated")
28
30{
31#define XX(num, name, string) GRPC_STATUS_##name = num,
33#undef XX
34};
35
36static inline const char* grpc_status_str(enum grpc_status s)
37{
38 switch (s)
39 {
40#define XX(num, name, string) \
41 case GRPC_STATUS_##name: \
42 return string;
44#undef XX
45 default:
46 return "<unknown>";
47 }
48}
49
50// CCF is primarily an HTTP framework. However, gRPC clients should be returned
51// an appropriate gRPC status code when an error is returned at the framework
52// level (e.g. authentication error) so we use the following function to
53// automatically convert HTTP errors to gRPC statuses.
54// Inspired by
55// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
56static grpc_status http_status_to_grpc(http_status s)
57{
58 // Note: GRPC_STATUS_CANCELLED, GRPC_STATUS_ABORTED and GRPC_STATUS_DATA_LOSS
59 // are currently never returned
60 switch (s)
61 {
62 case HTTP_STATUS_UNAUTHORIZED: // 401
63 return GRPC_STATUS_UNAUTHENTICATED;
64 case HTTP_STATUS_FORBIDDEN: // 404
65 return GRPC_STATUS_PERMISSION_DENIED;
66 case HTTP_STATUS_NOT_FOUND: // 404
67 return GRPC_STATUS_NOT_FOUND;
68 case HTTP_STATUS_CONFLICT: // 409
69 return GRPC_STATUS_ALREADY_EXISTS;
70 case HTTP_STATUS_PRECONDITION_FAILED: // 412
71 return GRPC_STATUS_FAILED_PRECONDITION;
72 case HTTP_STATUS_RANGE_NOT_SATISFIABLE: // 416
73 return GRPC_STATUS_OUT_OF_RANGE;
74 case HTTP_STATUS_TOO_MANY_REQUESTS: // 429
75 return GRPC_STATUS_RESOURCE_EXHAUSTED;
76 case HTTP_STATUS_NOT_IMPLEMENTED: // 501
77 return GRPC_STATUS_UNIMPLEMENTED;
78 case HTTP_STATUS_SERVICE_UNAVAILABLE: // 503
79 return GRPC_STATUS_UNAVAILABLE;
80 case HTTP_STATUS_GATEWAY_TIMEOUT: // 504
81 return GRPC_STATUS_DEADLINE_EXCEEDED;
82 default:
83 {
84 // For non-specific codes, we approximate to the closest generic code
85 if (s >= 200 && s < 300) // 2xx
86 return GRPC_STATUS_OK;
87 else if (s >= 400 && s < 500) // 4xx
88 return GRPC_STATUS_INVALID_ARGUMENT;
89 else if (s >= 500) // 5xx
90 return GRPC_STATUS_INTERNAL;
91 else
92 return GRPC_STATUS_UNKNOWN;
93 }
94 }
95}
96
97namespace ccf::grpc
98{
99 static const http::HeaderMap default_response_headers = {
100 {ccf::http::headers::CONTENT_TYPE, http::headervalues::contenttype::GRPC}};
101
102 static constexpr auto TRAILER_STATUS = "grpc-status";
103 static constexpr auto TRAILER_MESSAGE = "grpc-message";
104
105 static http::HeaderKeyValue make_status_trailer(int32_t code)
106 {
107 return {TRAILER_STATUS, std::to_string(code)};
108 }
109
110 static http::HeaderKeyValue make_message_trailer(const std::string& msg)
111 {
112 return {TRAILER_MESSAGE, msg};
113 }
114}
#define XX(num, name, string)
Definition grpc_status.h:31
#define GRPC_STATUS_MAP(XX)
Definition grpc_status.h:10
grpc_status
Definition grpc_status.h:30
llhttp_status http_status
Definition http_status.h:7
Definition grpc_status.h:98
std::map< std::string, std::string, std::less<> > HeaderMap
Definition http_header_map.h:10
HeaderMap::value_type HeaderKeyValue
Definition http_header_map.h:11