nghttp2_hd: Share static table globally
This commit is contained in:
parent
5a81e03497
commit
0c3cb104e9
183
lib/nghttp2_hd.c
183
lib/nghttp2_hd.c
|
@ -30,69 +30,76 @@
|
||||||
#include "nghttp2_frame.h"
|
#include "nghttp2_frame.h"
|
||||||
#include "nghttp2_helper.h"
|
#include "nghttp2_helper.h"
|
||||||
|
|
||||||
static const char *static_table[] = {
|
/* Make scalar initialization form of nghttp2_nv */
|
||||||
/* 0 */ ":authority", "",
|
#define MAKE_NV(N, V) \
|
||||||
/* 1 */ ":method", "GET",
|
{ { (uint8_t*)N, (uint8_t*)V, sizeof(N) - 1, sizeof(V) - 1 }, \
|
||||||
/* 2 */ ":method", "POST",
|
1, NGHTTP2_HD_FLAG_NONE }
|
||||||
/* 3 */ ":path", "/",
|
|
||||||
/* 4 */ ":path", "/index.html",
|
static nghttp2_hd_entry static_table[] = {
|
||||||
/* 5 */ ":scheme", "http",
|
/* 0 */ MAKE_NV(":authority", ""),
|
||||||
/* 6 */ ":scheme", "https",
|
/* 1 */ MAKE_NV(":method", "GET"),
|
||||||
/* 7 */ ":status", "200",
|
/* 2 */ MAKE_NV(":method", "POST"),
|
||||||
/* 8 */ ":status", "500",
|
/* 3 */ MAKE_NV(":path", "/"),
|
||||||
/* 9 */ ":status", "404",
|
/* 4 */ MAKE_NV(":path", "/index.html"),
|
||||||
/* 10 */ ":status", "403",
|
/* 5 */ MAKE_NV(":scheme", "http"),
|
||||||
/* 11 */ ":status", "400",
|
/* 6 */ MAKE_NV(":scheme", "https"),
|
||||||
/* 12 */ ":status", "401",
|
/* 7 */ MAKE_NV(":status", "200"),
|
||||||
/* 13 */ "accept-charset", "",
|
/* 8 */ MAKE_NV(":status", "500"),
|
||||||
/* 14 */ "accept-encoding", "",
|
/* 9 */ MAKE_NV(":status", "404"),
|
||||||
/* 15 */ "accept-language", "",
|
/* 10 */ MAKE_NV(":status", "403"),
|
||||||
/* 16 */ "accept-ranges", "",
|
/* 11 */ MAKE_NV(":status", "400"),
|
||||||
/* 17 */ "accept", "",
|
/* 12 */ MAKE_NV(":status", "401"),
|
||||||
/* 18 */ "access-control-allow-origin", "",
|
/* 13 */ MAKE_NV("accept-charset", ""),
|
||||||
/* 19 */ "age", "",
|
/* 14 */ MAKE_NV("accept-encoding", ""),
|
||||||
/* 20 */ "allow", "",
|
/* 15 */ MAKE_NV("accept-language", ""),
|
||||||
/* 21 */ "authorization", "",
|
/* 16 */ MAKE_NV("accept-ranges", ""),
|
||||||
/* 22 */ "cache-control", "",
|
/* 17 */ MAKE_NV("accept", ""),
|
||||||
/* 23 */ "content-disposition", "",
|
/* 18 */ MAKE_NV("access-control-allow-origin", ""),
|
||||||
/* 24 */ "content-encoding", "",
|
/* 19 */ MAKE_NV("age", ""),
|
||||||
/* 25 */ "content-language", "",
|
/* 20 */ MAKE_NV("allow", ""),
|
||||||
/* 26 */ "content-length", "",
|
/* 21 */ MAKE_NV("authorization", ""),
|
||||||
/* 27 */ "content-location", "",
|
/* 22 */ MAKE_NV("cache-control", ""),
|
||||||
/* 28 */ "content-range", "",
|
/* 23 */ MAKE_NV("content-disposition", ""),
|
||||||
/* 29 */ "content-type", "",
|
/* 24 */ MAKE_NV("content-encoding", ""),
|
||||||
/* 30 */ "cookie", "",
|
/* 25 */ MAKE_NV("content-language", ""),
|
||||||
/* 31 */ "date", "",
|
/* 26 */ MAKE_NV("content-length", ""),
|
||||||
/* 32 */ "etag", "",
|
/* 27 */ MAKE_NV("content-location", ""),
|
||||||
/* 33 */ "expect", "",
|
/* 28 */ MAKE_NV("content-range", ""),
|
||||||
/* 34 */ "expires", "",
|
/* 29 */ MAKE_NV("content-type", ""),
|
||||||
/* 35 */ "from", "",
|
/* 30 */ MAKE_NV("cookie", ""),
|
||||||
/* 36 */ "if-match", "",
|
/* 31 */ MAKE_NV("date", ""),
|
||||||
/* 37 */ "if-modified-since", "",
|
/* 32 */ MAKE_NV("etag", ""),
|
||||||
/* 38 */ "if-none-match", "",
|
/* 33 */ MAKE_NV("expect", ""),
|
||||||
/* 39 */ "if-range", "",
|
/* 34 */ MAKE_NV("expires", ""),
|
||||||
/* 40 */ "if-unmodified-since", "",
|
/* 35 */ MAKE_NV("from", ""),
|
||||||
/* 41 */ "last-modified", "",
|
/* 36 */ MAKE_NV("if-match", ""),
|
||||||
/* 42 */ "link", "",
|
/* 37 */ MAKE_NV("if-modified-since", ""),
|
||||||
/* 43 */ "location", "",
|
/* 38 */ MAKE_NV("if-none-match", ""),
|
||||||
/* 44 */ "max-forwards", "",
|
/* 39 */ MAKE_NV("if-range", ""),
|
||||||
/* 45 */ "proxy-authenticate", "",
|
/* 40 */ MAKE_NV("if-unmodified-since", ""),
|
||||||
/* 46 */ "proxy-authorization", "",
|
/* 41 */ MAKE_NV("last-modified", ""),
|
||||||
/* 47 */ "range", "",
|
/* 42 */ MAKE_NV("link", ""),
|
||||||
/* 48 */ "referer", "",
|
/* 43 */ MAKE_NV("location", ""),
|
||||||
/* 49 */ "refresh", "",
|
/* 44 */ MAKE_NV("max-forwards", ""),
|
||||||
/* 50 */ "retry-after", "",
|
/* 45 */ MAKE_NV("proxy-authenticate", ""),
|
||||||
/* 51 */ "server", "",
|
/* 46 */ MAKE_NV("proxy-authorization", ""),
|
||||||
/* 52 */ "set-cookie", "",
|
/* 47 */ MAKE_NV("range", ""),
|
||||||
/* 53 */ "strict-transport-security", "",
|
/* 48 */ MAKE_NV("referer", ""),
|
||||||
/* 54 */ "transfer-encoding", "",
|
/* 49 */ MAKE_NV("refresh", ""),
|
||||||
/* 55 */ "user-agent", "",
|
/* 50 */ MAKE_NV("retry-after", ""),
|
||||||
/* 56 */ "vary", "",
|
/* 51 */ MAKE_NV("server", ""),
|
||||||
/* 57 */ "via", "",
|
/* 52 */ MAKE_NV("set-cookie", ""),
|
||||||
/* 58 */ "www-authenticate", "",
|
/* 53 */ MAKE_NV("strict-transport-security", ""),
|
||||||
NULL
|
/* 54 */ MAKE_NV("transfer-encoding", ""),
|
||||||
|
/* 55 */ MAKE_NV("user-agent", ""),
|
||||||
|
/* 56 */ MAKE_NV("vary", ""),
|
||||||
|
/* 57 */ MAKE_NV("via", ""),
|
||||||
|
/* 58 */ MAKE_NV("www-authenticate", "")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const static size_t STATIC_TABLE_LENGTH =
|
||||||
|
sizeof(static_table)/sizeof(static_table[0]);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nghttp2_nv *nva;
|
nghttp2_nv *nva;
|
||||||
size_t nvacap;
|
size_t nvacap;
|
||||||
|
@ -215,7 +222,6 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
nghttp2_hd_side side,
|
nghttp2_hd_side side,
|
||||||
size_t hd_table_bufsize_max)
|
size_t hd_table_bufsize_max)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
int rv;
|
int rv;
|
||||||
context->role = role;
|
context->role = role;
|
||||||
context->side = side;
|
context->side = side;
|
||||||
|
@ -226,29 +232,6 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
for(i = 0; static_table[i]; i += 2);
|
|
||||||
context->static_hd_table = malloc(sizeof(nghttp2_hd_entry*)*(i / 2 + 1));
|
|
||||||
if(context->static_hd_table == NULL) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
context->static_hd_table[i / 2] = NULL;
|
|
||||||
for(i = 0; static_table[i]; i += 2) {
|
|
||||||
nghttp2_hd_entry *p = malloc(sizeof(nghttp2_hd_entry));
|
|
||||||
if(p == NULL) {
|
|
||||||
size_t j;
|
|
||||||
for(j = 0; j < i / 2; ++j) {
|
|
||||||
--context->static_hd_table[j]->ref;
|
|
||||||
nghttp2_hd_entry_free(context->static_hd_table[j]);
|
|
||||||
free(context->static_hd_table[j]);
|
|
||||||
}
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
nghttp2_hd_entry_init(p, NGHTTP2_HD_FLAG_NONE,
|
|
||||||
(uint8_t*)static_table[i], strlen(static_table[i]),
|
|
||||||
(uint8_t*)static_table[i + 1],
|
|
||||||
strlen(static_table[i+1]));
|
|
||||||
context->static_hd_table[i / 2] = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(role == NGHTTP2_HD_ROLE_INFLATE) {
|
if(role == NGHTTP2_HD_ROLE_INFLATE) {
|
||||||
context->emit_set = malloc(sizeof(nghttp2_hd_entry*)*
|
context->emit_set = malloc(sizeof(nghttp2_hd_entry*)*
|
||||||
|
@ -277,7 +260,6 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
context->hd_table_bufsize = 0;
|
context->hd_table_bufsize = 0;
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
free(context->static_hd_table);
|
|
||||||
free(context->buf_track);
|
free(context->buf_track);
|
||||||
free(context->emit_set);
|
free(context->emit_set);
|
||||||
nghttp2_hd_ringbuf_free(&context->hd_table);
|
nghttp2_hd_ringbuf_free(&context->hd_table);
|
||||||
|
@ -330,13 +312,6 @@ static void nghttp2_hd_context_free(nghttp2_hd_context *context)
|
||||||
free(context->emit_set);
|
free(context->emit_set);
|
||||||
|
|
||||||
nghttp2_hd_ringbuf_free(&context->hd_table);
|
nghttp2_hd_ringbuf_free(&context->hd_table);
|
||||||
|
|
||||||
for(i = 0; context->static_hd_table[i]; ++i) {
|
|
||||||
--context->static_hd_table[i]->ref;
|
|
||||||
nghttp2_hd_entry_free(context->static_hd_table[i]);
|
|
||||||
free(context->static_hd_table[i]);
|
|
||||||
}
|
|
||||||
free(context->static_hd_table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_hd_deflate_free(nghttp2_hd_context *deflater)
|
void nghttp2_hd_deflate_free(nghttp2_hd_context *deflater)
|
||||||
|
@ -745,8 +720,8 @@ static ssize_t find_in_hd_table(nghttp2_hd_context *context, nghttp2_nv *nv)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i = 0; context->static_hd_table[i]; ++i) {
|
for(i = 0; i < STATIC_TABLE_LENGTH; ++i) {
|
||||||
nghttp2_hd_entry *ent = context->static_hd_table[i];
|
nghttp2_hd_entry *ent = &static_table[i];
|
||||||
if(nghttp2_nv_equal(&ent->nv, nv)) {
|
if(nghttp2_nv_equal(&ent->nv, nv)) {
|
||||||
return context->hd_table.len + i;
|
return context->hd_table.len + i;
|
||||||
}
|
}
|
||||||
|
@ -765,8 +740,8 @@ static ssize_t find_name_in_hd_table(nghttp2_hd_context *context,
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i = 0; context->static_hd_table[i]; ++i) {
|
for(i = 0; i < STATIC_TABLE_LENGTH; ++i) {
|
||||||
nghttp2_hd_entry *ent = context->static_hd_table[i];
|
nghttp2_hd_entry *ent = &static_table[i];
|
||||||
if(ent->nv.namelen == nv->namelen &&
|
if(ent->nv.namelen == nv->namelen &&
|
||||||
memcmp(ent->nv.name, nv->name, nv->namelen) == 0) {
|
memcmp(ent->nv.name, nv->name, nv->namelen) == 0) {
|
||||||
return context->hd_table.len + i;
|
return context->hd_table.len + i;
|
||||||
|
@ -775,13 +750,19 @@ static ssize_t find_name_in_hd_table(nghttp2_hd_context *context,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_index_range(nghttp2_hd_context *context, size_t index)
|
||||||
|
{
|
||||||
|
return index < context->hd_table.len + STATIC_TABLE_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
|
nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
|
||||||
size_t index)
|
size_t index)
|
||||||
{
|
{
|
||||||
|
assert(check_index_range(context, index));
|
||||||
if(index < context->hd_table.len) {
|
if(index < context->hd_table.len) {
|
||||||
return nghttp2_hd_ringbuf_get(&context->hd_table, index);
|
return nghttp2_hd_ringbuf_get(&context->hd_table, index);
|
||||||
} else {
|
} else {
|
||||||
return context->static_hd_table[index - context->hd_table.len];
|
return &static_table[index - context->hd_table.len];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,12 +952,6 @@ static int inflater_post_process_hd_entry(nghttp2_hd_context *inflater,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_index_range(nghttp2_hd_context *context, size_t index)
|
|
||||||
{
|
|
||||||
return index < context->hd_table.len +
|
|
||||||
sizeof(static_table)/sizeof(static_table[0])/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t inflate_decode(uint8_t **dest_ptr, uint8_t *in, size_t inlen,
|
static ssize_t inflate_decode(uint8_t **dest_ptr, uint8_t *in, size_t inlen,
|
||||||
nghttp2_hd_side side)
|
nghttp2_hd_side side)
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,9 +83,8 @@ typedef struct {
|
||||||
} nghttp2_hd_ringbuf;
|
} nghttp2_hd_ringbuf;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Header table */
|
/* dynamic header table */
|
||||||
nghttp2_hd_ringbuf hd_table;
|
nghttp2_hd_ringbuf hd_table;
|
||||||
nghttp2_hd_entry **static_hd_table;
|
|
||||||
/* Holding emitted entry in deflating header block to retain
|
/* Holding emitted entry in deflating header block to retain
|
||||||
reference count. */
|
reference count. */
|
||||||
nghttp2_hd_entry **emit_set;
|
nghttp2_hd_entry **emit_set;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import re, sys
|
||||||
|
|
||||||
for line in sys.stdin:
|
for line in sys.stdin:
|
||||||
m = re.match(r'(\d+)\s+(\S+)\s+(\S+)?', line)
|
m = re.match(r'(\d+)\s+(\S+)\s+(\S+)?', line)
|
||||||
print '/* {} */ "{}", "{}",'.format(m.group(1),
|
print '/* {} */ MAKE_NV("{}", "{}"),'\
|
||||||
m.group(2),
|
.format(m.group(1),
|
||||||
m.group(3) if m.group(3) else '')
|
m.group(2),
|
||||||
|
m.group(3) if m.group(3) else '')
|
||||||
|
|
Loading…
Reference in New Issue