aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-12-13 16:40:38 -0800
committerGravatar Craig Tiller <ctiller@google.com>2017-01-06 14:52:01 -0800
commit732351f8267e51711abd3a390d940c8177871c97 (patch)
tree8fede2296fb7bfbe009f9f86e15aa61b7349f38f /src/core/lib
parent255edaa32e236c8e30d378517e64b507e5b765a9 (diff)
Start fixing http error --> grpc status conversion
Diffstat (limited to 'src/core/lib')
-rw-r--r--src/core/lib/iomgr/error.c116
-rw-r--r--src/core/lib/iomgr/error.h6
-rw-r--r--src/core/lib/iomgr/error_internal.h53
-rw-r--r--src/core/lib/security/transport/server_auth_filter.c2
-rw-r--r--src/core/lib/surface/call.c1
-rw-r--r--src/core/lib/transport/error_utils.c90
-rw-r--r--src/core/lib/transport/error_utils.h50
-rw-r--r--src/core/lib/transport/http2_errors.h56
-rw-r--r--src/core/lib/transport/status_conversion.c115
-rw-r--r--src/core/lib/transport/status_conversion.h50
10 files changed, 450 insertions, 89 deletions
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index 227c94020f..3cf644f421 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -33,13 +33,10 @@
#include "src/core/lib/iomgr/error.h"
-#include <inttypes.h>
-#include <stdbool.h>
#include <string.h>
#include <grpc/status.h>
#include <grpc/support/alloc.h>
-#include <grpc/support/avl.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
@@ -48,6 +45,7 @@
#include <grpc/support/log_windows.h>
#endif
+#include "src/core/lib/iomgr/error_internal.h"
#include "src/core/lib/profiling/timers.h"
static void destroy_integer(void *key) {}
@@ -164,16 +162,7 @@ static const char *error_time_name(grpc_error_times key) {
GPR_UNREACHABLE_CODE(return "unknown");
}
-struct grpc_error {
- gpr_refcount refs;
- gpr_avl ints;
- gpr_avl strs;
- gpr_avl times;
- gpr_avl errs;
- uintptr_t next_err;
-};
-
-static bool is_special(grpc_error *err) {
+bool grpc_error_is_special(grpc_error *err) {
return err == GRPC_ERROR_NONE || err == GRPC_ERROR_OOM ||
err == GRPC_ERROR_CANCELLED;
}
@@ -189,14 +178,14 @@ grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
}
#else
grpc_error *grpc_error_ref(grpc_error *err) {
- if (is_special(err)) return err;
+ if (grpc_error_is_special(err)) return err;
gpr_ref(&err->refs);
return err;
}
#endif
static void error_destroy(grpc_error *err) {
- GPR_ASSERT(!is_special(err));
+ GPR_ASSERT(!grpc_error_is_special(err));
gpr_avl_unref(err->ints);
gpr_avl_unref(err->strs);
gpr_avl_unref(err->errs);
@@ -216,7 +205,7 @@ void grpc_error_unref(grpc_error *err, const char *file, int line,
}
#else
void grpc_error_unref(grpc_error *err) {
- if (is_special(err)) return;
+ if (grpc_error_is_special(err)) return;
if (gpr_unref(&err->refs)) {
error_destroy(err);
}
@@ -259,7 +248,7 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc,
static grpc_error *copy_error_and_unref(grpc_error *in) {
GPR_TIMER_BEGIN("copy_error_and_unref", 0);
grpc_error *out;
- if (is_special(in)) {
+ if (grpc_error_is_special(in)) {
if (in == GRPC_ERROR_NONE)
out = grpc_error_set_int(GRPC_ERROR_CREATE("no error"),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
@@ -297,14 +286,29 @@ grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
return new;
}
+typedef struct {
+ grpc_error *error;
+ grpc_status_code code;
+ const char *msg;
+} special_error_status_map;
+static special_error_status_map error_status_map[] = {
+ {GRPC_ERROR_NONE, GRPC_STATUS_OK, NULL},
+ {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"},
+ {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"},
+};
+
bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
GPR_TIMER_BEGIN("grpc_error_get_int", 0);
void *pp;
- if (is_special(err)) {
- if (err == GRPC_ERROR_CANCELLED && which == GRPC_ERROR_INT_GRPC_STATUS) {
- *p = GRPC_STATUS_CANCELLED;
- GPR_TIMER_END("grpc_error_get_int", 0);
- return true;
+ if (grpc_error_is_special(err)) {
+ if (which == GRPC_ERROR_INT_GRPC_STATUS) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
+ if (error_status_map[i].error == err) {
+ if (p != NULL) *p = error_status_map[i].code;
+ GPR_TIMER_END("grpc_error_get_int", 0);
+ return true;
+ }
+ }
}
GPR_TIMER_END("grpc_error_get_int", 0);
return false;
@@ -329,67 +333,17 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
}
const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
- if (is_special(err)) return NULL;
- return gpr_avl_get(err->strs, (void *)(uintptr_t)which);
-}
-
-typedef struct {
- grpc_error *error;
- grpc_status_code code;
- const char *msg;
-} special_error_status_map;
-static special_error_status_map error_status_map[] = {
- {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""},
- {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "RPC cancelled"},
- {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"},
-};
-
-static grpc_error *recursively_find_error_with_status(grpc_error *error,
- intptr_t *status) {
- // If the error itself has a status code, return it.
- if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, status)) {
- return error;
- }
- if (is_special(error)) return NULL;
- // Otherwise, search through its children.
- intptr_t key = 0;
- while (true) {
- grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++);
- if (child_error == NULL) break;
- grpc_error *result =
- recursively_find_error_with_status(child_error, status);
- if (result != NULL) return result;
- }
- return NULL;
-}
-
-void grpc_error_get_status(grpc_error *error, grpc_status_code *code,
- const char **msg) {
- // Handle special errors via the static map.
- for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); ++i) {
- if (error == error_status_map[i].error) {
- *code = error_status_map[i].code;
- *msg = error_status_map[i].msg;
- return;
+ if (grpc_error_is_special(err)) {
+ if (which == GRPC_ERROR_STR_GRPC_MESSAGE) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
+ if (error_status_map[i].error == err) {
+ return error_status_map[i].msg;
+ }
+ }
}
+ return NULL;
}
- // Populate code.
- // Start with the parent error and recurse through the tree of children
- // until we find the first one that has a status code.
- intptr_t status = GRPC_STATUS_UNKNOWN; // Default in case we don't find one.
- grpc_error *found_error = recursively_find_error_with_status(error, &status);
- *code = (grpc_status_code)status;
- // Now populate msg.
- // If we found an error with a status code above, use that; otherwise,
- // fall back to using the parent error.
- if (found_error == NULL) found_error = error;
- // If the error has a status message, use it. Otherwise, fall back to
- // the error description.
- *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE);
- if (*msg == NULL && status != GRPC_STATUS_OK) {
- *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION);
- if (*msg == NULL) *msg = "unknown error"; // Just in case.
- }
+ return gpr_avl_get(err->strs, (void *)(uintptr_t)which);
}
grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index a2ba84deed..75ca9c4bf9 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -193,12 +193,6 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
/// Caller does NOT own return value.
const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which);
-/// A utility function to get the status code and message to be returned
-/// to the application. If not set in the top-level message, looks
-/// through child errors until it finds the first one with these attributes.
-void grpc_error_get_status(grpc_error *error, grpc_status_code *code,
- const char **msg);
-
/// Add a child error: an error that is believed to have contributed to this
/// error occurring. Allows root causing high level errors from lower level
/// errors that contributed to them.
diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h
new file mode 100644
index 0000000000..5afe9edc7f
--- /dev/null
+++ b/src/core/lib/iomgr/error_internal.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_ERROR_INTERNAL_H
+#define GRPC_ERROR_INTERNAL_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include <grpc/support/avl.h>
+
+struct grpc_error {
+ gpr_refcount refs;
+ gpr_avl ints;
+ gpr_avl strs;
+ gpr_avl times;
+ gpr_avl errs;
+ uintptr_t next_err;
+};
+
+bool grpc_error_is_special(grpc_error *err);
+
+#endif
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index 6b04ad2385..36e81d6501 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -130,7 +130,6 @@ static void on_md_processing_done(
grpc_metadata_array_destroy(&calld->md);
grpc_closure_sched(&exec_ctx, calld->on_done_recv, GRPC_ERROR_NONE);
} else {
- grpc_slice message;
for (size_t i = 0; i < calld->md.count; i++) {
grpc_slice_unref_internal(&exec_ctx, calld->md.metadata[i].key);
grpc_slice_unref_internal(&exec_ctx, calld->md.metadata[i].value);
@@ -139,7 +138,6 @@ static void on_md_processing_done(
error_details = error_details != NULL
? error_details
: "Authentication metadata processing failed.";
- message = grpc_slice_from_copied_string(error_details);
calld->transport_op->send_initial_metadata = NULL;
if (calld->transport_op->send_message != NULL) {
grpc_byte_stream_destroy(&exec_ctx, calld->transport_op->send_message);
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 57603ca386..4abf981997 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -56,6 +56,7 @@
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/completion_queue.h"
+#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/transport.h"
diff --git a/src/core/lib/transport/error_utils.c b/src/core/lib/transport/error_utils.c
new file mode 100644
index 0000000000..6403cf80d8
--- /dev/null
+++ b/src/core/lib/transport/error_utils.c
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/transport/error_utils.h"
+#include "src/core/lib/iomgr/error_internal.h"
+
+static grpc_error *recursively_find_error_with_status(grpc_error *error,
+ intptr_t *status) {
+ // If the error itself has a status code, return it.
+ if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, status)) {
+ return error;
+ }
+ if (grpc_error_is_special(error)) return NULL;
+ // Otherwise, search through its children.
+ intptr_t key = 0;
+ while (true) {
+ grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++);
+ if (child_error == NULL) break;
+ grpc_error *result =
+ recursively_find_error_with_status(child_error, status);
+ if (result != NULL) return result;
+ }
+ return NULL;
+}
+
+void grpc_error_get_status(grpc_error *error, grpc_status_code *code,
+ const char **msg) {
+ // Populate code.
+ // Start with the parent error and recurse through the tree of children
+ // until we find the first one that has a status code.
+ intptr_t status = GRPC_STATUS_UNKNOWN; // Default in case we don't find one.
+ grpc_error *found_error = recursively_find_error_with_status(error, &status);
+ *code = (grpc_status_code)status;
+ // Now populate msg.
+ // If we found an error with a status code above, use that; otherwise,
+ // fall back to using the parent error.
+ if (found_error == NULL) found_error = error;
+ // If the error has a status message, use it. Otherwise, fall back to
+ // the error description.
+ *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE);
+ if (*msg == NULL && status != GRPC_STATUS_OK) {
+ *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION);
+ if (*msg == NULL) *msg = "unknown error"; // Just in case.
+ }
+}
+
+bool grpc_error_has_clear_grpc_status(grpc_error *error) {
+ if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) {
+ return true;
+ }
+ intptr_t key = 0;
+ while (true) {
+ grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++);
+ if (child_error == NULL) break;
+ if (grpc_error_has_clear_grpc_status(child_error)) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h
new file mode 100644
index 0000000000..541dba852f
--- /dev/null
+++ b/src/core/lib/transport/error_utils.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_ERROR_UTILS_H
+#define GRPC_ERROR_UTILS_H
+
+#include "src/core/lib/iomgr/error.h"
+
+/// A utility function to get the status code and message to be returned
+/// to the application. If not set in the top-level message, looks
+/// through child errors until it finds the first one with these attributes.
+void grpc_error_get_status(grpc_error *error, grpc_status_code *code,
+ const char **msg);
+/// A utility function to check whether there is a clear status code that
+/// doesn't need to be guessed in \a error. This means that \a error or some
+/// child has GRPC_ERROR_INT_GRPC_STATUS set, or that it is GRPC_ERROR_NONE or
+/// GRPC_ERROR_CANCELLED
+bool grpc_error_has_clear_grpc_status(grpc_error *error);
+
+#endif
diff --git a/src/core/lib/transport/http2_errors.h b/src/core/lib/transport/http2_errors.h
new file mode 100644
index 0000000000..deab2b7e3e
--- /dev/null
+++ b/src/core/lib/transport/http2_errors.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ERRORS_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ERRORS_H
+
+/* error codes for RST_STREAM from http2 draft 14 section 7 */
+typedef enum {
+ GRPC_CHTTP2_NO_ERROR = 0x0,
+ GRPC_CHTTP2_PROTOCOL_ERROR = 0x1,
+ GRPC_CHTTP2_INTERNAL_ERROR = 0x2,
+ GRPC_CHTTP2_FLOW_CONTROL_ERROR = 0x3,
+ GRPC_CHTTP2_SETTINGS_TIMEOUT = 0x4,
+ GRPC_CHTTP2_STREAM_CLOSED = 0x5,
+ GRPC_CHTTP2_FRAME_SIZE_ERROR = 0x6,
+ GRPC_CHTTP2_REFUSED_STREAM = 0x7,
+ GRPC_CHTTP2_CANCEL = 0x8,
+ GRPC_CHTTP2_COMPRESSION_ERROR = 0x9,
+ GRPC_CHTTP2_CONNECT_ERROR = 0xa,
+ GRPC_CHTTP2_ENHANCE_YOUR_CALM = 0xb,
+ GRPC_CHTTP2_INADEQUATE_SECURITY = 0xc,
+ /* force use of a default clause */
+ GRPC_CHTTP2__ERROR_DO_NOT_USE = -1
+} grpc_chttp2_error_code;
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ERRORS_H */
diff --git a/src/core/lib/transport/status_conversion.c b/src/core/lib/transport/status_conversion.c
new file mode 100644
index 0000000000..eb1d53c8d1
--- /dev/null
+++ b/src/core/lib/transport/status_conversion.c
@@ -0,0 +1,115 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/transport/status_conversion.h"
+
+int grpc_chttp2_grpc_status_to_http2_error(grpc_status_code status) {
+ switch (status) {
+ case GRPC_STATUS_OK:
+ return GRPC_CHTTP2_NO_ERROR;
+ case GRPC_STATUS_CANCELLED:
+ return GRPC_CHTTP2_CANCEL;
+ case GRPC_STATUS_DEADLINE_EXCEEDED:
+ return GRPC_CHTTP2_CANCEL;
+ case GRPC_STATUS_RESOURCE_EXHAUSTED:
+ return GRPC_CHTTP2_ENHANCE_YOUR_CALM;
+ case GRPC_STATUS_PERMISSION_DENIED:
+ return GRPC_CHTTP2_INADEQUATE_SECURITY;
+ case GRPC_STATUS_UNAVAILABLE:
+ return GRPC_CHTTP2_REFUSED_STREAM;
+ default:
+ return GRPC_CHTTP2_INTERNAL_ERROR;
+ }
+}
+
+grpc_status_code grpc_chttp2_http2_error_to_grpc_status(
+ grpc_chttp2_error_code error, gpr_timespec deadline) {
+ switch (error) {
+ case GRPC_CHTTP2_NO_ERROR:
+ /* should never be received */
+ return GRPC_STATUS_INTERNAL;
+ case GRPC_CHTTP2_CANCEL:
+ /* http2 cancel translates to STATUS_CANCELLED iff deadline hasn't been
+ * exceeded */
+ return gpr_time_cmp(gpr_now(deadline.clock_type), deadline) >= 0
+ ? GRPC_STATUS_DEADLINE_EXCEEDED
+ : GRPC_STATUS_CANCELLED;
+ case GRPC_CHTTP2_ENHANCE_YOUR_CALM:
+ return GRPC_STATUS_RESOURCE_EXHAUSTED;
+ case GRPC_CHTTP2_INADEQUATE_SECURITY:
+ return GRPC_STATUS_PERMISSION_DENIED;
+ case GRPC_CHTTP2_REFUSED_STREAM:
+ return GRPC_STATUS_UNAVAILABLE;
+ default:
+ return GRPC_STATUS_INTERNAL;
+ }
+}
+
+grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status) {
+ switch (status) {
+ /* these HTTP2 status codes are called out explicitly in status.proto */
+ case 200:
+ return GRPC_STATUS_OK;
+ case 400:
+ return GRPC_STATUS_INVALID_ARGUMENT;
+ case 401:
+ return GRPC_STATUS_UNAUTHENTICATED;
+ case 403:
+ return GRPC_STATUS_PERMISSION_DENIED;
+ case 404:
+ return GRPC_STATUS_NOT_FOUND;
+ case 409:
+ return GRPC_STATUS_ABORTED;
+ case 412:
+ return GRPC_STATUS_FAILED_PRECONDITION;
+ case 429:
+ return GRPC_STATUS_RESOURCE_EXHAUSTED;
+ case 499:
+ return GRPC_STATUS_CANCELLED;
+ case 500:
+ return GRPC_STATUS_UNKNOWN;
+ case 501:
+ return GRPC_STATUS_UNIMPLEMENTED;
+ case 503:
+ return GRPC_STATUS_UNAVAILABLE;
+ case 504:
+ return GRPC_STATUS_DEADLINE_EXCEEDED;
+ /* everything else is unknown */
+ default:
+ return GRPC_STATUS_UNKNOWN;
+ }
+}
+
+int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status) {
+ return 200;
+}
diff --git a/src/core/lib/transport/status_conversion.h b/src/core/lib/transport/status_conversion.h
new file mode 100644
index 0000000000..592411529d
--- /dev/null
+++ b/src/core/lib/transport/status_conversion.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_STATUS_CONVERSION_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_STATUS_CONVERSION_H
+
+#include <grpc/grpc.h>
+#include "src/core/lib/transport/http2_errors.h"
+
+/* Conversion of grpc status codes to http2 error codes (for RST_STREAM) */
+grpc_chttp2_error_code grpc_chttp2_grpc_status_to_http2_error(
+ grpc_status_code status);
+grpc_status_code grpc_chttp2_http2_error_to_grpc_status(
+ grpc_chttp2_error_code error, gpr_timespec deadline);
+
+/* Conversion of HTTP status codes (:status) to grpc status codes */
+grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status);
+int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status);
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_STATUS_CONVERSION_H */