From 03c908313763ce2bd464ca2bfddcfe6ff2dd0bb1 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Thu, 15 Nov 2018 12:56:56 +0900 Subject: [PATCH 1/3] remove token-specific fields from h2o_header_flags_t --- include/h2o/header.h | 27 ++++++--------------------- include/h2o/token.h | 8 ++++---- lib/common/http1client.c | 3 +-- lib/core/headers.c | 4 ++-- lib/core/proxy.c | 12 ++++++------ lib/core/request.c | 2 +- lib/handler/mruby.c | 2 +- lib/handler/mruby/middleware.c | 2 +- lib/http1.c | 2 +- lib/http2/connection.c | 11 ++++++----- lib/http2/hpack.c | 19 +++++++++++-------- t/00unit/lib/http2/hpack.c | 8 ++++---- 12 files changed, 44 insertions(+), 56 deletions(-) diff --git a/include/h2o/header.h b/include/h2o/header.h index 2f193f9f18..f6af27e983 100644 --- a/include/h2o/header.h +++ b/include/h2o/header.h @@ -29,6 +29,10 @@ extern "C" { #endif +typedef struct st_h2o_header_flags_t { + unsigned char dont_compress : 1; +} h2o_header_flags_t; + /** * represents a HTTP header */ @@ -46,8 +50,8 @@ typedef struct st_h2o_header_t { */ h2o_iovec_t value; /** - * flags of the header - */ + * flags of the header + */ h2o_header_flags_t flags; } h2o_header_t; @@ -103,14 +107,6 @@ ssize_t h2o_set_header_token(h2o_mem_pool_t *pool, h2o_headers_t *headers, const * deletes a header from list */ ssize_t h2o_delete_header(h2o_headers_t *headers, ssize_t cursor); -/** - * validates the structure - */ -static void h2o_header_validate(const h2o_header_t *header); -/** - * returns an boolean value if given header's name is a token, with validation - */ -static int h2o_header_is_token(const h2o_header_t *header); /* inline definitions */ @@ -123,17 +119,6 @@ inline int h2o_header_name_is_equal(const h2o_header_t *x, const h2o_header_t *y } } -inline void h2o_header_validate(const h2o_header_t *header) -{ - assert(header->flags.token_index_plus1 == 0 || header->name == &h2o__tokens[header->flags.token_index_plus1 - 1].buf); -} - -inline int h2o_header_is_token(const h2o_header_t *header) -{ - h2o_header_validate(header); - return header->flags.token_index_plus1 != 0; -} - #ifdef __cplusplus } #endif diff --git a/include/h2o/token.h b/include/h2o/token.h index 58f1578608..4cad1b7912 100644 --- a/include/h2o/token.h +++ b/include/h2o/token.h @@ -29,7 +29,7 @@ extern "C" { #endif -typedef struct st_h2o_header_flags_t { +typedef struct st_h2o_token_flags_t { unsigned char token_index_plus1; /* 1-origin, 0 means not token */ char http2_static_table_name_index; /* non-zero if any */ unsigned char proxy_should_drop_for_req : 1; @@ -37,15 +37,15 @@ typedef struct st_h2o_header_flags_t { unsigned char is_init_header_special : 1; unsigned char http2_should_reject : 1; unsigned char copy_for_push_request : 1; - unsigned char dont_compress : 1; -} h2o_header_flags_t; + unsigned char dont_compress : 1; /* consult `h2o_header_t:dont_compress` as well */ +} h2o_token_flags_t; /** * a predefined, read-only, fast variant of h2o_iovec_t, defined in h2o/token.h */ typedef struct st_h2o_token_t { h2o_iovec_t buf; - h2o_header_flags_t flags; + h2o_token_flags_t flags; } h2o_token_t; #ifndef H2O_MAX_TOKENS diff --git a/lib/common/http1client.c b/lib/common/http1client.c index bce42ad114..f1516d6716 100644 --- a/lib/common/http1client.c +++ b/lib/common/http1client.c @@ -267,14 +267,13 @@ static void on_head(h2o_socket_t *sock, const char *err) token = h2o_lookup_token(src_headers[i].name, src_headers[i].name_len); if (token != NULL) { headers[i].name = (h2o_iovec_t *)&token->buf; - headers[i].flags = token->flags; } else { header_names[i] = h2o_iovec_init(src_headers[i].name, src_headers[i].name_len); headers[i].name = &header_names[i]; - headers[i].flags = (h2o_header_flags_t){0}; } headers[i].value = h2o_iovec_init(src_headers[i].value, src_headers[i].value_len); headers[i].orig_name = orig_name; + headers[i].flags = (h2o_header_flags_t){0}; } if (!(100 <= http_status && http_status <= 199 && http_status != 101)) diff --git a/lib/core/headers.c b/lib/core/headers.c index 07e95a58cb..d0615a2593 100644 --- a/lib/core/headers.c +++ b/lib/core/headers.c @@ -63,7 +63,7 @@ ssize_t h2o_find_header_by_str(const h2o_headers_t *headers, const char *name, s ssize_t h2o_add_header(h2o_mem_pool_t *pool, h2o_headers_t *headers, const h2o_token_t *token, const char *orig_name, const char *value, size_t value_len) { - return add_header(pool, headers, (h2o_iovec_t *)&token->buf, orig_name, value, value_len, token->flags); + return add_header(pool, headers, (h2o_iovec_t *)&token->buf, orig_name, value, value_len, (h2o_header_flags_t){0}); } ssize_t h2o_add_header_by_str(h2o_mem_pool_t *pool, h2o_headers_t *headers, const char *name, size_t name_len, int maybe_token, @@ -74,7 +74,7 @@ ssize_t h2o_add_header_by_str(h2o_mem_pool_t *pool, h2o_headers_t *headers, cons if (maybe_token) { const h2o_token_t *token = h2o_lookup_token(name, name_len); if (token != NULL) { - return add_header(pool, headers, (h2o_iovec_t *)token, orig_name, value, value_len, token->flags); + return add_header(pool, headers, (h2o_iovec_t *)token, orig_name, value, value_len, (h2o_header_flags_t){0}); } } name_buf = h2o_mem_alloc_pool(pool, *name_buf, 1); diff --git a/lib/core/proxy.c b/lib/core/proxy.c index c0864a6bf0..fc1249d899 100644 --- a/lib/core/proxy.c +++ b/lib/core/proxy.c @@ -212,10 +212,10 @@ static void build_request(h2o_req_t *req, h2o_iovec_t *method, h2o_url_t *url, h const h2o_header_t *h, *h_end; int found_early_data = 0; for (h = req_headers.entries, h_end = h + req_headers.size; h != h_end; ++h) { - if (h->flags.proxy_should_drop_for_req) - continue; - if (h2o_header_is_token(h)) { + if (h2o_iovec_is_token(h->name)) { const h2o_token_t *token = (void *)h->name; + if (token->flags.proxy_should_drop_for_req) + continue; if (token == H2O_TOKEN_COOKIE) { /* merge the cookie headers; see HTTP/2 8.1.2.5 and HTTP/1 (RFC6265 5.4) */ /* FIXME current algorithm is O(n^2) against the number of cookie headers */ @@ -429,10 +429,10 @@ static h2o_httpclient_body_cb on_head(h2o_httpclient_t *client, const char *errs req->res.reason = h2o_strdup(&req->pool, msg.base, msg.len).base; for (i = 0; i != num_headers; ++i) { h2o_iovec_t value = headers[i].value; - if (headers[i].flags.proxy_should_drop_for_res) - continue; - if (h2o_header_is_token(&headers[i])) { + if (h2o_iovec_is_token(headers[i].name)) { const h2o_token_t *token = H2O_STRUCT_FROM_MEMBER(h2o_token_t, buf, headers[i].name); + if (token->flags.proxy_should_drop_for_res) + continue; if (token == H2O_TOKEN_CONTENT_LENGTH) { if (req->res.content_length != SIZE_MAX || (req->res.content_length = h2o_strtosize(headers[i].value.base, headers[i].value.len)) == SIZE_MAX) { diff --git a/lib/core/request.c b/lib/core/request.c index fd9d5923d5..e9a8ebb48d 100644 --- a/lib/core/request.c +++ b/lib/core/request.c @@ -284,7 +284,7 @@ void h2o_init_request(h2o_req_t *req, h2o_conn_t *conn, h2o_req_t *src) req->headers.size = src->headers.size; for (i = 0; i != src->headers.size; ++i) { h2o_header_t *dst_header = req->headers.entries + i, *src_header = src->headers.entries + i; - if (h2o_header_is_token(src_header)) { + if (h2o_iovec_is_token(src_header->name)) { dst_header->name = src_header->name; } else { dst_header->name = h2o_mem_alloc_pool(&req->pool, *dst_header->name, 1); diff --git a/lib/handler/mruby.c b/lib/handler/mruby.c index bc643db4cc..7ba053c420 100644 --- a/lib/handler/mruby.c +++ b/lib/handler/mruby.c @@ -689,7 +689,7 @@ static int iterate_headers_callback(h2o_mruby_shared_context_t *shared_ctx, h2o_ { mrb_value env = mrb_obj_value(cb_data); mrb_value n; - if (h2o_header_is_token(header)) { + if (h2o_iovec_is_token(header->name)) { const h2o_token_t *token = H2O_STRUCT_FROM_MEMBER(h2o_token_t, buf, header->name); n = h2o_mruby_token_env_key(shared_ctx, token); } else { diff --git a/lib/handler/mruby/middleware.c b/lib/handler/mruby/middleware.c index 839e220523..effa1b2546 100644 --- a/lib/handler/mruby/middleware.c +++ b/lib/handler/mruby/middleware.c @@ -147,7 +147,7 @@ static int iterate_headers_callback(h2o_mruby_shared_context_t *shared_ctx, h2o_ { mrb_value result_hash = mrb_obj_value(cb_data); mrb_value n; - if (h2o_header_is_token(header)) { + if (h2o_iovec_is_token(header->name)) { const h2o_token_t *token = H2O_STRUCT_FROM_MEMBER(h2o_token_t, buf, header->name); n = h2o_mruby_token_string(shared_ctx, token); } else { diff --git a/lib/http1.c b/lib/http1.c index 4ce6f17484..73ffa1f62e 100644 --- a/lib/http1.c +++ b/lib/http1.c @@ -360,7 +360,7 @@ static ssize_t fixup_request(struct st_h2o_http1_conn_t *conn, struct phr_header conn->req.input.path = h2o_strdup(&conn->req.pool, conn->req.input.path.base, conn->req.input.path.len); for (i = 0; i != conn->req.headers.size; ++i) { h2o_header_t *header = conn->req.headers.entries + i; - if (!h2o_header_is_token(header)) { + if (!h2o_iovec_is_token(header->name)) { *header->name = h2o_strdup(&conn->req.pool, header->name->base, header->name->len); } header->value = h2o_strdup(&conn->req.pool, header->value.base, header->value.len); diff --git a/lib/http2/connection.c b/lib/http2/connection.c index 2f32e71e53..e3a5e16fa3 100644 --- a/lib/http2/connection.c +++ b/lib/http2/connection.c @@ -1495,12 +1495,13 @@ static void push_path(h2o_req_t *src_req, const char *abspath, size_t abspath_le size_t i; for (i = 0; i != src_stream->req.headers.size; ++i) { h2o_header_t *src_header = src_stream->req.headers.entries + i; - if (src_header->flags.copy_for_push_request) { - assert(h2o_header_is_token(src_header)); /* currently only predefined headers are copiable*/ + /* currently only predefined headers are copiable */ + if (h2o_iovec_is_token(src_header->name)) { h2o_token_t *token = H2O_STRUCT_FROM_MEMBER(h2o_token_t, buf, src_header->name); - h2o_add_header(&stream->req.pool, &stream->req.headers, token, NULL, - h2o_strdup(&stream->req.pool, src_header->value.base, src_header->value.len).base, - src_header->value.len); + if (token->flags.copy_for_push_request) + h2o_add_header(&stream->req.pool, &stream->req.headers, token, NULL, + h2o_strdup(&stream->req.pool, src_header->value.base, src_header->value.len).base, + src_header->value.len); } } } diff --git a/lib/http2/hpack.c b/lib/http2/hpack.c index 7fd4a5d318..b9e7aed5d6 100644 --- a/lib/http2/hpack.c +++ b/lib/http2/hpack.c @@ -736,16 +736,17 @@ size_t h2o_hpack_encode_string(uint8_t *dst, const char *s, size_t len) } static uint8_t *do_encode_header(h2o_hpack_header_table_t *header_table, uint8_t *dst, const h2o_iovec_t *name, - const h2o_iovec_t *value, h2o_header_flags_t flags) + const h2o_iovec_t *value, int dont_compress) { - int name_index = flags.http2_static_table_name_index; + int is_token = h2o_iovec_is_token(name); + int name_index = is_token ? ((const h2o_token_t *)name)->flags.http2_static_table_name_index : 0; /* try to send as indexed */ { size_t header_table_index = header_table->entry_start_index, n; for (n = header_table->num_entries; n != 0; --n) { struct st_h2o_hpack_header_table_entry_t *entry = header_table->entries + header_table_index; - if (flags.token_index_plus1 != 0) { + if (is_token) { if (name != entry->name) goto Next; } else { @@ -768,7 +769,10 @@ static uint8_t *do_encode_header(h2o_hpack_header_table_t *header_table, uint8_t } } - int dont_compress = flags.dont_compress && value->len < 20 ? 1 : 0; + if (!dont_compress && is_token) + dont_compress = ((const h2o_token_t *)name)->flags.dont_compress; + if (dont_compress) + dont_compress = value->len < 20; if (name_index != 0) { /* literal header field with indexing (indexed name). */ @@ -796,7 +800,7 @@ static uint8_t *do_encode_header(h2o_hpack_header_table_t *header_table, uint8_t struct st_h2o_hpack_header_table_entry_t *entry = header_table_add(header_table, name->len + value->len + HEADER_TABLE_ENTRY_SIZE_OFFSET, 32); if (entry != NULL) { - if (flags.token_index_plus1 != 0) { + if (is_token) { entry->name = (h2o_iovec_t *)name; } else { entry->name = alloc_buf(NULL, name->len); @@ -814,14 +818,13 @@ static uint8_t *do_encode_header(h2o_hpack_header_table_t *header_table, uint8_t static uint8_t *encode_header(h2o_hpack_header_table_t *header_table, uint8_t *dst, const h2o_header_t *header) { - h2o_header_validate(header); - return do_encode_header(header_table, dst, header->name, &header->value, header->flags); + return do_encode_header(header_table, dst, header->name, &header->value, header->flags.dont_compress); } static uint8_t *encode_header_token(h2o_hpack_header_table_t *header_table, uint8_t *dst, const h2o_token_t *token, const h2o_iovec_t *value) { - return do_encode_header(header_table, dst, &token->buf, value, token->flags); + return do_encode_header(header_table, dst, &token->buf, value, token->flags.dont_compress); } static uint8_t *encode_method(h2o_hpack_header_table_t *header_table, uint8_t *dst, h2o_iovec_t value) diff --git a/t/00unit/lib/http2/hpack.c b/t/00unit/lib/http2/hpack.c index d05c88494d..419b8beb92 100644 --- a/t/00unit/lib/http2/hpack.c +++ b/t/00unit/lib/http2/hpack.c @@ -452,16 +452,16 @@ static void test_hpack_dynamic_table(void) /* expected: literal header with incremental indexing (name not indexed) */ n = h2o_iovec_init(H2O_STRLIT("x-name")); v = h2o_iovec_init(H2O_STRLIT("v1")); - p = do_encode_header(&header_table, p, &n, &v, (h2o_header_flags_t){0}); + p = do_encode_header(&header_table, p, &n, &v, 0); /* expected: literal header with incremental indexing (name indexed) */ v = h2o_iovec_init(H2O_STRLIT("v2")); - p = do_encode_header(&header_table, p, &n, &v, (h2o_header_flags_t){0}); + p = do_encode_header(&header_table, p, &n, &v, 0); /* expected: literal header with incremental indexing (name indexed, referring to the name associated with v2) */ v = h2o_iovec_init(H2O_STRLIT("v3")); - p = do_encode_header(&header_table, p, &n, &v, (h2o_header_flags_t){0}); + p = do_encode_header(&header_table, p, &n, &v, 0); /* expected: indexed header field */ v = h2o_iovec_init(H2O_STRLIT("v1")); - p = do_encode_header(&header_table, p, &n, &v, (h2o_header_flags_t){0}); + p = do_encode_header(&header_table, p, &n, &v, 0); const h2o_iovec_t expected = h2o_iovec_init( H2O_STRLIT("\x40\x85" /* literal header with incremental indexing (name not indexed, 5 bytes, huffman coded) */ From d08a2bd15785f25c126d175f71074f65b92ba9f2 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Thu, 15 Nov 2018 14:29:06 +0900 Subject: [PATCH 2/3] remove `token_index_plus1` --- include/h2o/token.h | 1 - misc/tokens.pl | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/h2o/token.h b/include/h2o/token.h index 4cad1b7912..0e4ad0f2b4 100644 --- a/include/h2o/token.h +++ b/include/h2o/token.h @@ -30,7 +30,6 @@ extern "C" { #endif typedef struct st_h2o_token_flags_t { - unsigned char token_index_plus1; /* 1-origin, 0 means not token */ char http2_static_table_name_index; /* non-zero if any */ unsigned char proxy_should_drop_for_req : 1; unsigned char proxy_should_drop_for_res : 1; diff --git a/misc/tokens.pl b/misc/tokens.pl index 697545b00b..9ac6f5e93c 100755 --- a/misc/tokens.pl +++ b/misc/tokens.pl @@ -96,7 +96,7 @@ /* DO NOT EDIT! generated by tokens.pl */ h2o_token_t h2o__tokens[] = { ? for my $i (0..$#$tokens) { - { { H2O_STRLIT("[$i][0] ?>") }, { , [$i][$_] } (1..$#{$tokens->[$i]})) ?> } } + { { H2O_STRLIT("[$i][0] ?>") }, { [$i][$_] } (1..$#{$tokens->[$i]})) ?> } } ? } }; size_t h2o__num_tokens = ; From 0b68155695a1d8a44d4e5024e74a9c5487b2c8ef Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Thu, 15 Nov 2018 14:29:44 +0900 Subject: [PATCH 3/3] regen --- lib/common/token_table.h | 126 +++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/lib/common/token_table.h b/lib/common/token_table.h index 2a7e129382..d5bcaa6381 100644 --- a/lib/common/token_table.h +++ b/lib/common/token_table.h @@ -21,69 +21,69 @@ */ /* DO NOT EDIT! generated by tokens.pl */ -h2o_token_t h2o__tokens[] = {{{H2O_STRLIT(":authority")}, {1, 1, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT(":method")}, {2, 2, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT(":path")}, {3, 4, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT(":scheme")}, {4, 6, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT(":status")}, {5, 8, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("accept")}, {6, 19, 0, 0, 0, 0, 1, 0}}, - {{H2O_STRLIT("accept-charset")}, {7, 15, 0, 0, 0, 0, 1, 0}}, - {{H2O_STRLIT("accept-encoding")}, {8, 16, 0, 0, 0, 0, 1, 0}}, - {{H2O_STRLIT("accept-language")}, {9, 17, 0, 0, 0, 0, 1, 0}}, - {{H2O_STRLIT("accept-ranges")}, {10, 18, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("access-control-allow-origin")}, {11, 20, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("age")}, {12, 21, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("allow")}, {13, 22, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("authorization")}, {14, 23, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("cache-control")}, {15, 24, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("cache-digest")}, {16, 0, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("connection")}, {17, 0, 1, 1, 0, 1, 0, 0}}, - {{H2O_STRLIT("content-disposition")}, {18, 25, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("content-encoding")}, {19, 26, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("content-language")}, {20, 27, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("content-length")}, {21, 28, 0, 0, 1, 0, 0, 0}}, - {{H2O_STRLIT("content-location")}, {22, 29, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("content-range")}, {23, 30, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("content-type")}, {24, 31, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("cookie")}, {25, 32, 0, 0, 0, 0, 0, 1}}, - {{H2O_STRLIT("date")}, {26, 33, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("early-data")}, {27, 0, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("etag")}, {28, 34, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("expect")}, {29, 35, 0, 0, 1, 0, 0, 0}}, - {{H2O_STRLIT("expires")}, {30, 36, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("from")}, {31, 37, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("host")}, {32, 38, 0, 0, 1, 1, 0, 0}}, - {{H2O_STRLIT("http2-settings")}, {33, 0, 1, 0, 0, 1, 0, 0}}, - {{H2O_STRLIT("if-match")}, {34, 39, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("if-modified-since")}, {35, 40, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("if-none-match")}, {36, 41, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("if-range")}, {37, 42, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("if-unmodified-since")}, {38, 43, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("keep-alive")}, {39, 0, 1, 1, 0, 0, 0, 0}}, - {{H2O_STRLIT("last-modified")}, {40, 44, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("link")}, {41, 45, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("location")}, {42, 46, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("max-forwards")}, {43, 47, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("proxy-authenticate")}, {44, 48, 1, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("proxy-authorization")}, {45, 49, 1, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("range")}, {46, 50, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("referer")}, {47, 51, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("refresh")}, {48, 52, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("retry-after")}, {49, 53, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("server")}, {50, 54, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("set-cookie")}, {51, 55, 0, 0, 0, 0, 0, 1}}, - {{H2O_STRLIT("strict-transport-security")}, {52, 56, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("te")}, {53, 0, 1, 0, 0, 1, 0, 0}}, - {{H2O_STRLIT("transfer-encoding")}, {54, 57, 1, 1, 1, 1, 0, 0}}, - {{H2O_STRLIT("upgrade")}, {55, 0, 1, 1, 1, 1, 0, 0}}, - {{H2O_STRLIT("user-agent")}, {56, 58, 0, 0, 0, 0, 1, 0}}, - {{H2O_STRLIT("vary")}, {57, 59, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("via")}, {58, 60, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("www-authenticate")}, {59, 61, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("x-compress-hint")}, {60, 0, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("x-forwarded-for")}, {61, 0, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("x-reproxy-url")}, {62, 0, 0, 0, 0, 0, 0, 0}}, - {{H2O_STRLIT("x-traffic")}, {63, 0, 0, 0, 0, 0, 0, 0}}}; +h2o_token_t h2o__tokens[] = {{{H2O_STRLIT(":authority")}, {1, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT(":method")}, {2, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT(":path")}, {4, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT(":scheme")}, {6, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT(":status")}, {8, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("accept")}, {19, 0, 0, 0, 0, 1, 0}}, + {{H2O_STRLIT("accept-charset")}, {15, 0, 0, 0, 0, 1, 0}}, + {{H2O_STRLIT("accept-encoding")}, {16, 0, 0, 0, 0, 1, 0}}, + {{H2O_STRLIT("accept-language")}, {17, 0, 0, 0, 0, 1, 0}}, + {{H2O_STRLIT("accept-ranges")}, {18, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("access-control-allow-origin")}, {20, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("age")}, {21, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("allow")}, {22, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("authorization")}, {23, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("cache-control")}, {24, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("cache-digest")}, {0, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("connection")}, {0, 1, 1, 0, 1, 0, 0}}, + {{H2O_STRLIT("content-disposition")}, {25, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("content-encoding")}, {26, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("content-language")}, {27, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("content-length")}, {28, 0, 0, 1, 0, 0, 0}}, + {{H2O_STRLIT("content-location")}, {29, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("content-range")}, {30, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("content-type")}, {31, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("cookie")}, {32, 0, 0, 0, 0, 0, 1}}, + {{H2O_STRLIT("date")}, {33, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("early-data")}, {0, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("etag")}, {34, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("expect")}, {35, 0, 0, 1, 0, 0, 0}}, + {{H2O_STRLIT("expires")}, {36, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("from")}, {37, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("host")}, {38, 0, 0, 1, 1, 0, 0}}, + {{H2O_STRLIT("http2-settings")}, {0, 1, 0, 0, 1, 0, 0}}, + {{H2O_STRLIT("if-match")}, {39, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("if-modified-since")}, {40, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("if-none-match")}, {41, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("if-range")}, {42, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("if-unmodified-since")}, {43, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("keep-alive")}, {0, 1, 1, 0, 0, 0, 0}}, + {{H2O_STRLIT("last-modified")}, {44, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("link")}, {45, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("location")}, {46, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("max-forwards")}, {47, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("proxy-authenticate")}, {48, 1, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("proxy-authorization")}, {49, 1, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("range")}, {50, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("referer")}, {51, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("refresh")}, {52, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("retry-after")}, {53, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("server")}, {54, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("set-cookie")}, {55, 0, 0, 0, 0, 0, 1}}, + {{H2O_STRLIT("strict-transport-security")}, {56, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("te")}, {0, 1, 0, 0, 1, 0, 0}}, + {{H2O_STRLIT("transfer-encoding")}, {57, 1, 1, 1, 1, 0, 0}}, + {{H2O_STRLIT("upgrade")}, {0, 1, 1, 1, 1, 0, 0}}, + {{H2O_STRLIT("user-agent")}, {58, 0, 0, 0, 0, 1, 0}}, + {{H2O_STRLIT("vary")}, {59, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("via")}, {60, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("www-authenticate")}, {61, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("x-compress-hint")}, {0, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("x-forwarded-for")}, {0, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("x-reproxy-url")}, {0, 0, 0, 0, 0, 0, 0}}, + {{H2O_STRLIT("x-traffic")}, {0, 0, 0, 0, 0, 0, 0}}}; size_t h2o__num_tokens = 63; const h2o_token_t *h2o_lookup_token(const char *name, size_t len)