Skip to content
This repository was archived by the owner on Jul 6, 2018. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
http2: add configured debug statements
Using `./configure --debug-http2` will enable verbose debug
statements from node.js,

Using `./configure --debug-nghttp2` will enable verbose debug
statements from nghttp2.

The two can be used together
  • Loading branch information
jasnell committed May 31, 2017
commit d6d0dffc904aba8a6d27e3d1c4e09969251ffc01
12 changes: 11 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,15 @@ intl_optgroup.add_option('--download-path',

parser.add_option_group(intl_optgroup)

http2_optgroup.add_option('--debug-http2',
action='store_true',
dest='debug_http2',
help='build with http2 debug statements on (default is false)')

http2_optgroup.add_option('--debug-nghttp2',
action='store_true',
dest='debug_nghttp2',
help='Build nghttp2 with DEBUGBUILD')
help='build nghttp2 with DEBUGBUILD (default is false)')

parser.add_option('--with-perfctr',
action='store_true',
Expand Down Expand Up @@ -898,6 +903,11 @@ def configure_node(o):
if options.enable_static:
o['variables']['node_target_type'] = 'static_library'

if options.debug_http2:
o['variables']['debug_http2'] = 1
else:
o['variables']['debug_http2'] = 'false'

if options.debug_nghttp2:
o['variables']['debug_nghttp2'] = 1
else:
Expand Down
4 changes: 4 additions & 0 deletions node.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
'NODE_RELEASE_URLBASE="<(node_release_urlbase)"',
]
}],
[
'debug_http2==1', {
'defines': [ 'NODE_DEBUG_HTTP2=1' ]
}],
[ 'v8_enable_i18n_support==1', {
'defines': [ 'NODE_HAVE_I18N_SUPPORT=1' ],
'dependencies': [
Expand Down
88 changes: 68 additions & 20 deletions src/node_http2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,13 @@ void Http2Session::OnFreeSession() {

ssize_t Http2Session::OnMaxFrameSizePadding(size_t frameLen,
size_t maxPayloadLen) {
DEBUG_HTTP2("Http2Session: using max frame size padding\n");
return maxPayloadLen;
}

ssize_t Http2Session::OnCallbackPadding(size_t frameLen,
size_t maxPayloadLen) {
DEBUG_HTTP2("Http2Session: using callback padding\n");
Isolate* isolate = env()->isolate();
Local<Context> context = env()->context();

Expand Down Expand Up @@ -146,7 +148,9 @@ void Http2Session::SetNextStreamID(const FunctionCallbackInfo<Value>& args) {
Http2Session* session;
ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());
nghttp2_session* s = session->session();
nghttp2_session_set_next_stream_id(s, args[0]->Int32Value());
int32_t id = args[0]->Int32Value();
DEBUG_HTTP2("Http2Session: setting next stream id to %d\n", id);
nghttp2_session_set_next_stream_id(s, id);
}

void HttpErrorString(const FunctionCallbackInfo<Value>& args) {
Expand Down Expand Up @@ -193,6 +197,7 @@ void PackSettings(const FunctionCallbackInfo<Value>& args) {

// Used to fill in the spec defined initial values for each setting.
void RefreshDefaultSettings(const FunctionCallbackInfo<Value>& args) {
DEBUG_HTTP2("Http2Session: refreshing default settings\n");
Environment* env = Environment::GetCurrent(args);
int32_t* const buffer = env->http2_default_settings_buffer();
buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
Expand All @@ -207,6 +212,7 @@ void RefreshDefaultSettings(const FunctionCallbackInfo<Value>& args) {

template <get_setting fn>
void RefreshSettings(const FunctionCallbackInfo<Value>& args) {
DEBUG_HTTP2("Http2Session: refreshing settings for session\n");
CHECK_EQ(args.Length(), 1);
CHECK(args[0]->IsObject());
Http2Session* session;
Expand All @@ -231,6 +237,7 @@ void RefreshSettings(const FunctionCallbackInfo<Value>& args) {

// Used to fill in the spec defined initial values for each setting.
void RefreshSessionState(const FunctionCallbackInfo<Value>& args) {
DEBUG_HTTP2("Http2Session: refreshing session state\n");
CHECK_EQ(args.Length(), 1);
CHECK(args[0]->IsObject());
Environment* env = Environment::GetCurrent(args);
Expand Down Expand Up @@ -263,9 +270,10 @@ void RefreshStreamState(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(args.Length(), 2);
CHECK(args[0]->IsObject());
CHECK(args[1]->IsNumber());
int32_t id = args[1]->Int32Value();
DEBUG_HTTP2("Http2Session: refreshing stream %d state\n", id);
Http2Session* session;
ASSIGN_OR_RETURN_UNWRAP(&session, args[0].As<Object>());
int32_t id = args[1]->Int32Value();
nghttp2_session* s = session->session();
Nghttp2Stream* stream;

Expand Down Expand Up @@ -313,7 +321,7 @@ void Http2Session::New(const FunctionCallbackInfo<Value>& args) {

nghttp2_session_type type =
static_cast<nghttp2_session_type>(args[0]->IntegerValue());

DEBUG_HTTP2("Http2Session: creating a session of type: %d\n", type);
new Http2Session(env, args.This(), type, args[1]);
}

Expand All @@ -327,6 +335,7 @@ void Http2Session::Consume(const FunctionCallbackInfo<Value>& args) {
}

void Http2Session::Destroy(const FunctionCallbackInfo<Value>& args) {
DEBUG_HTTP2("Http2Session: destroying session\n");
Http2Session* session;
ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());
session->Unconsume();
Expand All @@ -343,6 +352,9 @@ void Http2Session::SubmitPriority(const FunctionCallbackInfo<Value>& args) {
int32_t weight = args[2]->Int32Value();
bool exclusive = args[3]->BooleanValue();
bool silent = args[4]->BooleanValue();
DEBUG_HTTP2("Http2Session: submitting priority for stream %d: "
"parent: %d, weight: %d, exclusive: %d, silent: %d\n",
id, parent, weight, exclusive, silent);
CHECK_GT(id, 0);
CHECK_GE(parent, 0);
CHECK_GE(weight, 0);
Expand Down Expand Up @@ -394,13 +406,17 @@ void Http2Session::SubmitRstStream(const FunctionCallbackInfo<Value>& args) {
Http2Session* session;
ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());

int32_t id = args[0]->Int32Value();
uint32_t code = args[1]->Uint32Value();

Nghttp2Stream* stream;
if (!(stream = session->FindStream(args[0]->Int32Value()))) {
if (!(stream = session->FindStream(id))) {
// invalid stream
return args.GetReturnValue().Set(NGHTTP2_ERR_INVALID_STREAM_ID);
}
args.GetReturnValue().Set(
stream->SubmitRstStream(args[1]->Uint32Value()));
DEBUG_HTTP2("Http2Session: sending rst_stream for stream %d, code: %d\n",
id, code);
args.GetReturnValue().Set(stream->SubmitRstStream(code));
}

void Http2Session::SubmitRequest(const FunctionCallbackInfo<Value>& args) {
Expand All @@ -418,19 +434,24 @@ void Http2Session::SubmitRequest(const FunctionCallbackInfo<Value>& args) {

Local<Array> headers = args[0].As<Array>();
bool endStream = args[1]->BooleanValue();
int32_t parent_id = args[2]->Int32Value();
int32_t parent = args[2]->Int32Value();
int32_t weight = args[3]->Int32Value();
bool exclusive = args[4]->BooleanValue();

DEBUG_HTTP2("Http2Session: submitting request: headers: %d, end-stream: %d, "
"parent: %d, weight: %d, exclusive: %d", headers->Length(),
endStream, parent, weight, exclusive);

nghttp2_priority_spec prispec;
nghttp2_priority_spec_init(&prispec, parent_id, weight, exclusive ? 1 : 0);
nghttp2_priority_spec_init(&prispec, parent, weight, exclusive ? 1 : 0);

Headers list(isolate, headers);

args.GetReturnValue().Set(
session->Nghttp2Session::SubmitRequest(&prispec,
*list, list.length(),
nullptr, endStream));
int32_t ret = session->Nghttp2Session::SubmitRequest(&prispec,
*list, list.length(),
nullptr, endStream);
DEBUG_HTTP2("Http2Session: request submitted, response: %d\n", ret);
args.GetReturnValue().Set(ret);
}

void Http2Session::SubmitResponse(const FunctionCallbackInfo<Value>& args) {
Expand All @@ -444,10 +465,14 @@ void Http2Session::SubmitResponse(const FunctionCallbackInfo<Value>& args) {
Environment* env = session->env();
Isolate* isolate = env->isolate();

int32_t id = args[0]->Int32Value();
Local<Array> headers = args[1].As<Array>();
bool endStream = args[2]->BooleanValue();

if (!(stream = session->FindStream(args[0]->Int32Value()))) {
DEBUG_HTTP2("Http2Session: submitting response for stream %d: headers: %d, "
"end-stream: %d\n", id, headers->Length(), endStream);

if (!(stream = session->FindStream(id))) {
return args.GetReturnValue().Set(NGHTTP2_ERR_INVALID_STREAM_ID);
}

Expand All @@ -468,11 +493,16 @@ void Http2Session::SendHeaders(const FunctionCallbackInfo<Value>& args) {
Environment* env = session->env();
Isolate* isolate = env->isolate();

if (!(stream = session->FindStream(args[0]->Int32Value()))) {
int32_t id = args[0]->Int32Value();
Local<Array> headers = args[1].As<Array>();

DEBUG_HTTP2("Http2Session: sending informational headers for stream %d, "
"count: %d\n", id, headers->Length());

if (!(stream = session->FindStream(id))) {
return args.GetReturnValue().Set(NGHTTP2_ERR_INVALID_STREAM_ID);
}

Local<Array> headers = args[1].As<Array>();
Headers list(isolate, headers);

args.GetReturnValue().Set(stream->SubmitInfo(*list, list.length()));
Expand All @@ -483,7 +513,9 @@ void Http2Session::ShutdownStream(const FunctionCallbackInfo<Value>& args) {
Http2Session* session;
ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());
Nghttp2Stream* stream;
if (!(stream = session->FindStream(args[0]->Int32Value()))) {
int32_t id = args[0]->Int32Value();
DEBUG_HTTP2("Http2Session: shutting down stream %d\n", id);
if (!(stream = session->FindStream(id))) {
return args.GetReturnValue().Set(NGHTTP2_ERR_INVALID_STREAM_ID);
}
stream->Shutdown();
Expand Down Expand Up @@ -517,10 +549,16 @@ void Http2Session::StreamReadStop(const FunctionCallbackInfo<Value>& args) {
static void DoSessionShutdown(SessionShutdownWrap* req) {
int status;
if (req->graceful()) {
DEBUG_HTTP2("Http2Session: initiating graceful session shutdown. "
"last-stream-id: %d, code: %d\n",
req->lastStreamID(), req->errorCode());
status = nghttp2_session_terminate_session2(req->handle()->session(),
req->lastStreamID(),
req->errorCode());
} else {
DEBUG_HTTP2("Http2Session: initiating immediate shutdown. "
"last-stream-id: %d, code: %d, opaque-data: %d\n",
req->lastStreamID(), req->errorCode(), req->opaqueDataLength());
status = nghttp2_submit_goaway(req->handle()->session(),
NGHTTP2_FLAG_NONE,
req->lastStreamID(),
Expand Down Expand Up @@ -593,6 +631,7 @@ void Http2Session::DestroyStream(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(args.Length(), 1);
CHECK(args[0]->IsNumber());
int32_t id = args[0]->Int32Value();
DEBUG_HTTP2("Http2Session: destroy stream %d\n", id);
Nghttp2Stream* stream;
if (!(stream = session->FindStream(id))) {
return args.GetReturnValue().Set(NGHTTP2_ERR_INVALID_STREAM_ID);
Expand All @@ -610,17 +649,23 @@ void Http2Session::SubmitPushPromise(const FunctionCallbackInfo<Value>& args) {
CHECK(args[1]->IsArray()); // headers array

Nghttp2Stream* parent;
int32_t id = args[0]->Int32Value();
Local<Array> headers = args[1].As<Array>();
bool endStream = args[2]->BooleanValue();

if (!(parent = session->FindStream(args[0]->Int32Value()))) {
DEBUG_HTTP2("Http2Session: submitting push promise for stream %d: "
"end-stream: %d, headers: %d\n", id, endStream,
headers->Length());

if (!(parent = session->FindStream(id))) {
return args.GetReturnValue().Set(NGHTTP2_ERR_INVALID_STREAM_ID);
}

Local<Array> headers = args[1].As<Array>();
bool endStream = args[2]->BooleanValue();
Headers list(isolate, headers);

int32_t ret = parent->SubmitPushPromise(*list, list.length(),
nullptr, endStream);
DEBUG_HTTP2("Http2Session: push promise submitted, ret: %d\n", ret);
args.GetReturnValue().Set(ret);
}

Expand Down Expand Up @@ -674,7 +719,6 @@ void Http2Session::Send(uv_buf_t* buf, size_t length) {
if (stream_ == nullptr || !stream_->IsAlive() || stream_->IsClosing()) {
return;
}

HandleScope scope(env()->isolate());
SessionSendBuffer* req = ContainerOf(&SessionSendBuffer::buffer_, buf);
uv_buf_t actual = uv_buf_init(buf->base, length);
Expand All @@ -685,6 +729,8 @@ void Http2Session::Send(uv_buf_t* buf, size_t length) {

void Http2Session::OnTrailers(Nghttp2Stream* stream,
MaybeStackBuffer<nghttp2_nv>* trailers) {
DEBUG_HTTP2("Http2Session: prompting for trailers on stream %d\n",
stream->id());
Local<Context> context = env()->context();
Context::Scope context_scope(context);
Isolate* isolate = env()->isolate();
Expand Down Expand Up @@ -1020,6 +1066,7 @@ void Http2Session::OnStreamReadImpl(ssize_t nread,


void Http2Session::Consume(Local<External> external) {
DEBUG_HTTP2("Http2Session: consuming socket\n");
CHECK(prev_alloc_cb_.is_empty());
StreamBase* stream = static_cast<StreamBase*>(external->Value());
CHECK_NE(stream, nullptr);
Expand All @@ -1033,6 +1080,7 @@ void Http2Session::Consume(Local<External> external) {


void Http2Session::Unconsume() {
DEBUG_HTTP2("Http2Session: unconsuming socket\n");
if (prev_alloc_cb_.is_empty())
return;
stream_->set_alloc_cb(prev_alloc_cb_);
Expand Down
Loading