http2: refactor Http2Stream and inbound headers by jasnell · Pull Request #16676 · nodejs/node · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions doc/api/http2.md
8 changes: 7 additions & 1 deletion lib/internal/http2/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ const IDX_OPTIONS_MAX_RESERVED_REMOTE_STREAMS = 1;
const IDX_OPTIONS_MAX_SEND_HEADER_BLOCK_LENGTH = 2;
const IDX_OPTIONS_PEER_MAX_CONCURRENT_STREAMS = 3;
const IDX_OPTIONS_PADDING_STRATEGY = 4;
const IDX_OPTIONS_FLAGS = 5;
const IDX_OPTIONS_MAX_HEADER_LIST_PAIRS = 5;
const IDX_OPTIONS_FLAGS = 6;

function updateOptionsBuffer(options) {
var flags = 0;
Expand Down Expand Up @@ -201,6 +202,11 @@ function updateOptionsBuffer(options) {
optionsBuffer[IDX_OPTIONS_PADDING_STRATEGY] =
options.paddingStrategy;
}
if (typeof options.maxHeaderListPairs === 'number') {
flags |= (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS);
optionsBuffer[IDX_OPTIONS_MAX_HEADER_LIST_PAIRS] =
options.maxHeaderListPairs;
}
optionsBuffer[IDX_OPTIONS_FLAGS] = flags;
}

Expand Down
31 changes: 21 additions & 10 deletions src/node_http2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "node_http2_state.h"

#include <queue>
#include <algorithm>

namespace node {

Expand All @@ -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)};
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, this is … clever 😄

}


Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -936,18 +946,19 @@ 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++];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can’t this just be headers[--count]? I don’t think you really need the n if you didn’t need it before

// The header name and value are passed as external one-byte strings
name_str =
ExternalHeader::New<true>(env(), item.name).ToLocalChecked();
value_str =
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
Expand All @@ -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()),
Expand Down
25 changes: 12 additions & 13 deletions src/node_http2.h
Loading