@@ -851,7 +851,7 @@ ssize_t Http2Session::OnCallbackPadding(size_t frameLen,
851851 buffer[PADDING_BUF_FRAME_LENGTH] = frameLen;
852852 buffer[PADDING_BUF_MAX_PAYLOAD_LENGTH] = maxPayloadLen;
853853 buffer[PADDING_BUF_RETURN_VALUE] = frameLen;
854- MakeCallback (env ()->ongetpadding_string (), 0 , nullptr );
854+ MakeCallback (env ()->http2session_on_select_padding_function (), 0 , nullptr );
855855 uint32_t retval = buffer[PADDING_BUF_RETURN_VALUE];
856856 retval = std::min (retval, static_cast <uint32_t >(maxPayloadLen));
857857 retval = std::max (retval, static_cast <uint32_t >(frameLen));
@@ -1017,7 +1017,7 @@ int Http2Session::OnInvalidFrame(nghttp2_session* handle,
10171017 Local<Context> context = env->context ();
10181018 Context::Scope context_scope (context);
10191019 Local<Value> arg = Integer::New (isolate, lib_error_code);
1020- session->MakeCallback (env->error_string (), 1 , &arg);
1020+ session->MakeCallback (env->http2session_on_error_function (), 1 , &arg);
10211021 }
10221022 return 0 ;
10231023}
@@ -1054,7 +1054,9 @@ int Http2Session::OnFrameNotSent(nghttp2_session* handle,
10541054 Integer::New (isolate, frame->hd .type ),
10551055 Integer::New (isolate, error_code)
10561056 };
1057- session->MakeCallback (env->onframeerror_string (), arraysize (argv), argv);
1057+ session->MakeCallback (
1058+ env->http2session_on_frame_error_function (),
1059+ arraysize (argv), argv);
10581060 return 0 ;
10591061}
10601062
@@ -1085,22 +1087,19 @@ int Http2Session::OnStreamClose(nghttp2_session* handle,
10851087 return 0 ;
10861088
10871089 stream->Close (code);
1090+
10881091 // It is possible for the stream close to occur before the stream is
1089- // ever passed on to the javascript side. If that happens, skip straight
1090- // to destroying the stream. We can check this by looking for the
1091- // onstreamclose function. If it exists, then the stream has already
1092- // been passed on to javascript.
1093- Local<Value> fn =
1094- stream-> object ()-> Get (context, env-> onstreamclose_string ())
1095- . ToLocalChecked ();
1096-
1097- if (!fn-> IsFunction ()) {
1092+ // ever passed on to the javascript side. If that happens, the callback
1093+ // will return false.
1094+ Local<Value> arg = Integer::NewFromUnsigned (isolate, code);
1095+ MaybeLocal<Value> answer =
1096+ stream-> MakeCallback (env-> http2session_on_stream_close_function (),
1097+ 1 , &arg);
1098+ if (answer. IsEmpty () ||
1099+ !(answer. ToLocalChecked ()-> BooleanValue (env-> context ()). FromJust ())) {
1100+ // Skip to destroy
10981101 stream->Destroy ();
1099- return 0 ;
11001102 }
1101-
1102- Local<Value> arg = Integer::NewFromUnsigned (isolate, code);
1103- stream->MakeCallback (fn.As <Function>(), 1 , &arg);
11041103 return 0 ;
11051104}
11061105
@@ -1233,7 +1232,7 @@ int Http2Session::OnNghttpError(nghttp2_session* handle,
12331232 Local<Context> context = env->context ();
12341233 Context::Scope context_scope (context);
12351234 Local<Value> arg = Integer::New (isolate, NGHTTP2_ERR_PROTO);
1236- session->MakeCallback (env->error_string (), 1 , &arg);
1235+ session->MakeCallback (env->http2session_on_error_function (), 1 , &arg);
12371236 }
12381237 return 0 ;
12391238}
@@ -1317,7 +1316,8 @@ void Http2Session::HandleHeadersFrame(const nghttp2_frame* frame) {
13171316 Integer::New (isolate, stream->headers_category ()),
13181317 Integer::New (isolate, frame->hd .flags ),
13191318 Array::New (isolate, headers_v.data (), headers_size * 2 )};
1320- MakeCallback (env ()->onheaders_string (), arraysize (args), args);
1319+ MakeCallback (env ()->http2session_on_headers_function (),
1320+ arraysize (args), args);
13211321}
13221322
13231323
@@ -1343,7 +1343,8 @@ void Http2Session::HandlePriorityFrame(const nghttp2_frame* frame) {
13431343 Integer::New (isolate, spec.weight ),
13441344 Boolean::New (isolate, spec.exclusive )
13451345 };
1346- MakeCallback (env ()->onpriority_string (), arraysize (argv), argv);
1346+ MakeCallback (env ()->http2session_on_priority_function (),
1347+ arraysize (argv), argv);
13471348}
13481349
13491350
@@ -1383,7 +1384,8 @@ void Http2Session::HandleGoawayFrame(const nghttp2_frame* frame) {
13831384 length).ToLocalChecked ();
13841385 }
13851386
1386- MakeCallback (env ()->ongoawaydata_string (), arraysize (argv), argv);
1387+ MakeCallback (env ()->http2session_on_goaway_data_function (),
1388+ arraysize (argv), argv);
13871389}
13881390
13891391// Called by OnFrameReceived when a complete ALTSVC frame has been received.
@@ -1411,7 +1413,8 @@ void Http2Session::HandleAltSvcFrame(const nghttp2_frame* frame) {
14111413 altsvc->field_value_len ).ToLocalChecked (),
14121414 };
14131415
1414- MakeCallback (env ()->onaltsvc_string (), arraysize (argv), argv);
1416+ MakeCallback (env ()->http2session_on_altsvc_function (),
1417+ arraysize (argv), argv);
14151418}
14161419
14171420void Http2Session::HandleOriginFrame (const nghttp2_frame* frame) {
@@ -1436,7 +1439,7 @@ void Http2Session::HandleOriginFrame(const nghttp2_frame* frame) {
14361439 .ToLocalChecked ();
14371440 }
14381441 Local<Value> holder = Array::New (isolate, origin_v.data (), origin_v.size ());
1439- MakeCallback (env ()->onorigin_string (), 1 , &holder);
1442+ MakeCallback (env ()->http2session_on_origin_function (), 1 , &holder);
14401443}
14411444
14421445// Called by OnFrameReceived when a complete PING frame has been received.
@@ -1457,7 +1460,7 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) {
14571460 // is buggy or malicious, and we're not going to tolerate such
14581461 // nonsense.
14591462 arg = Integer::New (isolate, NGHTTP2_ERR_PROTO);
1460- MakeCallback (env ()->error_string (), 1 , &arg);
1463+ MakeCallback (env ()->http2session_on_error_function (), 1 , &arg);
14611464 return ;
14621465 }
14631466
@@ -1469,15 +1472,15 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) {
14691472 arg = Buffer::Copy (env (),
14701473 reinterpret_cast <const char *>(frame->ping .opaque_data ),
14711474 8 ).ToLocalChecked ();
1472- MakeCallback (env ()->onping_string (), 1 , &arg);
1475+ MakeCallback (env ()->http2session_on_ping_function (), 1 , &arg);
14731476}
14741477
14751478// Called by OnFrameReceived when a complete SETTINGS frame has been received.
14761479void Http2Session::HandleSettingsFrame (const nghttp2_frame* frame) {
14771480 bool ack = frame->hd .flags & NGHTTP2_FLAG_ACK;
14781481 if (!ack) {
14791482 // This is not a SETTINGS acknowledgement, notify and return
1480- MakeCallback (env ()->onsettings_string (), 0 , nullptr );
1483+ MakeCallback (env ()->http2session_on_settings_function (), 0 , nullptr );
14811484 return ;
14821485 }
14831486
@@ -1502,7 +1505,7 @@ void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) {
15021505 Local<Context> context = env ()->context ();
15031506 Context::Scope context_scope (context);
15041507 Local<Value> arg = Integer::New (isolate, NGHTTP2_ERR_PROTO);
1505- MakeCallback (env ()->error_string (), 1 , &arg);
1508+ MakeCallback (env ()->http2session_on_error_function (), 1 , &arg);
15061509}
15071510
15081511// Callback used when data has been written to the stream.
@@ -1827,7 +1830,7 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
18271830 if (UNLIKELY (ret < 0 )) {
18281831 Debug (this , " fatal error receiving data: %d" , ret);
18291832 Local<Value> arg = Integer::New (isolate, ret);
1830- MakeCallback (env ()->error_string (), 1 , &arg);
1833+ MakeCallback (env ()->http2session_on_error_function (), 1 , &arg);
18311834 return ;
18321835 }
18331836
@@ -2032,7 +2035,7 @@ void Http2Stream::OnTrailers() {
20322035 Local<Context> context = env ()->context ();
20332036 Context::Scope context_scope (context);
20342037 flags_ &= ~NGHTTP2_STREAM_FLAG_TRAILERS;
2035- MakeCallback (env ()->ontrailers_string (), 0 , nullptr );
2038+ MakeCallback (env ()->http2session_on_stream_trailers_function (), 0 , nullptr );
20362039}
20372040
20382041// Submit informational headers for a stream.
@@ -2898,6 +2901,29 @@ void nghttp2_header::MemoryInfo(MemoryTracker* tracker) const {
28982901 tracker->TrackFieldWithSize (" value" , nghttp2_rcbuf_get_buf (value).len );
28992902}
29002903
2904+ void SetCallbackFunctions (const FunctionCallbackInfo<Value>& args) {
2905+ Environment* env = Environment::GetCurrent (args);
2906+ CHECK_EQ (args.Length (), 12 );
2907+
2908+ #define SET_FUNCTION (arg, name ) \
2909+ CHECK (args[arg]->IsFunction ()); \
2910+ env->set_http2session_on_ ## name ## _function (args[arg].As <Function>());
2911+
2912+ SET_FUNCTION (0 , error)
2913+ SET_FUNCTION (1 , priority)
2914+ SET_FUNCTION (2 , settings)
2915+ SET_FUNCTION (3 , ping)
2916+ SET_FUNCTION (4 , headers)
2917+ SET_FUNCTION (5 , frame_error)
2918+ SET_FUNCTION (6 , goaway_data)
2919+ SET_FUNCTION (7 , altsvc)
2920+ SET_FUNCTION (8 , origin)
2921+ SET_FUNCTION (9 , select_padding)
2922+ SET_FUNCTION (10 , stream_trailers)
2923+ SET_FUNCTION (11 , stream_close)
2924+
2925+ #undef SET_FUNCTION
2926+ }
29012927
29022928// Set up the process.binding('http2') binding.
29032929void Initialize (Local<Object> target,
@@ -3106,6 +3132,7 @@ HTTP_STATUS_CODES(V)
31063132
31073133 env->SetMethod (target, " refreshDefaultSettings" , RefreshDefaultSettings);
31083134 env->SetMethod (target, " packSettings" , PackSettings);
3135+ env->SetMethod (target, " setCallbackFunctions" , SetCallbackFunctions);
31093136
31103137 target->Set (context,
31113138 env->constants_string (),
0 commit comments