From 17032010845f257a830ec6ba07961c5e75527d5b Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 20 Feb 2016 19:02:19 +0900 Subject: [PATCH] nghttpx: Get rid of hdidx --- src/shrpx_downstream.cc | 81 +++++++++++++------------ src/shrpx_downstream.h | 6 +- src/shrpx_http_downstream_connection.cc | 4 +- src/shrpx_https_upstream.cc | 4 +- src/shrpx_spdy_upstream.cc | 5 +- 5 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/shrpx_downstream.cc b/src/shrpx_downstream.cc index 8f8165b7..71a0a2b6 100644 --- a/src/shrpx_downstream.cc +++ b/src/shrpx_downstream.cc @@ -237,15 +237,15 @@ void Downstream::force_resume_read() { } namespace { -const Headers::value_type *search_header_linear(const Headers &headers, - const StringRef &name) { - const Headers::value_type *res = nullptr; - for (auto &kv : headers) { +const Headers::value_type * +search_header_linear_backwards(const Headers &headers, const StringRef &name) { + for (auto it = headers.rbegin(); it != headers.rend(); ++it) { + auto &kv = *it; if (kv.name == name) { - res = &kv; + return &kv; } } - return res; + return nullptr; } } // namespace @@ -330,10 +330,10 @@ void Downstream::crumble_request_cookie(std::vector &nva) { namespace { void add_header(bool &key_prev, size_t &sum, Headers &headers, std::string name, - std::string value) { + std::string value, int16_t token = -1) { key_prev = true; sum += name.size() + value.size(); - headers.emplace_back(std::move(name), std::move(value)); + headers.emplace_back(std::move(name), std::move(value), false, token); } } // namespace @@ -356,6 +356,8 @@ void append_last_header_key(bool &key_prev, size_t &sum, Headers &headers, sum += len; auto &item = headers.back(); item.name.append(data, len); + util::inp_strlower(item.name); + item.token = http2::lookup_token(item.name); } } // namespace @@ -370,56 +372,58 @@ void append_last_header_value(bool &key_prev, size_t &sum, Headers &headers, } // namespace int FieldStore::index_headers() { - http2::init_hdidx(hdidx_); content_length = -1; - for (size_t i = 0; i < headers_.size(); ++i) { - auto &kv = headers_[i]; - util::inp_strlower(kv.name); - - auto token = http2::lookup_token( - reinterpret_cast(kv.name.c_str()), kv.name.size()); - if (token < 0) { + for (auto &kv : headers_) { + if (kv.token != http2::HD_CONTENT_LENGTH) { continue; } - kv.token = token; - http2::index_header(hdidx_, token, i); - - if (token == http2::HD_CONTENT_LENGTH) { - auto len = util::parse_uint(kv.value); - if (len == -1) { - return -1; - } - if (content_length != -1) { - return -1; - } - content_length = len; + auto len = util::parse_uint(kv.value); + if (len == -1) { + return -1; } + if (content_length != -1) { + return -1; + } + content_length = len; } return 0; } const Headers::value_type *FieldStore::header(int16_t token) const { - return http2::get_header(hdidx_, token, headers_); + for (auto it = headers_.rbegin(); it != headers_.rend(); ++it) { + auto &kv = *it; + if (kv.token == token) { + return &kv; + } + } + return nullptr; } Headers::value_type *FieldStore::header(int16_t token) { - return http2::get_header(hdidx_, token, headers_); + for (auto it = headers_.rbegin(); it != headers_.rend(); ++it) { + auto &kv = *it; + if (kv.token == token) { + return &kv; + } + } + return nullptr; } const Headers::value_type *FieldStore::header(const StringRef &name) const { - return search_header_linear(headers_, name); + return search_header_linear_backwards(headers_, name); } -void FieldStore::add_header(std::string name, std::string value) { +void FieldStore::add_header_lower(std::string name, std::string value) { + util::inp_strlower(name); + auto token = http2::lookup_token(name); shrpx::add_header(header_key_prev_, buffer_size_, headers_, std::move(name), - std::move(value)); + std::move(value), token); } void FieldStore::add_header(std::string name, std::string value, int16_t token) { - http2::index_header(hdidx_, token, headers_.size()); buffer_size_ += name.size() + value.size(); headers_.emplace_back(std::move(name), std::move(value), false, token); } @@ -427,7 +431,6 @@ void FieldStore::add_header(std::string name, std::string value, void FieldStore::add_header(const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, bool no_index, int16_t token) { - http2::index_header(hdidx_, token, headers_.size()); shrpx::add_header(buffer_size_, headers_, name, namelen, value, valuelen, no_index, token); } @@ -442,10 +445,7 @@ void FieldStore::append_last_header_value(const char *data, size_t len) { data, len); } -void FieldStore::clear_headers() { - headers_.clear(); - http2::init_hdidx(hdidx_); -} +void FieldStore::clear_headers() { headers_.clear(); } void FieldStore::add_trailer(const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, @@ -456,7 +456,8 @@ void FieldStore::add_trailer(const uint8_t *name, size_t namelen, no_index, -1); } -void FieldStore::add_trailer(std::string name, std::string value) { +void FieldStore::add_trailer_lower(std::string name, std::string value) { + util::inp_strlower(name); shrpx::add_header(trailer_key_prev_, buffer_size_, trailers_, std::move(name), std::move(value)); } diff --git a/src/shrpx_downstream.h b/src/shrpx_downstream.h index a1f32760..4132e905 100644 --- a/src/shrpx_downstream.h +++ b/src/shrpx_downstream.h @@ -56,7 +56,6 @@ public: buffer_size_(0), header_key_prev_(false), trailer_key_prev_(false) { - http2::init_hdidx(hdidx_); headers_.reserve(headers_initial_capacity); } @@ -80,7 +79,7 @@ public: // such header is found, returns nullptr. const Headers::value_type *header(const StringRef &name) const; - void add_header(std::string name, std::string value); + void add_header_lower(std::string name, std::string value); void add_header(std::string name, std::string value, int16_t token); void add_header(const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, bool no_index, int16_t token); @@ -100,7 +99,7 @@ public: void add_trailer(const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, bool no_index, int16_t token); - void add_trailer(std::string name, std::string value); + void add_trailer_lower(std::string name, std::string value); void append_last_trailer_key(const char *data, size_t len); void append_last_trailer_value(const char *data, size_t len); @@ -115,7 +114,6 @@ private: // trailer fields. For HTTP/1.1, trailer fields are only included // with chunked encoding. For HTTP/2, there is no such limit. Headers trailers_; - http2::HeaderIndex hdidx_; // Sum of the length of name and value in headers_ and trailers_. // This could also be increased by add_extra_buffer_size() to take // into account for request URI in case of HTTP/1.x request. diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index 8e2796a6..8b96e314 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -691,7 +691,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { if (ensure_max_header_fields(downstream, httpconf) != 0) { return -1; } - resp.fs.add_header(std::string(data, len), ""); + resp.fs.add_header_lower(std::string(data, len), ""); } } else { // trailer part @@ -704,7 +704,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { // wrong place or crash if trailer fields are currently empty. return -1; } - resp.fs.add_trailer(std::string(data, len), ""); + resp.fs.add_trailer_lower(std::string(data, len), ""); } } return 0; diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index c807e753..5875ac1b 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -142,7 +142,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE); return -1; } - req.fs.add_header(std::string(data, len), ""); + req.fs.add_header_lower(std::string(data, len), ""); } } else { // trailer part @@ -156,7 +156,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { } return -1; } - req.fs.add_trailer(std::string(data, len), ""); + req.fs.add_trailer_lower(std::string(data, len), ""); } } return 0; diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index ee80a144..27d768c2 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -188,7 +188,10 @@ void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type, } for (size_t i = 0; nv[i]; i += 2) { - req.fs.add_header(nv[i], nv[i + 1]); + auto name = std::string(nv[i]); + auto value = std::string(nv[i + 1]); + auto token = http2::lookup_token(name); + req.fs.add_header(std::move(name), std::move(value), token); } if (req.fs.index_headers() != 0) {