• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2017 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 #include <grpc/support/port_platform.h>
20 
21 #include "src/core/lib/channel/status_util.h"
22 
23 #include <string.h>
24 
25 #include <vector>
26 
27 #include "absl/strings/str_cat.h"
28 #include "absl/strings/str_join.h"
29 
30 #include "src/core/lib/gpr/useful.h"
31 
32 struct status_string_entry {
33   const char* str;
34   grpc_status_code status;
35 };
36 static const status_string_entry g_status_string_entries[] = {
37     {"OK", GRPC_STATUS_OK},
38     {"CANCELLED", GRPC_STATUS_CANCELLED},
39     {"UNKNOWN", GRPC_STATUS_UNKNOWN},
40     {"INVALID_ARGUMENT", GRPC_STATUS_INVALID_ARGUMENT},
41     {"DEADLINE_EXCEEDED", GRPC_STATUS_DEADLINE_EXCEEDED},
42     {"NOT_FOUND", GRPC_STATUS_NOT_FOUND},
43     {"ALREADY_EXISTS", GRPC_STATUS_ALREADY_EXISTS},
44     {"PERMISSION_DENIED", GRPC_STATUS_PERMISSION_DENIED},
45     {"UNAUTHENTICATED", GRPC_STATUS_UNAUTHENTICATED},
46     {"RESOURCE_EXHAUSTED", GRPC_STATUS_RESOURCE_EXHAUSTED},
47     {"FAILED_PRECONDITION", GRPC_STATUS_FAILED_PRECONDITION},
48     {"ABORTED", GRPC_STATUS_ABORTED},
49     {"OUT_OF_RANGE", GRPC_STATUS_OUT_OF_RANGE},
50     {"UNIMPLEMENTED", GRPC_STATUS_UNIMPLEMENTED},
51     {"INTERNAL", GRPC_STATUS_INTERNAL},
52     {"UNAVAILABLE", GRPC_STATUS_UNAVAILABLE},
53     {"DATA_LOSS", GRPC_STATUS_DATA_LOSS},
54 };
55 
grpc_status_code_from_string(const char * status_str,grpc_status_code * status)56 bool grpc_status_code_from_string(const char* status_str,
57                                   grpc_status_code* status) {
58   for (size_t i = 0; i < GPR_ARRAY_SIZE(g_status_string_entries); ++i) {
59     if (strcmp(status_str, g_status_string_entries[i].str) == 0) {
60       *status = g_status_string_entries[i].status;
61       return true;
62     }
63   }
64   return false;
65 }
66 
grpc_status_code_to_string(grpc_status_code status)67 const char* grpc_status_code_to_string(grpc_status_code status) {
68   switch (status) {
69     case GRPC_STATUS_OK:
70       return "OK";
71     case GRPC_STATUS_CANCELLED:
72       return "CANCELLED";
73     case GRPC_STATUS_UNKNOWN:
74       return "UNKNOWN";
75     case GRPC_STATUS_INVALID_ARGUMENT:
76       return "INVALID_ARGUMENT";
77     case GRPC_STATUS_DEADLINE_EXCEEDED:
78       return "DEADLINE_EXCEEDED";
79     case GRPC_STATUS_NOT_FOUND:
80       return "NOT_FOUND";
81     case GRPC_STATUS_ALREADY_EXISTS:
82       return "ALREADY_EXISTS";
83     case GRPC_STATUS_PERMISSION_DENIED:
84       return "PERMISSION_DENIED";
85     case GRPC_STATUS_RESOURCE_EXHAUSTED:
86       return "RESOURCE_EXHAUSTED";
87     case GRPC_STATUS_FAILED_PRECONDITION:
88       return "FAILED_PRECONDITION";
89     case GRPC_STATUS_ABORTED:
90       return "ABORTED";
91     case GRPC_STATUS_OUT_OF_RANGE:
92       return "OUT_OF_RANGE";
93     case GRPC_STATUS_UNIMPLEMENTED:
94       return "UNIMPLEMENTED";
95     case GRPC_STATUS_INTERNAL:
96       return "INTERNAL";
97     case GRPC_STATUS_UNAVAILABLE:
98       return "UNAVAILABLE";
99     case GRPC_STATUS_DATA_LOSS:
100       return "DATA_LOSS";
101     case GRPC_STATUS_UNAUTHENTICATED:
102       return "UNAUTHENTICATED";
103     default:
104       return "UNKNOWN";
105   }
106 }
107 
grpc_status_code_from_int(int status_int,grpc_status_code * status)108 bool grpc_status_code_from_int(int status_int, grpc_status_code* status) {
109   // The range of status code enum is [0, 16], 0 is OK, 16 is UNAUTHENTICATED.
110   if (status_int < GRPC_STATUS_OK || status_int > GRPC_STATUS_UNAUTHENTICATED) {
111     *status = GRPC_STATUS_UNKNOWN;
112     return false;
113   }
114   *status = static_cast<grpc_status_code>(status_int);
115   return true;
116 }
117 
118 namespace grpc_core {
119 
120 namespace internal {
121 
ToString() const122 std::string StatusCodeSet::ToString() const {
123   std::vector<absl::string_view> codes;
124   for (size_t i = 0; i < GPR_ARRAY_SIZE(g_status_string_entries); ++i) {
125     if (Contains(g_status_string_entries[i].status)) {
126       codes.emplace_back(g_status_string_entries[i].str);
127     }
128   }
129   return absl::StrCat("{", absl::StrJoin(codes, ","), "}");
130 }
131 
132 }  // namespace internal
133 
MaybeRewriteIllegalStatusCode(absl::Status status,absl::string_view source)134 absl::Status MaybeRewriteIllegalStatusCode(absl::Status status,
135                                            absl::string_view source) {
136   switch (status.code()) {
137     // The set of disallowed codes, as per
138     // https://github.com/grpc/proposal/blob/master/A54-restrict-control-plane-status-codes.md.
139     case absl::StatusCode::kInvalidArgument:
140     case absl::StatusCode::kNotFound:
141     case absl::StatusCode::kAlreadyExists:
142     case absl::StatusCode::kFailedPrecondition:
143     case absl::StatusCode::kAborted:
144     case absl::StatusCode::kOutOfRange:
145     case absl::StatusCode::kDataLoss: {
146       return absl::InternalError(
147           absl::StrCat("Illegal status code from ", source,
148                        "; original status: ", status.ToString()));
149     }
150     default:
151       return status;
152   }
153 }
154 
155 }  // namespace grpc_core
156