http2: Use std::array for indexing headers

This commit is contained in:
Tatsuhiro Tsujikawa 2015-02-05 23:06:56 +09:00
parent 6774fa6e07
commit f8f9b36acd
7 changed files with 30 additions and 24 deletions

View File

@ -84,7 +84,7 @@ struct Stream {
int64_t upload_left; int64_t upload_left;
int32_t stream_id; int32_t stream_id;
int file; int file;
int hdidx[http2::HD_MAXIDX]; http2::HeaderIndex hdidx;
Stream(Http2Handler *handler, int32_t stream_id); Stream(Http2Handler *handler, int32_t stream_id);
~Stream(); ~Stream();
}; };

View File

@ -593,9 +593,11 @@ int lookup_token(const uint8_t *name, size_t namelen) {
return -1; return -1;
} }
void init_hdidx(int *hdidx) { memset(hdidx, -1, sizeof(hdidx[0]) * HD_MAXIDX); } void init_hdidx(HeaderIndex &hdidx) {
std::fill(std::begin(hdidx), std::end(hdidx), -1);
}
void index_headers(int *hdidx, const Headers &headers) { void index_headers(HeaderIndex &hdidx, const Headers &headers) {
for (size_t i = 0; i < headers.size(); ++i) { for (size_t i = 0; i < headers.size(); ++i) {
auto &kv = headers[i]; auto &kv = headers[i];
auto token = lookup_token( auto token = lookup_token(
@ -606,7 +608,7 @@ void index_headers(int *hdidx, const Headers &headers) {
} }
} }
void index_header(int *hdidx, int token, size_t idx) { void index_header(HeaderIndex &hdidx, int token, size_t idx) {
if (token == -1) { if (token == -1) {
return; return;
} }
@ -614,7 +616,7 @@ void index_header(int *hdidx, int token, size_t idx) {
hdidx[token] = idx; hdidx[token] = idx;
} }
bool check_http2_request_pseudo_header(const int *hdidx, int token) { bool check_http2_request_pseudo_header(const HeaderIndex &hdidx, int token) {
switch (token) { switch (token) {
case HD__AUTHORITY: case HD__AUTHORITY:
case HD__METHOD: case HD__METHOD:
@ -626,7 +628,7 @@ bool check_http2_request_pseudo_header(const int *hdidx, int token) {
} }
} }
bool check_http2_response_pseudo_header(const int *hdidx, int token) { bool check_http2_response_pseudo_header(const HeaderIndex &hdidx, int token) {
switch (token) { switch (token) {
case HD__STATUS: case HD__STATUS:
return hdidx[token] == -1; return hdidx[token] == -1;
@ -648,7 +650,7 @@ bool http2_header_allowed(int token) {
} }
} }
bool http2_mandatory_request_headers_presence(const int *hdidx) { bool http2_mandatory_request_headers_presence(const HeaderIndex &hdidx) {
if (hdidx[HD__METHOD] == -1 || hdidx[HD__PATH] == -1 || if (hdidx[HD__METHOD] == -1 || hdidx[HD__PATH] == -1 ||
hdidx[HD__SCHEME] == -1 || hdidx[HD__SCHEME] == -1 ||
(hdidx[HD__AUTHORITY] == -1 && hdidx[HD_HOST] == -1)) { (hdidx[HD__AUTHORITY] == -1 && hdidx[HD_HOST] == -1)) {
@ -657,7 +659,7 @@ bool http2_mandatory_request_headers_presence(const int *hdidx) {
return true; return true;
} }
const Headers::value_type *get_header(const int *hdidx, int token, const Headers::value_type *get_header(const HeaderIndex &hdidx, int token,
const Headers &nva) { const Headers &nva) {
auto i = hdidx[token]; auto i = hdidx[token];
if (i == -1) { if (i == -1) {

View File

@ -31,6 +31,7 @@
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <vector> #include <vector>
#include <array>
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@ -210,6 +211,8 @@ enum {
HD_MAXIDX, HD_MAXIDX,
}; };
using HeaderIndex = std::array<int, HD_MAXIDX>;
// Looks up header token for header name |name| of length |namelen|. // Looks up header token for header name |name| of length |namelen|.
// Only headers we are interested in are tokenized. If header name // Only headers we are interested in are tokenized. If header name
// cannot be tokenized, returns -1. // cannot be tokenized, returns -1.
@ -218,19 +221,19 @@ int lookup_token(const std::string &name);
// Initializes |hdidx|, header index. The |hdidx| must point to the // Initializes |hdidx|, header index. The |hdidx| must point to the
// array containing at least HD_MAXIDX elements. // array containing at least HD_MAXIDX elements.
void init_hdidx(int *hdidx); void init_hdidx(HeaderIndex &hdidx);
// Indexes header |token| using index |idx|. // Indexes header |token| using index |idx|.
void index_header(int *hdidx, int token, size_t idx); void index_header(HeaderIndex &hdidx, int token, size_t idx);
// Iterates |headers| and for each element, call index_header. // Iterates |headers| and for each element, call index_header.
void index_headers(int *hdidx, const Headers &headers); void index_headers(HeaderIndex &hdidx, const Headers &headers);
// Returns true if HTTP/2 request pseudo header |token| is not indexed // Returns true if HTTP/2 request pseudo header |token| is not indexed
// yet and not -1. // yet and not -1.
bool check_http2_request_pseudo_header(const int *hdidx, int token); bool check_http2_request_pseudo_header(const HeaderIndex &hdidx, int token);
// Returns true if HTTP/2 response pseudo header |token| is not // Returns true if HTTP/2 response pseudo header |token| is not
// indexed yet and not -1. // indexed yet and not -1.
bool check_http2_response_pseudo_header(const int *hdidx, int token); bool check_http2_response_pseudo_header(const HeaderIndex &hdidx, int token);
// Returns true if header field denoted by |token| is allowed for // Returns true if header field denoted by |token| is allowed for
// HTTP/2. // HTTP/2.
@ -238,10 +241,10 @@ bool http2_header_allowed(int token);
// Returns true that |hdidx| contains mandatory HTTP/2 request // Returns true that |hdidx| contains mandatory HTTP/2 request
// headers. // headers.
bool http2_mandatory_request_headers_presence(const int *hdidx); bool http2_mandatory_request_headers_presence(const HeaderIndex &hdidx);
// Returns header denoted by |token| using index |hdidx|. // Returns header denoted by |token| using index |hdidx|.
const Headers::value_type *get_header(const int *hdidx, int token, const Headers::value_type *get_header(const HeaderIndex &hdidx, int token,
const Headers &nva); const Headers &nva);
} // namespace http2 } // namespace http2

View File

@ -120,7 +120,7 @@ void test_http2_get_header(void) {
rv = http2::get_header(nva, "foxtrot"); rv = http2::get_header(nva, "foxtrot");
CU_ASSERT(rv == nullptr); CU_ASSERT(rv == nullptr);
int hdidx[http2::HD_MAXIDX]; http2::HeaderIndex hdidx;
http2::init_hdidx(hdidx); http2::init_hdidx(hdidx);
hdidx[http2::HD_CONTENT_LENGTH] = 6; hdidx[http2::HD_CONTENT_LENGTH] = 6;
rv = http2::get_header(hdidx, http2::HD_CONTENT_LENGTH, nva); rv = http2::get_header(hdidx, http2::HD_CONTENT_LENGTH, nva);
@ -227,7 +227,7 @@ void test_http2_parse_http_status_code(void) {
} }
void test_http2_index_header(void) { void test_http2_index_header(void) {
int hdidx[http2::HD_MAXIDX]; http2::HeaderIndex hdidx;
http2::init_hdidx(hdidx); http2::init_hdidx(hdidx);
http2::index_header(hdidx, http2::HD__AUTHORITY, 0); http2::index_header(hdidx, http2::HD__AUTHORITY, 0);
@ -244,7 +244,7 @@ void test_http2_lookup_token(void) {
} }
void test_http2_check_http2_pseudo_header(void) { void test_http2_check_http2_pseudo_header(void) {
int hdidx[http2::HD_MAXIDX]; http2::HeaderIndex hdidx;
http2::init_hdidx(hdidx); http2::init_hdidx(hdidx);
CU_ASSERT(http2::check_http2_request_pseudo_header(hdidx, http2::HD__METHOD)); CU_ASSERT(http2::check_http2_request_pseudo_header(hdidx, http2::HD__METHOD));
@ -272,7 +272,7 @@ void test_http2_http2_header_allowed(void) {
} }
void test_http2_mandatory_request_headers_presence(void) { void test_http2_mandatory_request_headers_presence(void) {
int hdidx[http2::HD_MAXIDX]; http2::HeaderIndex hdidx;
http2::init_hdidx(hdidx); http2::init_hdidx(hdidx);
CU_ASSERT(!http2::http2_mandatory_request_headers_presence(hdidx)); CU_ASSERT(!http2::http2_mandatory_request_headers_presence(hdidx));

View File

@ -153,9 +153,9 @@ struct Request {
int level; int level;
// RequestPriority value defined in HtmlParser.h // RequestPriority value defined in HtmlParser.h
int pri; int pri;
int res_hdidx[http2::HD_MAXIDX]; http2::HeaderIndex res_hdidx;
// used for incoming PUSH_PROMISE // used for incoming PUSH_PROMISE
int req_hdidx[http2::HD_MAXIDX]; http2::HeaderIndex req_hdidx;
bool expect_final_response; bool expect_final_response;
}; };

View File

@ -288,7 +288,8 @@ const std::string &Downstream::get_assembled_request_cookie() const {
} }
namespace { namespace {
int index_headers(int *hdidx, Headers &headers, int64_t &content_length) { int index_headers(http2::HeaderIndex &hdidx, Headers &headers,
int64_t &content_length) {
for (size_t i = 0; i < headers.size(); ++i) { for (size_t i = 0; i < headers.size(); ++i) {
auto &kv = headers[i]; auto &kv = headers[i];
util::inp_strlower(kv.name); util::inp_strlower(kv.name);

View File

@ -362,8 +362,8 @@ private:
int response_major_; int response_major_;
int response_minor_; int response_minor_;
int request_hdidx_[http2::HD_MAXIDX]; http2::HeaderIndex request_hdidx_;
int response_hdidx_[http2::HD_MAXIDX]; http2::HeaderIndex response_hdidx_;
// true if the request contains upgrade token (HTTP Upgrade or // true if the request contains upgrade token (HTTP Upgrade or
// CONNECT) // CONNECT)