blob: 61209ae48d1d3ed9457a7586d0717f9e59aadba1 [file] [log] [blame]
murgatroid99c3910ca2016-01-06 13:14:23 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2016 gRPC authors.
murgatroid99c3910ca2016-01-06 13:14:23 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
murgatroid99c3910ca2016-01-06 13:14:23 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
murgatroid99c3910ca2016-01-06 13:14:23 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
murgatroid99c3910ca2016-01-06 13:14:23 -080016 *
17 */
18
19#include <stdlib.h>
20#include <string.h>
21
Craig Tiller7c70b6c2017-01-23 07:48:42 -080022#include <grpc/grpc.h>
23#include <grpc/support/alloc.h>
murgatroid9936187ab2016-01-06 13:23:59 -080024#include <grpc/support/port_platform.h>
murgatroid99c3910ca2016-01-06 13:14:23 -080025
Craig Tiller7c70b6c2017-01-23 07:48:42 -080026#include "src/core/lib/iomgr/error.h"
ncteisenbbb38012017-03-10 14:58:43 -080027#include "src/core/lib/slice/slice_internal.h"
Craig Tiller7c70b6c2017-01-23 07:48:42 -080028#include "src/core/lib/slice/slice_string_helpers.h"
29
30static grpc_error *conforms_to(grpc_slice slice, const uint8_t *legal_bits,
31 const char *err_desc) {
32 const uint8_t *p = GRPC_SLICE_START_PTR(slice);
33 const uint8_t *e = GRPC_SLICE_END_PTR(slice);
murgatroid99c3910ca2016-01-06 13:14:23 -080034 for (; p != e; p++) {
Craig Tiller7c70b6c2017-01-23 07:48:42 -080035 int idx = *p;
murgatroid99c3910ca2016-01-06 13:14:23 -080036 int byte = idx / 8;
37 int bit = idx % 8;
Craig Tiller7c70b6c2017-01-23 07:48:42 -080038 if ((legal_bits[byte] & (1 << bit)) == 0) {
39 char *dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
40 grpc_error *error = grpc_error_set_str(
Noah Eisen3005ce82017-03-14 13:38:41 -070041 grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc),
ncteisen4b36a3d2017-03-13 19:08:06 -070042 GRPC_ERROR_INT_OFFSET,
Craig Tiller7c70b6c2017-01-23 07:48:42 -080043 p - GRPC_SLICE_START_PTR(slice)),
ncteisenbbb38012017-03-10 14:58:43 -080044 GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(dump));
Craig Tiller7c70b6c2017-01-23 07:48:42 -080045 gpr_free(dump);
46 return error;
47 }
murgatroid99c3910ca2016-01-06 13:14:23 -080048 }
Craig Tiller7c70b6c2017-01-23 07:48:42 -080049 return GRPC_ERROR_NONE;
murgatroid99c3910ca2016-01-06 13:14:23 -080050}
51
Craig Tiller7c70b6c2017-01-23 07:48:42 -080052static int error2int(grpc_error *error) {
53 int r = (error == GRPC_ERROR_NONE);
54 GRPC_ERROR_UNREF(error);
55 return r;
56}
57
58grpc_error *grpc_validate_header_key_is_legal(grpc_slice slice) {
murgatroid99d12d5ba2016-01-08 13:26:23 -080059 static const uint8_t legal_header_bits[256 / 8] = {
Craig Tiller6f871642016-02-03 16:15:31 -080060 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00,
murgatroid99c3910ca2016-01-06 13:14:23 -080061 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Craig Tiller7c70b6c2017-01-23 07:48:42 -080063 if (GRPC_SLICE_LENGTH(slice) == 0) {
ncteisen4b36a3d2017-03-13 19:08:06 -070064 return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
65 "Metadata keys cannot be zero length");
Craig Tiller296c7bb2017-01-10 15:34:02 -080066 }
Craig Tiller7c70b6c2017-01-23 07:48:42 -080067 if (GRPC_SLICE_START_PTR(slice)[0] == ':') {
ncteisen4b36a3d2017-03-13 19:08:06 -070068 return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
69 "Metadata keys cannot start with :");
Craig Tiller7c70b6c2017-01-23 07:48:42 -080070 }
71 return conforms_to(slice, legal_header_bits, "Illegal header key");
murgatroid99c3910ca2016-01-06 13:14:23 -080072}
73
Craig Tiller7c70b6c2017-01-23 07:48:42 -080074int grpc_header_key_is_legal(grpc_slice slice) {
75 return error2int(grpc_validate_header_key_is_legal(slice));
76}
77
78grpc_error *grpc_validate_header_nonbin_value_is_legal(grpc_slice slice) {
murgatroid99d12d5ba2016-01-08 13:26:23 -080079 static const uint8_t legal_header_bits[256 / 8] = {
murgatroid99c3910ca2016-01-06 13:14:23 -080080 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
81 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Craig Tiller7c70b6c2017-01-23 07:48:42 -080083 return conforms_to(slice, legal_header_bits, "Illegal header value");
Craig Tillerf2b5b7e2017-01-10 08:28:59 -080084}
85
Craig Tiller7c70b6c2017-01-23 07:48:42 -080086int grpc_header_nonbin_value_is_legal(grpc_slice slice) {
87 return error2int(grpc_validate_header_nonbin_value_is_legal(slice));
88}
89
90int grpc_is_binary_header(grpc_slice slice) {
91 if (GRPC_SLICE_LENGTH(slice) < 5) return 0;
92 return 0 == memcmp(GRPC_SLICE_END_PTR(slice) - 4, "-bin", 4);
murgatroid99c3910ca2016-01-06 13:14:23 -080093}