1 /*
2  * Copyright (c) 2014-2018 DeNA Co., Ltd., Kazuho Oku, Fastly
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  */
22 #ifndef h2o__hpack_h
23 #define h2o__hpack_h
24 
25 #include <stddef.h>
26 #include <stdint.h>
27 #include "h2o/header.h"
28 #include "h2o/url.h"
29 #include "h2o/cache_digests.h"
30 
31 #define H2O_HPACK_ENCODE_INT_MAX_LENGTH 10 /* first byte + 9 bytes (7*9==63 bits to hold positive numbers of int64_t) */
32 
33 extern const char h2o_hpack_err_found_upper_case_in_header_name[];
34 extern const char h2o_hpack_soft_err_found_invalid_char_in_header_name[];
35 extern const char h2o_hpack_soft_err_found_invalid_char_in_header_value[];
36 
37 #define H2O_HPACK_SOFT_ERROR_BIT_INVALID_NAME 0x1
38 #define H2O_HPACK_SOFT_ERROR_BIT_INVALID_VALUE 0x2
39 
40 /**
41  * encodes an integer (maximum size of the output excluding the first octet is H2O_HTTP2_ENCODE_INT_MAX_LENGTH bytes)
42  */
43 uint8_t *h2o_hpack_encode_int(uint8_t *dst, int64_t value, unsigned prefix_bits);
44 /**
45  * encodes a huffman string and returns its length, or returns SIZE_MAX if the resulting string would be longer than the input
46  */
47 size_t h2o_hpack_encode_huffman(uint8_t *dst, const uint8_t *src, size_t len);
48 /**
49  * decodes an integer, or returns an error code (either H2O_HTTP2_ERROR_COMPRESSION or H2O_HTTP2_ERROR_INCOMPLETE)
50  */
51 int64_t h2o_hpack_decode_int(const uint8_t **src, const uint8_t *src_end, unsigned prefix_bits);
52 /**
53  * Decodes a huffman string and returns its length, or SIZE_MAX if hard fails. The destination buffer must be at least double the
54  * size of the input. For the soft errors being detected, the corresponding bits of `*soft_errors` will be set.
55  */
56 size_t h2o_hpack_decode_huffman(char *dst, unsigned *soft_errors, const uint8_t *src, size_t len, int is_name,
57                                 const char **err_desc);
58 /**
59  * Validates header name and returns if hard validation succeeded. Upon failure, description of the hard failure will be stored in
60  * `*err_desc`. Upon success, the corresponding bits in `*soft_errors` will be set for the soft errors being detected.
61  */
62 int h2o_hpack_validate_header_name(unsigned *soft_errors, const char *s, size_t len, const char **err_desc);
63 /**
64  * Validates a header field value and returns soft errors.
65  */
66 void h2o_hpack_validate_header_value(unsigned *soft_errors, const char *s, size_t len);
67 
68 #define H2O_HPACK_PARSE_HEADERS_METHOD_EXISTS 1
69 #define H2O_HPACK_PARSE_HEADERS_SCHEME_EXISTS 2
70 #define H2O_HPACK_PARSE_HEADERS_PATH_EXISTS 4
71 #define H2O_HPACK_PARSE_HEADERS_AUTHORITY_EXISTS 8
72 
73 /**
74  * Decodes a header field. This function must indicate soft errors using error codes, setting `*err_desc` to appropciate values.
75  */
76 typedef int (*h2o_hpack_decode_header_cb)(h2o_mem_pool_t *pool, void *ctx, h2o_iovec_t **name, h2o_iovec_t *value,
77                                           const uint8_t **const src, const uint8_t *src_end, const char **err_desc);
78 /**
79  * HPACK implementation of `h2o_hpack_decode_header_cb`.
80  */
81 int h2o_hpack_decode_header(h2o_mem_pool_t *pool, void *_hpack_header_table, h2o_iovec_t **name, h2o_iovec_t *_value,
82                             const uint8_t **const src, const uint8_t *src_end, const char **err_desc);
83 /**
84  * Request parser that uses given callback as the decoder.
85  */
86 int h2o_hpack_parse_request(h2o_mem_pool_t *pool, h2o_hpack_decode_header_cb decode_cb, void *decode_ctx, h2o_iovec_t *method,
87                             const h2o_url_scheme_t **scheme, h2o_iovec_t *authority, h2o_iovec_t *path, h2o_headers_t *headers,
88                             int *pseudo_header_exists_map, size_t *content_length, h2o_cache_digests_t **digests,
89                             h2o_iovec_t *datagram_flow_id, const uint8_t *src, size_t len, const char **err_desc);
90 /**
91  * Response parser that uses given callback as the decoder.
92  */
93 int h2o_hpack_parse_response(h2o_mem_pool_t *pool, h2o_hpack_decode_header_cb decode_cb, void *decode_ctx, int *status,
94                              h2o_headers_t *headers, h2o_iovec_t *datagram_flow_id, const uint8_t *src, size_t len,
95                              const char **err_desc);
96 
97 #endif
98