@@ -228,27 +228,18 @@ void Http2Session::Http2Settings::Init() {
228
228
count_ = n;
229
229
}
230
230
231
- Http2Session::Http2Settings::Http2Settings (Environment* env,
232
- Http2Session* session, uint64_t start_time)
233
- : AsyncWrap(env,
234
- env->http2settings_constructor_template ()
235
- ->NewInstance(env->context ())
236
- .ToLocalChecked(),
237
- PROVIDER_HTTP2SETTINGS),
238
- session_(session),
239
- startTime_(start_time) {
240
- Init ();
241
- }
242
-
243
-
244
- Http2Session::Http2Settings::Http2Settings (Environment* env)
245
- : Http2Settings(env, nullptr , 0 ) {}
246
-
247
231
// The Http2Settings class is used to configure a SETTINGS frame that is
248
232
// to be sent to the connected peer. The settings are set using a TypedArray
249
233
// that is shared with the JavaScript side.
250
- Http2Session::Http2Settings::Http2Settings (Http2Session* session)
251
- : Http2Settings(session->env (), session, uv_hrtime()) {}
234
+ Http2Session::Http2Settings::Http2Settings (Environment* env,
235
+ Http2Session* session,
236
+ Local<Object> obj,
237
+ uint64_t start_time)
238
+ : AsyncWrap(env, obj, PROVIDER_HTTP2SETTINGS),
239
+ session_ (session),
240
+ startTime_(start_time) {
241
+ Init ();
242
+ }
252
243
253
244
// Generates a Buffer that contains the serialized payload of a SETTINGS
254
245
// frame. This can be used, for instance, to create the Base64-encoded
@@ -916,13 +907,14 @@ int Http2Session::OnBeginHeadersCallback(nghttp2_session* handle,
916
907
// The common case is that we're creating a new stream. The less likely
917
908
// case is that we're receiving a set of trailers
918
909
if (LIKELY (stream == nullptr )) {
919
- if (UNLIKELY (!session->CanAddStream ())) {
910
+ if (UNLIKELY (!session->CanAddStream () ||
911
+ Http2Stream::New (session, id, frame->headers .cat ) ==
912
+ nullptr )) {
920
913
// Too many concurrent streams being opened
921
914
nghttp2_submit_rst_stream (**session, NGHTTP2_FLAG_NONE, id,
922
915
NGHTTP2_ENHANCE_YOUR_CALM);
923
916
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
924
917
}
925
- new Http2Stream (session, id, frame->headers .cat );
926
918
} else if (!stream->IsDestroyed ()) {
927
919
stream->StartHeaders (frame->headers .cat );
928
920
}
@@ -1789,7 +1781,7 @@ Http2Stream* Http2Session::SubmitRequest(
1789
1781
*ret = nghttp2_submit_request (session_, prispec, nva, len, *prov, nullptr );
1790
1782
CHECK_NE (*ret, NGHTTP2_ERR_NOMEM);
1791
1783
if (LIKELY (*ret > 0 ))
1792
- stream = new Http2Stream (this , *ret, NGHTTP2_HCAT_HEADERS, options);
1784
+ stream = Http2Stream::New (this , *ret, NGHTTP2_HCAT_HEADERS, options);
1793
1785
return stream;
1794
1786
}
1795
1787
@@ -1875,20 +1867,30 @@ void Http2Session::Consume(Local<External> external) {
1875
1867
Debug (this , " i/o stream consumed" );
1876
1868
}
1877
1869
1878
-
1879
- Http2Stream::Http2Stream (
1880
- Http2Session* session,
1881
- int32_t id,
1882
- nghttp2_headers_category category,
1883
- int options) : AsyncWrap(session->env (),
1884
- session->env()->http2stream_constructor_template()
1885
- ->NewInstance(session->env ()->context())
1886
- .ToLocalChecked(),
1887
- AsyncWrap::PROVIDER_HTTP2STREAM),
1888
- StreamBase(session->env ()),
1889
- session_(session),
1890
- id_(id),
1891
- current_headers_category_(category) {
1870
+ Http2Stream* Http2Stream::New (Http2Session* session,
1871
+ int32_t id,
1872
+ nghttp2_headers_category category,
1873
+ int options) {
1874
+ Local<Object> obj;
1875
+ if (!session->env ()
1876
+ ->http2stream_constructor_template ()
1877
+ ->NewInstance (session->env ()->context ())
1878
+ .ToLocal (&obj)) {
1879
+ return nullptr ;
1880
+ }
1881
+ return new Http2Stream (session, obj, id, category, options);
1882
+ }
1883
+
1884
+ Http2Stream::Http2Stream (Http2Session* session,
1885
+ Local<Object> obj,
1886
+ int32_t id,
1887
+ nghttp2_headers_category category,
1888
+ int options)
1889
+ : AsyncWrap(session->env (), obj, AsyncWrap::PROVIDER_HTTP2STREAM),
1890
+ StreamBase(session->env ()),
1891
+ session_(session),
1892
+ id_(id),
1893
+ current_headers_category_(category) {
1892
1894
MakeWeak ();
1893
1895
statistics_.start_time = uv_hrtime ();
1894
1896
@@ -2132,7 +2134,7 @@ Http2Stream* Http2Stream::SubmitPushPromise(nghttp2_nv* nva,
2132
2134
CHECK_NE (*ret, NGHTTP2_ERR_NOMEM);
2133
2135
Http2Stream* stream = nullptr ;
2134
2136
if (*ret > 0 )
2135
- stream = new Http2Stream (session_, *ret, NGHTTP2_HCAT_HEADERS, options);
2137
+ stream = Http2Stream::New (session_, *ret, NGHTTP2_HCAT_HEADERS, options);
2136
2138
2137
2139
return stream;
2138
2140
}
@@ -2354,7 +2356,14 @@ void HttpErrorString(const FunctionCallbackInfo<Value>& args) {
2354
2356
// output for an HTTP2-Settings header field.
2355
2357
void PackSettings (const FunctionCallbackInfo<Value>& args) {
2356
2358
Environment* env = Environment::GetCurrent (args);
2357
- Http2Session::Http2Settings settings (env);
2359
+ // TODO(addaleax): We should not be creating a full AsyncWrap for this.
2360
+ Local<Object> obj;
2361
+ if (!env->http2settings_constructor_template ()
2362
+ ->NewInstance (env->context ())
2363
+ .ToLocal (&obj)) {
2364
+ return ;
2365
+ }
2366
+ Http2Session::Http2Settings settings (env, nullptr , obj);
2358
2367
args.GetReturnValue ().Set (settings.Pack ());
2359
2368
}
2360
2369
@@ -2483,7 +2492,7 @@ void Http2Session::Request(const FunctionCallbackInfo<Value>& args) {
2483
2492
session->Http2Session ::SubmitRequest (*priority, *list, list.length (),
2484
2493
&ret, options);
2485
2494
2486
- if (ret <= 0 ) {
2495
+ if (ret <= 0 || stream == nullptr ) {
2487
2496
Debug (session, " could not submit request: %s" , nghttp2_strerror (ret));
2488
2497
return args.GetReturnValue ().Set (ret);
2489
2498
}
@@ -2656,7 +2665,7 @@ void Http2Stream::PushPromise(const FunctionCallbackInfo<Value>& args) {
2656
2665
int32_t ret = 0 ;
2657
2666
Http2Stream* stream = parent->SubmitPushPromise (*list, list.length (),
2658
2667
&ret, options);
2659
- if (ret <= 0 ) {
2668
+ if (ret <= 0 || stream == nullptr ) {
2660
2669
Debug (parent, " failed to create push stream: %d" , ret);
2661
2670
return args.GetReturnValue ().Set (ret);
2662
2671
}
@@ -2792,9 +2801,15 @@ void Http2Session::Ping(const FunctionCallbackInfo<Value>& args) {
2792
2801
CHECK_EQ (Buffer::Length (args[0 ]), 8 );
2793
2802
}
2794
2803
2795
- Http2Session::Http2Ping* ping = new Http2Ping (session);
2796
- Local<Object> obj = ping->object ();
2797
- obj->Set (env->context (), env->ondone_string (), args[1 ]).FromJust ();
2804
+ Local<Object> obj;
2805
+ if (!env->http2ping_constructor_template ()
2806
+ ->NewInstance (env->context ())
2807
+ .ToLocal (&obj)) {
2808
+ return ;
2809
+ }
2810
+ if (obj->Set (env->context (), env->ondone_string (), args[1 ]).IsNothing ())
2811
+ return ;
2812
+ Http2Session::Http2Ping* ping = new Http2Ping (session, obj);
2798
2813
2799
2814
// To prevent abuse, we strictly limit the number of unacknowledged PING
2800
2815
// frames that may be sent at any given time. This is configurable in the
@@ -2818,10 +2833,17 @@ void Http2Session::Settings(const FunctionCallbackInfo<Value>& args) {
2818
2833
Http2Session* session;
2819
2834
ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
2820
2835
2821
- Http2Session::Http2Settings* settings = new Http2Settings (session);
2822
- Local<Object> obj = settings->object ();
2823
- obj->Set (env->context (), env->ondone_string (), args[0 ]).FromJust ();
2836
+ Local<Object> obj;
2837
+ if (!env->http2settings_constructor_template ()
2838
+ ->NewInstance (env->context ())
2839
+ .ToLocal (&obj)) {
2840
+ return ;
2841
+ }
2842
+ if (obj->Set (env->context (), env->ondone_string (), args[0 ]).IsNothing ())
2843
+ return ;
2824
2844
2845
+ Http2Session::Http2Settings* settings =
2846
+ new Http2Settings (session->env (), session, obj, 0 );
2825
2847
if (!session->AddSettings (settings)) {
2826
2848
settings->Done (false );
2827
2849
return args.GetReturnValue ().Set (false );
@@ -2868,15 +2890,10 @@ bool Http2Session::AddSettings(Http2Session::Http2Settings* settings) {
2868
2890
return true ;
2869
2891
}
2870
2892
2871
- Http2Session::Http2Ping::Http2Ping (
2872
- Http2Session* session)
2873
- : AsyncWrap(session->env (),
2874
- session->env()->http2ping_constructor_template()
2875
- ->NewInstance(session->env ()->context())
2876
- .ToLocalChecked(),
2877
- AsyncWrap::PROVIDER_HTTP2PING),
2878
- session_(session),
2879
- startTime_(uv_hrtime()) { }
2893
+ Http2Session::Http2Ping::Http2Ping (Http2Session* session, Local<Object> obj)
2894
+ : AsyncWrap(session->env (), obj, AsyncWrap::PROVIDER_HTTP2PING),
2895
+ session_(session),
2896
+ startTime_(uv_hrtime()) {}
2880
2897
2881
2898
void Http2Session::Http2Ping::Send (uint8_t * payload) {
2882
2899
uint8_t data[8 ];
0 commit comments