Commit 346fafde authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Implement draft-ietf-httpbis-header-compression-02

parent 0b005e3f
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
#include "nghttp2_buffer.h" #include "nghttp2_buffer.h"
/* The maximum payload length of a frame */ /* The maximum payload length of a frame */
/* TODO The spec says the max payload length in HTTP is ((1 << 14) -
1) */
#define NGHTTP2_MAX_FRAME_LENGTH ((1 << 16) - 1) #define NGHTTP2_MAX_FRAME_LENGTH ((1 << 16) - 1)
/* The maximum paylaod length of a frame used in HTTP */
#define NGHTTP2_MAX_HTTP_FRAME_LENGTH ((1 << 14) - 1)
/* The maximum header block length. This is not specified by the /* The maximum header block length. This is not specified by the
spec. We just chose the arbitrary size */ spec. We just chose the arbitrary size */
......
This diff is collapsed.
...@@ -32,8 +32,7 @@ ...@@ -32,8 +32,7 @@
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
#define NGHTTP2_INITIAL_HD_TABLE_SIZE 128 #define NGHTTP2_INITIAL_HD_TABLE_SIZE 128
#define NGHTTP2_INITIAL_REFSET_SIZE 128 #define NGHTTP2_INITIAL_EMIT_SET_SIZE 128
#define NGHTTP2_INITIAL_WS_SIZE 128
#define NGHTTP2_HD_MAX_BUFFER_SIZE 4096 #define NGHTTP2_HD_MAX_BUFFER_SIZE 4096
#define NGHTTP2_HD_MAX_ENTRY_SIZE 1024 #define NGHTTP2_HD_MAX_ENTRY_SIZE 1024
...@@ -54,6 +53,11 @@ typedef enum { ...@@ -54,6 +53,11 @@ typedef enum {
NGHTTP2_HD_FLAG_NAME_ALLOC = 1, NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
/* Indicates value was dynamically allocated and must be freed */ /* Indicates value was dynamically allocated and must be freed */
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1, NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
/* Indicates that the entry is in the reference set */
NGHTTP2_HD_FLAG_REFSET = 1 << 2,
/* Indicates that the entry is emitted in the current header
processing. */
NGHTTP2_HD_FLAG_EMIT = 1 << 3,
} nghttp2_hd_flags; } nghttp2_hd_flags;
typedef struct { typedef struct {
...@@ -65,54 +69,20 @@ typedef struct { ...@@ -65,54 +69,20 @@ typedef struct {
uint8_t flags; uint8_t flags;
} nghttp2_hd_entry; } nghttp2_hd_entry;
typedef enum {
NGHTTP2_HD_CAT_NONE,
NGHTTP2_HD_CAT_INDEXED,
NGHTTP2_HD_CAT_INDNAME,
NGHTTP2_HD_CAT_NEWNAME
} nghttp2_hd_entry_cat;
typedef struct nghttp2_hd_ws_entry {
nghttp2_hd_entry_cat cat;
union {
/* For NGHTTP2_HD_CAT_INDEXED */
struct {
nghttp2_hd_entry *entry;
uint8_t index;
} indexed;
/* For NGHTTP2_HD_CAT_NEWNAME */
struct {
nghttp2_nv nv;
} newname;
/* For NGHTTP2_HD_CAT_LITERAL_INDNAME */
struct {
/* The entry in header table the name stored */
nghttp2_hd_entry *entry;
uint8_t *value;
uint16_t valuelen;
} indname;
};
} nghttp2_hd_ws_entry;
typedef struct { typedef struct {
/* Header table */ /* Header table */
nghttp2_hd_entry **hd_table; nghttp2_hd_entry **hd_table;
/* Reference set */ /* Holding emitted entry in deflating header block to retain
nghttp2_hd_entry **refset; reference count. */
/* Working set */ nghttp2_hd_entry **emit_set;
nghttp2_hd_ws_entry *ws;
/* The capacity of the |hd_table| */ /* The capacity of the |hd_table| */
uint16_t hd_table_capacity; uint16_t hd_table_capacity;
/* the number of entry the |hd_table| contains */ /* The number of entry the |hd_table| contains */
uint16_t hd_tablelen; uint16_t hd_tablelen;
/* The capacity of the |refset| */ /* The capacity of the |emit_set| */
uint16_t refset_capacity; uint16_t emit_set_capacity;
/* The number of entry the |refset| contains */ /* The number of entry the |emit_set| contains */
uint16_t refsetlen; uint16_t emit_setlen;
/* The capacity of the |ws| */
uint16_t ws_capacity;
/* The number of entry the |ws| contains */
uint16_t wslen;
/* Abstract buffer size of hd_table as described in the spec. This /* Abstract buffer size of hd_table as described in the spec. This
is the sum of length of name/value in hd_table + is the sum of length of name/value in hd_table +
NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */ NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
...@@ -218,8 +188,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater, ...@@ -218,8 +188,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
uint8_t *in, size_t inlen); uint8_t *in, size_t inlen);
/* /*
* Signals the end of processing one header block. This function * Signals the end of processing one header block.
* creates new reference set from working set.
* *
* This function returns 0 if it succeeds. Currently this function * This function returns 0 if it succeeds. Currently this function
* always succeeds. * always succeeds.
......
...@@ -227,7 +227,7 @@ int main(int argc, char* argv[]) ...@@ -227,7 +227,7 @@ int main(int argc, char* argv[])
!CU_add_test(pSuite, "hd_inflate_newname_inc", !CU_add_test(pSuite, "hd_inflate_newname_inc",
test_nghttp2_hd_inflate_newname_inc) || test_nghttp2_hd_inflate_newname_inc) ||
!CU_add_test(pSuite, "hd_inflate_indname_subst", !CU_add_test(pSuite, "hd_inflate_indname_subst",
test_nghttp2_hd_inflate_newname_inc) || test_nghttp2_hd_inflate_indname_subst) ||
!CU_add_test(pSuite, "hd_inflate_indname_subst_eviction", !CU_add_test(pSuite, "hd_inflate_indname_subst_eviction",
test_nghttp2_hd_inflate_indname_subst_eviction) || test_nghttp2_hd_inflate_indname_subst_eviction) ||
!CU_add_test(pSuite, "hd_inflate_indname_subst_eviction_neg", !CU_add_test(pSuite, "hd_inflate_indname_subst_eviction_neg",
......
...@@ -156,11 +156,11 @@ void test_nghttp2_hd_inflate_indname_inc(void) ...@@ -156,11 +156,11 @@ void test_nghttp2_hd_inflate_indname_inc(void)
nghttp2_nv *resnva; nghttp2_nv *resnva;
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER); nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&buf, &buflen, &offset, 12, CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&buf, &buflen, &offset, 11,
nv.value, nv.valuelen, 1)); nv.value, nv.valuelen, 1));
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset)); CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
assert_nv_equal(&nv, resnva, 1); assert_nv_equal(&nv, resnva, 1);
CU_ASSERT(39 == inflater.hd_tablelen); CU_ASSERT(31 == inflater.hd_tablelen);
assert_nv_equal(&nv, &inflater.hd_table[inflater.hd_tablelen-1]->nv, 1); assert_nv_equal(&nv, &inflater.hd_table[inflater.hd_tablelen-1]->nv, 1);
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
...@@ -174,13 +174,14 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void) ...@@ -174,13 +174,14 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void)
uint8_t *buf = NULL; uint8_t *buf = NULL;
size_t buflen = 0; size_t buflen = 0;
size_t offset = 0; size_t offset = 0;
/* Default header table capacity is 1592. Adding 2547 bytes, /* Default header table capacity is 1262. Adding 2835 bytes,
including overhead, to the table evicts first entry. including overhead, to the table evicts first entry.
use name ":host" which index 2 and value length 2510. */ use name ":host" which index 2 and value length 2798. */
uint8_t value[2510]; uint8_t value[2798];
nghttp2_nv *resnva; nghttp2_nv *resnva;
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER); nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
memset(value, '0', sizeof(value));
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&buf, &buflen, &offset, 2, CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&buf, &buflen, &offset, 2,
value, sizeof(value), 1)); value, sizeof(value), 1));
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset)); CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
...@@ -191,8 +192,8 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void) ...@@ -191,8 +192,8 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void)
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater); nghttp2_hd_end_headers(&inflater);
CU_ASSERT(38 == inflater.hd_tablelen); CU_ASSERT(30 == inflater.hd_tablelen);
CU_ASSERT(37 == inflater.refset[0]->index); CU_ASSERT(inflater.hd_table[29]->flags & NGHTTP2_HD_FLAG_REFSET);
free(buf); free(buf);
nghttp2_hd_inflate_free(&inflater); nghttp2_hd_inflate_free(&inflater);
...@@ -212,7 +213,7 @@ void test_nghttp2_hd_inflate_newname_inc(void) ...@@ -212,7 +213,7 @@ void test_nghttp2_hd_inflate_newname_inc(void)
&nv, 1)); &nv, 1));
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset)); CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
assert_nv_equal(&nv, resnva, 1); assert_nv_equal(&nv, resnva, 1);
CU_ASSERT(39 == inflater.hd_tablelen); CU_ASSERT(31 == inflater.hd_tablelen);
assert_nv_equal(&nv, &inflater.hd_table[inflater.hd_tablelen-1]->nv, 1); assert_nv_equal(&nv, &inflater.hd_table[inflater.hd_tablelen-1]->nv, 1);
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
...@@ -231,13 +232,13 @@ void test_nghttp2_hd_inflate_indname_subst(void) ...@@ -231,13 +232,13 @@ void test_nghttp2_hd_inflate_indname_subst(void)
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER); nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
CU_ASSERT(0 == nghttp2_hd_emit_subst_indname_block(&buf, &buflen, &offset, CU_ASSERT(0 == nghttp2_hd_emit_subst_indname_block(&buf, &buflen, &offset,
12, 11,
nv.value, nv.valuelen, nv.value, nv.valuelen,
12)); 11));
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset)); CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
assert_nv_equal(&nv, resnva, 1); assert_nv_equal(&nv, resnva, 1);
CU_ASSERT(38 == inflater.hd_tablelen); CU_ASSERT(30 == inflater.hd_tablelen);
assert_nv_equal(&nv, &inflater.hd_table[12]->nv, 1); assert_nv_equal(&nv, &inflater.hd_table[11]->nv, 1);
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
free(buf); free(buf);
...@@ -250,13 +251,14 @@ void test_nghttp2_hd_inflate_indname_subst_eviction(void) ...@@ -250,13 +251,14 @@ void test_nghttp2_hd_inflate_indname_subst_eviction(void)
uint8_t *buf = NULL; uint8_t *buf = NULL;
size_t buflen = 0; size_t buflen = 0;
size_t offset = 0; size_t offset = 0;
/* Default header table capacity is 1592. Adding 2547 bytes, /* Default header table capacity is 1262. Adding 2877 bytes,
including overhead, to the table evicts first entry. including overhead, to the table evicts first entry.
use name ":host" which index 2 and value length 2510. */ use name ":host" which index 2 and value length 2840. */
uint8_t value[2510]; uint8_t value[2840];
nghttp2_nv *resnva; nghttp2_nv *resnva;
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER); nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
memset(value, '0', sizeof(value));
CU_ASSERT(0 == nghttp2_hd_emit_subst_indname_block(&buf, &buflen, &offset, CU_ASSERT(0 == nghttp2_hd_emit_subst_indname_block(&buf, &buflen, &offset,
2, 2,
value, sizeof(value), 2)); value, sizeof(value), 2));
...@@ -268,8 +270,8 @@ void test_nghttp2_hd_inflate_indname_subst_eviction(void) ...@@ -268,8 +270,8 @@ void test_nghttp2_hd_inflate_indname_subst_eviction(void)
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater); nghttp2_hd_end_headers(&inflater);
CU_ASSERT(37 == inflater.hd_tablelen); CU_ASSERT(29 == inflater.hd_tablelen);
CU_ASSERT(1 == inflater.refset[0]->index); CU_ASSERT(inflater.hd_table[1]->flags & NGHTTP2_HD_FLAG_REFSET);
free(buf); free(buf);
nghttp2_hd_inflate_free(&inflater); nghttp2_hd_inflate_free(&inflater);
...@@ -281,12 +283,13 @@ void test_nghttp2_hd_inflate_indname_subst_eviction_neg(void) ...@@ -281,12 +283,13 @@ void test_nghttp2_hd_inflate_indname_subst_eviction_neg(void)
uint8_t *buf = NULL; uint8_t *buf = NULL;
size_t buflen = 0; size_t buflen = 0;
size_t offset = 0; size_t offset = 0;
/* Default header table capacity is 1592. Adding 2548 bytes, /* Default header table capacity is 1262. Adding 2878 bytes,
including overhead, to the table evicts first entry. including overhead, to the table evicts first 2 entries.
use name ":host" which index 2 and value length 2511. */ use name ":host" which index 2 and value length 2841. */
uint8_t value[2511]; uint8_t value[2841];
nghttp2_nv *resnva; nghttp2_nv *resnva;
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER); nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
memset(value, '0', sizeof(value));
/* Try to substitute index 0, but it will be evicted */ /* Try to substitute index 0, but it will be evicted */
CU_ASSERT(0 == nghttp2_hd_emit_subst_indname_block(&buf, &buflen, &offset, CU_ASSERT(0 == nghttp2_hd_emit_subst_indname_block(&buf, &buflen, &offset,
2, 2,
...@@ -299,8 +302,8 @@ void test_nghttp2_hd_inflate_indname_subst_eviction_neg(void) ...@@ -299,8 +302,8 @@ void test_nghttp2_hd_inflate_indname_subst_eviction_neg(void)
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater); nghttp2_hd_end_headers(&inflater);
CU_ASSERT(37 == inflater.hd_tablelen); CU_ASSERT(29 == inflater.hd_tablelen);
CU_ASSERT(0 == inflater.refset[0]->index); CU_ASSERT(inflater.hd_table[0]->flags & NGHTTP2_HD_FLAG_REFSET);
free(buf); free(buf);
nghttp2_hd_inflate_free(&inflater); nghttp2_hd_inflate_free(&inflater);
...@@ -320,7 +323,7 @@ void test_nghttp2_hd_inflate_newname_subst(void) ...@@ -320,7 +323,7 @@ void test_nghttp2_hd_inflate_newname_subst(void)
&nv, 1)); &nv, 1));
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset)); CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
assert_nv_equal(&nv, resnva, 1); assert_nv_equal(&nv, resnva, 1);
CU_ASSERT(38 == inflater.hd_tablelen); CU_ASSERT(30 == inflater.hd_tablelen);
assert_nv_equal(&nv, &inflater.hd_table[1]->nv, 1); assert_nv_equal(&nv, &inflater.hd_table[1]->nv, 1);
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment