diff options
author | James M Snell <jasnell@gmail.com> | 2017-11-01 11:48:11 -0700 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2017-11-04 22:32:44 -0700 |
commit | 9f3d59eabb6564ad337a762d61ac767f9130e8a5 (patch) | |
tree | a0fdb43c530be18d6ed5dded16378c6f30d91da6 /src/node_http2.cc | |
parent | 1f045f491a6a8d6ac193474f3856e2bdbd6847be (diff) | |
download | android-node-v8-9f3d59eabb6564ad337a762d61ac767f9130e8a5.tar.gz android-node-v8-9f3d59eabb6564ad337a762d61ac767f9130e8a5.tar.bz2 android-node-v8-9f3d59eabb6564ad337a762d61ac767f9130e8a5.zip |
http2: refactor multiple internals
* eliminate pooling of Nghttp2Stream instances. After testing,
the pooling is not having any tangible benefit
and makes things more complicated. Simplify. Simplify.
* refactor inbound headers
* Enforce MAX_HEADERS_LIST setting and limit the number of header
pairs accepted from the peer. Use the ENHANCE_YOUR_CALM error
code when receiving either too many headers or too many octets.
Use a vector to store the headers instead of a queue
PR-URL: https://github.com/nodejs/node/pull/16676
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_http2.cc')
-rw-r--r-- | src/node_http2.cc | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/src/node_http2.cc b/src/node_http2.cc index 8beaee0548..f9025d1fd3 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -5,6 +5,7 @@ #include "node_http2_state.h" #include <queue> +#include <algorithm> namespace node { @@ -20,8 +21,6 @@ using v8::Undefined; namespace http2 { -Freelist<Nghttp2Stream, FREELIST_MAX> stream_free_list; - Nghttp2Session::Callbacks Nghttp2Session::callback_struct_saved[2] = { Callbacks(false), Callbacks(true)}; @@ -67,6 +66,10 @@ Http2Options::Http2Options(Environment* env) { buffer.GetValue(IDX_OPTIONS_PADDING_STRATEGY)); SetPaddingStrategy(strategy); } + + if (flags & (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS)) { + SetMaxHeaderPairs(buffer[IDX_OPTIONS_MAX_HEADER_LIST_PAIRS]); + } } Http2Settings::Http2Settings(Environment* env) : env_(env) { @@ -173,11 +176,14 @@ inline void Http2Settings::RefreshDefaults(Environment* env) { DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE; buffer[IDX_SETTINGS_MAX_FRAME_SIZE] = DEFAULT_SETTINGS_MAX_FRAME_SIZE; + buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] = + DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE; buffer[IDX_SETTINGS_COUNT] = (1 << IDX_SETTINGS_HEADER_TABLE_SIZE) | (1 << IDX_SETTINGS_ENABLE_PUSH) | (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE) | - (1 << IDX_SETTINGS_MAX_FRAME_SIZE); + (1 << IDX_SETTINGS_MAX_FRAME_SIZE) | + (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE); } @@ -192,7 +198,10 @@ Http2Session::Http2Session(Environment* env, padding_strategy_ = opts.GetPaddingStrategy(); - Init(type, *opts); + int32_t maxHeaderPairs = opts.GetMaxHeaderPairs(); + maxHeaderPairs = type == NGHTTP2_SESSION_SERVER ? + std::max(maxHeaderPairs, 4) : std::max(maxHeaderPairs, 1); + Init(type, *opts, nullptr, maxHeaderPairs); // For every node::Http2Session instance, there is a uv_prepare_t handle // whose callback is triggered on every tick of the event loop. When @@ -911,7 +920,8 @@ void Http2Session::OnTrailers(Nghttp2Stream* stream, void Http2Session::OnHeaders( Nghttp2Stream* stream, - std::queue<nghttp2_header>* headers, + nghttp2_header* headers, + size_t count, nghttp2_headers_category cat, uint8_t flags) { Local<Context> context = env()->context(); @@ -936,10 +946,11 @@ void Http2Session::OnHeaders( // like {name1: value1, name2: value2, name3: [value3, value4]}. We do it // this way for performance reasons (it's faster to generate and pass an // array than it is to generate and pass the object). - do { + size_t n = 0; + while (count > 0) { size_t j = 0; - while (!headers->empty() && j < arraysize(argv) / 2) { - nghttp2_header item = headers->front(); + while (count > 0 && j < arraysize(argv) / 2) { + nghttp2_header item = headers[n++]; // The header name and value are passed as external one-byte strings name_str = ExternalHeader::New<true>(env(), item.name).ToLocalChecked(); @@ -947,7 +958,7 @@ void Http2Session::OnHeaders( ExternalHeader::New<false>(env(), item.value).ToLocalChecked(); argv[j * 2] = name_str; argv[j * 2 + 1] = value_str; - headers->pop(); + count--; j++; } // For performance, we pass name and value pairs to array.protototype.push @@ -956,7 +967,7 @@ void Http2Session::OnHeaders( if (j > 0) { fn->Call(env()->context(), holder, j * 2, argv).ToLocalChecked(); } - } while (!headers->empty()); + } Local<Value> args[4] = { Integer::New(isolate, stream->id()), |