@@ -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
@@ -918,13 +909,14 @@ int Http2Session::OnBeginHeadersCallback(nghttp2_session* handle,
918
909
// The common case is that we're creating a new stream. The less likely
919
910
// case is that we're receiving a set of trailers
920
911
if (LIKELY (stream == nullptr )) {
921
- if (UNLIKELY (!session->CanAddStream ())) {
912
+ if (UNLIKELY (!session->CanAddStream () ||
913
+ Http2Stream::New (session, id, frame->headers .cat ) ==
914
+ nullptr )) {
922
915
// Too many concurrent streams being opened
923
916
nghttp2_submit_rst_stream (**session, NGHTTP2_FLAG_NONE, id,
924
917
NGHTTP2_ENHANCE_YOUR_CALM);
925
918
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
926
919
}
927
- new Http2Stream (session, id, frame->headers .cat );
928
920
} else if (!stream->IsDestroyed ()) {
929
921
stream->StartHeaders (frame->headers .cat );
930
922
}
@@ -1771,7 +1763,7 @@ Http2Stream* Http2Session::SubmitRequest(
1771
1763
*ret = nghttp2_submit_request (session_, prispec, nva, len, *prov, nullptr );
1772
1764
CHECK_NE (*ret, NGHTTP2_ERR_NOMEM);
1773
1765
if (LIKELY (*ret > 0 ))
1774
- stream = new Http2Stream (this , *ret, NGHTTP2_HCAT_HEADERS, options);
1766
+ stream = Http2Stream::New (this , *ret, NGHTTP2_HCAT_HEADERS, options);
1775
1767
return stream;
1776
1768
}
1777
1769
@@ -1857,20 +1849,30 @@ void Http2Session::Consume(Local<External> external) {
1857
1849
Debug (this , " i/o stream consumed" );
1858
1850
}
1859
1851
1860
-
1861
- Http2Stream::Http2Stream (
1862
- Http2Session* session,
1863
- int32_t id,
1864
- nghttp2_headers_category category,
1865
- int options) : AsyncWrap(session->env (),
1866
- session->env()->http2stream_constructor_template()
1867
- ->NewInstance(session->env ()->context())
1868
- .ToLocalChecked(),
1869
- AsyncWrap::PROVIDER_HTTP2STREAM),
1870
- StreamBase(session->env ()),
1871
- session_(session),
1872
- id_(id),
1873
- current_headers_category_(category) {
1852
+ Http2Stream* Http2Stream::New (Http2Session* session,
1853
+ int32_t id,
1854
+ nghttp2_headers_category category,
1855
+ int options) {
1856
+ Local<Object> obj;
1857
+ if (!session->env ()
1858
+ ->http2stream_constructor_template ()
1859
+ ->NewInstance (session->env ()->context ())
1860
+ .ToLocal (&obj)) {
1861
+ return nullptr ;
1862
+ }
1863
+ return new Http2Stream (session, obj, id, category, options);
1864
+ }
1865
+
1866
+ Http2Stream::Http2Stream (Http2Session* session,
1867
+ Local<Object> obj,
1868
+ int32_t id,
1869
+ nghttp2_headers_category category,
1870
+ int options)
1871
+ : AsyncWrap(session->env (), obj, AsyncWrap::PROVIDER_HTTP2STREAM),
1872
+ StreamBase(session->env ()),
1873
+ session_(session),
1874
+ id_(id),
1875
+ current_headers_category_(category) {
1874
1876
MakeWeak ();
1875
1877
statistics_.start_time = uv_hrtime ();
1876
1878
@@ -2113,7 +2115,7 @@ Http2Stream* Http2Stream::SubmitPushPromise(nghttp2_nv* nva,
2113
2115
CHECK_NE (*ret, NGHTTP2_ERR_NOMEM);
2114
2116
Http2Stream* stream = nullptr ;
2115
2117
if (*ret > 0 )
2116
- stream = new Http2Stream (session_, *ret, NGHTTP2_HCAT_HEADERS, options);
2118
+ stream = Http2Stream::New (session_, *ret, NGHTTP2_HCAT_HEADERS, options);
2117
2119
2118
2120
return stream;
2119
2121
}
@@ -2335,7 +2337,14 @@ void HttpErrorString(const FunctionCallbackInfo<Value>& args) {
2335
2337
// output for an HTTP2-Settings header field.
2336
2338
void PackSettings (const FunctionCallbackInfo<Value>& args) {
2337
2339
Environment* env = Environment::GetCurrent (args);
2338
- Http2Session::Http2Settings settings (env);
2340
+ // TODO(addaleax): We should not be creating a full AsyncWrap for this.
2341
+ Local<Object> obj;
2342
+ if (!env->http2settings_constructor_template ()
2343
+ ->NewInstance (env->context ())
2344
+ .ToLocal (&obj)) {
2345
+ return ;
2346
+ }
2347
+ Http2Session::Http2Settings settings (env, nullptr , obj);
2339
2348
args.GetReturnValue ().Set (settings.Pack ());
2340
2349
}
2341
2350
@@ -2464,7 +2473,7 @@ void Http2Session::Request(const FunctionCallbackInfo<Value>& args) {
2464
2473
session->Http2Session ::SubmitRequest (*priority, *list, list.length (),
2465
2474
&ret, options);
2466
2475
2467
- if (ret <= 0 ) {
2476
+ if (ret <= 0 || stream == nullptr ) {
2468
2477
Debug (session, " could not submit request: %s" , nghttp2_strerror (ret));
2469
2478
return args.GetReturnValue ().Set (ret);
2470
2479
}
@@ -2637,7 +2646,7 @@ void Http2Stream::PushPromise(const FunctionCallbackInfo<Value>& args) {
2637
2646
int32_t ret = 0 ;
2638
2647
Http2Stream* stream = parent->SubmitPushPromise (*list, list.length (),
2639
2648
&ret, options);
2640
- if (ret <= 0 ) {
2649
+ if (ret <= 0 || stream == nullptr ) {
2641
2650
Debug (parent, " failed to create push stream: %d" , ret);
2642
2651
return args.GetReturnValue ().Set (ret);
2643
2652
}
@@ -2773,9 +2782,15 @@ void Http2Session::Ping(const FunctionCallbackInfo<Value>& args) {
2773
2782
CHECK_EQ (Buffer::Length (args[0 ]), 8 );
2774
2783
}
2775
2784
2776
- Http2Session::Http2Ping* ping = new Http2Ping (session);
2777
- Local<Object> obj = ping->object ();
2778
- obj->Set (env->context (), env->ondone_string (), args[1 ]).FromJust ();
2785
+ Local<Object> obj;
2786
+ if (!env->http2ping_constructor_template ()
2787
+ ->NewInstance (env->context ())
2788
+ .ToLocal (&obj)) {
2789
+ return ;
2790
+ }
2791
+ if (obj->Set (env->context (), env->ondone_string (), args[1 ]).IsNothing ())
2792
+ return ;
2793
+ Http2Session::Http2Ping* ping = new Http2Ping (session, obj);
2779
2794
2780
2795
// To prevent abuse, we strictly limit the number of unacknowledged PING
2781
2796
// frames that may be sent at any given time. This is configurable in the
@@ -2799,10 +2814,17 @@ void Http2Session::Settings(const FunctionCallbackInfo<Value>& args) {
2799
2814
Http2Session* session;
2800
2815
ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
2801
2816
2802
- Http2Session::Http2Settings* settings = new Http2Settings (session);
2803
- Local<Object> obj = settings->object ();
2804
- obj->Set (env->context (), env->ondone_string (), args[0 ]).FromJust ();
2817
+ Local<Object> obj;
2818
+ if (!env->http2settings_constructor_template ()
2819
+ ->NewInstance (env->context ())
2820
+ .ToLocal (&obj)) {
2821
+ return ;
2822
+ }
2823
+ if (obj->Set (env->context (), env->ondone_string (), args[0 ]).IsNothing ())
2824
+ return ;
2805
2825
2826
+ Http2Session::Http2Settings* settings =
2827
+ new Http2Settings (session->env (), session, obj, 0 );
2806
2828
if (!session->AddSettings (settings)) {
2807
2829
settings->Done (false );
2808
2830
return args.GetReturnValue ().Set (false );
@@ -2849,15 +2871,10 @@ bool Http2Session::AddSettings(Http2Session::Http2Settings* settings) {
2849
2871
return true ;
2850
2872
}
2851
2873
2852
- Http2Session::Http2Ping::Http2Ping (
2853
- Http2Session* session)
2854
- : AsyncWrap(session->env (),
2855
- session->env()->http2ping_constructor_template()
2856
- ->NewInstance(session->env ()->context())
2857
- .ToLocalChecked(),
2858
- AsyncWrap::PROVIDER_HTTP2PING),
2859
- session_(session),
2860
- startTime_(uv_hrtime()) { }
2874
+ Http2Session::Http2Ping::Http2Ping (Http2Session* session, Local<Object> obj)
2875
+ : AsyncWrap(session->env (), obj, AsyncWrap::PROVIDER_HTTP2PING),
2876
+ session_(session),
2877
+ startTime_(uv_hrtime()) {}
2861
2878
2862
2879
void Http2Session::Http2Ping::Send (uint8_t * payload) {
2863
2880
uint8_t data[8 ];
0 commit comments