From 24cb90806dd06c4207c5244ac50f0db83ccfaaf8 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 1 Apr 2014 23:17:50 +0900 Subject: [PATCH] Add flags to nghttp2_nv structure This is preliminary change for upcoming HPACK updates. The flags are used to determine the name/value pair is indexable or not. --- examples/client.c | 6 ++++-- examples/libevent-client.c | 6 ++++-- examples/libevent-server.c | 3 ++- lib/includes/nghttp2/nghttp2.h | 20 ++++++++++++++++++++ lib/nghttp2_frame.c | 2 ++ lib/nghttp2_hd.c | 13 ++++++++++++- src/http2.cc | 3 ++- src/http2.h | 9 ++++++--- src/http2_test.cc | 3 ++- tests/nghttp2_test_helper.h | 3 ++- 10 files changed, 56 insertions(+), 12 deletions(-) diff --git a/examples/client.c b/examples/client.c index 305d79ef..58947fa1 100644 --- a/examples/client.c +++ b/examples/client.c @@ -53,11 +53,13 @@ enum { #define MAKE_NV(NAME, VALUE) \ {(uint8_t*)NAME, (uint8_t*)VALUE, \ - (uint16_t)(sizeof(NAME) - 1), (uint16_t)(sizeof(VALUE) - 1) } + (uint16_t)(sizeof(NAME) - 1), (uint16_t)(sizeof(VALUE) - 1), \ + NGHTTP2_NV_FLAG_NONE } #define MAKE_NV_CS(NAME, VALUE) \ {(uint8_t*)NAME, (uint8_t*)VALUE, \ - (uint16_t)(sizeof(NAME) - 1), (uint16_t)(strlen(VALUE)) } + (uint16_t)(sizeof(NAME) - 1), (uint16_t)(strlen(VALUE)), \ + NGHTTP2_NV_FLAG_NONE } struct Connection { SSL *ssl; diff --git a/examples/libevent-client.c b/examples/libevent-client.c index 2c635b8b..aad4cf38 100644 --- a/examples/libevent-client.c +++ b/examples/libevent-client.c @@ -381,10 +381,12 @@ static void send_client_connection_header(http2_session_data *session_data) } #define MAKE_NV(NAME, VALUE, VALUELEN) \ - { (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, VALUELEN } + { (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, VALUELEN, \ + NGHTTP2_NV_FLAG_NONE } #define MAKE_NV2(NAME, VALUE) \ - { (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1 } + { (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \ + NGHTTP2_NV_FLAG_NONE } /* Send HTTP request to the remote peer */ static void submit_request(http2_session_data *session_data) diff --git a/examples/libevent-server.c b/examples/libevent-server.c index fdf71852..a99262f1 100644 --- a/examples/libevent-server.c +++ b/examples/libevent-server.c @@ -49,7 +49,8 @@ #define ARRLEN(x) (sizeof(x)/sizeof(x[0])) #define MAKE_NV(NAME, VALUE) \ - { (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1 } + { (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \ + NGHTTP2_NV_FLAG_NONE } struct app_context; typedef struct app_context app_context; diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h index ba4729ef..05ee18bb 100644 --- a/lib/includes/nghttp2/nghttp2.h +++ b/lib/includes/nghttp2/nghttp2.h @@ -346,6 +346,22 @@ typedef enum { NGHTTP2_MSG_MORE } nghttp2_io_flag; +/** + * @enum + * + * The flags for header field name/value pair. + */ +typedef enum { + /** + * No flag set. + */ + NGHTTP2_NV_FLAG_NONE = 0, + /** + * Indicates that this name/value pair must not be indexed. + */ + NGHTTP2_NV_FLAG_NO_INDEX = 0x1 +} nghttp2_nv_flag; + /** * @struct * @@ -370,6 +386,10 @@ typedef struct { * The length of the |value|. */ uint16_t valuelen; + /** + * Bitwise OR of one or more of :type:`nghttp2_nv_flag`. + */ + uint8_t flags; } nghttp2_nv; /** diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index 621d63f6..19dff3ad 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -919,6 +919,8 @@ ssize_t nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, data = (uint8_t*)(*nva_ptr) + sizeof(nghttp2_nv)*nvlen; for(i = 0; i < nvlen; ++i) { + p->flags = nva[i].flags; + memcpy(data, nva[i].name, nva[i].namelen); p->name = data; p->namelen = nva[i].namelen; diff --git a/lib/nghttp2_hd.c b/lib/nghttp2_hd.c index fdb28538..96104473 100644 --- a/lib/nghttp2_hd.c +++ b/lib/nghttp2_hd.c @@ -34,7 +34,7 @@ /* Make scalar initialization form of nghttp2_nv */ #define MAKE_STATIC_ENT(I, N, V, NH, VH) \ - { { { (uint8_t*)N, (uint8_t*)V, sizeof(N) - 1, sizeof(V) - 1 }, \ + { { { (uint8_t*)N, (uint8_t*)V, sizeof(N) - 1, sizeof(V) - 1, 0 }, \ NH, VH, 1, NGHTTP2_HD_FLAG_NONE }, I } /* Sorted by hash(name) and its table index */ @@ -144,6 +144,11 @@ int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags, uint8_t *value, uint16_t valuelen) { int rv = 0; + + /* Since nghttp2_hd_entry is used for indexing, ent->nv.flags always + NGHTTP2_NV_FLAG_NONE */ + ent->nv.flags = NGHTTP2_NV_FLAG_NONE; + if((flags & NGHTTP2_HD_FLAG_NAME_ALLOC) && (flags & NGHTTP2_HD_FLAG_NAME_GIFT) == 0) { if(namelen == 0) { @@ -1402,6 +1407,9 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater, return NGHTTP2_ERR_NOMEM; } + /* Set NGHTTP2_NV_FLAG_NO_INDEX if never indexing repr is used */ + nv.flags = NGHTTP2_NV_FLAG_NONE; + if(inflater->index_required) { nghttp2_hd_entry *new_ent; uint8_t ent_flags; @@ -1455,6 +1463,9 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater, return NGHTTP2_ERR_NOMEM; } + /* Set NGHTTP2_NV_FLAG_NO_INDEX if never indexing repr is used */ + nv.flags = NGHTTP2_NV_FLAG_NONE; + nv.name = inflater->ent_name->nv.name; nv.namelen = inflater->ent_name->nv.namelen; diff --git a/src/http2.cc b/src/http2.cc index 0feb4b4c..8f5a8252 100644 --- a/src/http2.cc +++ b/src/http2.cc @@ -341,7 +341,8 @@ nghttp2_nv make_nv(const std::string& name, const std::string& value) return { (uint8_t*)name.c_str(), (uint8_t*)value.c_str(), - (uint16_t)name.size(), (uint16_t)value.size() + (uint16_t)name.size(), (uint16_t)value.size(), + NGHTTP2_NV_FLAG_NONE }; } diff --git a/src/http2.h b/src/http2.h index 901541f1..1648e33f 100644 --- a/src/http2.h +++ b/src/http2.h @@ -130,7 +130,8 @@ template nghttp2_nv make_nv_ll(const char(&name)[N], const char(&value)[M]) { return { (uint8_t*)name, (uint8_t*)value, - (uint16_t)(N - 1), (uint16_t)(M - 1) }; + (uint16_t)(N - 1), (uint16_t)(M - 1), + NGHTTP2_NV_FLAG_NONE }; } // Create nghttp2_nv from string literal |name| and c-string |value|. @@ -138,7 +139,8 @@ template nghttp2_nv make_nv_lc(const char(&name)[N], const char *value) { return { (uint8_t*)name, (uint8_t*)value, - (uint16_t)(N - 1), (uint16_t)strlen(value) }; + (uint16_t)(N - 1), (uint16_t)strlen(value), + NGHTTP2_NV_FLAG_NONE }; } // Create nghttp2_nv from string literal |name| and std::string @@ -147,7 +149,8 @@ template nghttp2_nv make_nv_ls(const char(&name)[N], const std::string& value) { return { (uint8_t*)name, (uint8_t*)value.c_str(), - (uint16_t)(N - 1), (uint16_t)value.size() }; + (uint16_t)(N - 1), (uint16_t)value.size(), + NGHTTP2_NV_FLAG_NONE }; } // Appends headers in |headers| to |nv|. Certain headers, including diff --git a/src/http2_test.cc b/src/http2_test.cc index de74ceea..0c568113 100644 --- a/src/http2_test.cc +++ b/src/http2_test.cc @@ -38,7 +38,8 @@ using namespace nghttp2; #define MAKE_NV(K, V) {(uint8_t*)K, (uint8_t*)V, \ - (uint16_t)(sizeof(K)-1), (uint16_t)(sizeof(V)-1)} + (uint16_t)(sizeof(K)-1), (uint16_t)(sizeof(V)-1), \ + NGHTTP2_NV_FLAG_NONE } namespace shrpx { diff --git a/tests/nghttp2_test_helper.h b/tests/nghttp2_test_helper.h index 204b0d9d..956a0cd9 100644 --- a/tests/nghttp2_test_helper.h +++ b/tests/nghttp2_test_helper.h @@ -34,7 +34,8 @@ #include "nghttp2_session.h" #define MAKE_NV(NAME, VALUE) \ - { (uint8_t*)NAME, (uint8_t*)VALUE, strlen(NAME), strlen(VALUE) } + { (uint8_t*)NAME, (uint8_t*)VALUE, strlen(NAME), strlen(VALUE), \ + NGHTTP2_NV_FLAG_NONE } #define ARRLEN(ARR) (sizeof(ARR)/sizeof(ARR[0])) #define assert_nv_equal(A, B, len) \