44#include " node.h"
55#include " node_buffer.h"
66#include " node_http2.h"
7- #include " node_http2_state.h"
87#include " node_http_common-inl.h"
98#include " node_mem-inl.h"
109#include " node_perf.h"
@@ -113,7 +112,7 @@ Http2Scope::~Http2Scope() {
113112// instances to configure an appropriate nghttp2_options struct. The class
114113// uses a single TypedArray instance that is shared with the JavaScript side
115114// to more efficiently pass values back and forth.
116- Http2Options::Http2Options (Environment* env , nghttp2_session_type type) {
115+ Http2Options::Http2Options (Http2State* http2_state , nghttp2_session_type type) {
117116 nghttp2_option* option;
118117 CHECK_EQ (nghttp2_option_new (&option), 0 );
119118 CHECK_NOT_NULL (option);
@@ -138,7 +137,7 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
138137 nghttp2_option_set_builtin_recv_extension_type (option, NGHTTP2_ORIGIN);
139138 }
140139
141- AliasedUint32Array& buffer = env-> http2_state () ->options_buffer ;
140+ AliasedUint32Array& buffer = http2_state->options_buffer ;
142141 uint32_t flags = buffer[IDX_OPTIONS_FLAGS];
143142
144143 if (flags & (1 << IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE)) {
@@ -213,8 +212,8 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
213212 SetMaxSessionMemory (buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1000000 );
214213}
215214
216- void Http2Session::Http2Settings::Init () {
217- AliasedUint32Array& buffer = env ()-> http2_state () ->settings_buffer ;
215+ void Http2Session::Http2Settings::Init (Http2State* http2_state ) {
216+ AliasedUint32Array& buffer = http2_state->settings_buffer ;
218217 uint32_t flags = buffer[IDX_SETTINGS_COUNT];
219218
220219 size_t n = 0 ;
@@ -244,14 +243,14 @@ void Http2Session::Http2Settings::Init() {
244243// The Http2Settings class is used to configure a SETTINGS frame that is
245244// to be sent to the connected peer. The settings are set using a TypedArray
246245// that is shared with the JavaScript side.
247- Http2Session::Http2Settings::Http2Settings (Environment* env ,
246+ Http2Session::Http2Settings::Http2Settings (Http2State* http2_state ,
248247 Http2Session* session,
249248 Local<Object> obj,
250249 uint64_t start_time)
251- : AsyncWrap(env, obj, PROVIDER_HTTP2SETTINGS),
250+ : AsyncWrap(http2_state-> env () , obj, PROVIDER_HTTP2SETTINGS),
252251 session_(session),
253252 startTime_(start_time) {
254- Init ();
253+ Init (http2_state );
255254}
256255
257256// Generates a Buffer that contains the serialized payload of a SETTINGS
@@ -272,10 +271,9 @@ Local<Value> Http2Session::Http2Settings::Pack() {
272271
273272// Updates the shared TypedArray with the current remote or local settings for
274273// the session.
275- void Http2Session::Http2Settings::Update (Environment* env,
276- Http2Session* session,
274+ void Http2Session::Http2Settings::Update (Http2Session* session,
277275 get_setting fn) {
278- AliasedUint32Array& buffer = env ->http2_state ()->settings_buffer ;
276+ AliasedUint32Array& buffer = session ->http2_state ()->settings_buffer ;
279277 buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
280278 fn (**session, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE);
281279 buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] =
@@ -293,8 +291,8 @@ void Http2Session::Http2Settings::Update(Environment* env,
293291}
294292
295293// Initializes the shared TypedArray with the default settings values.
296- void Http2Session::Http2Settings::RefreshDefaults (Environment* env ) {
297- AliasedUint32Array& buffer = env-> http2_state () ->settings_buffer ;
294+ void Http2Session::Http2Settings::RefreshDefaults (Http2State* http2_state ) {
295+ AliasedUint32Array& buffer = http2_state->settings_buffer ;
298296
299297 buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
300298 DEFAULT_SETTINGS_HEADER_TABLE_SIZE;
@@ -469,16 +467,17 @@ void Http2Session::DecreaseAllocatedSize(size_t size) {
469467 current_nghttp2_memory_ -= size;
470468}
471469
472- Http2Session::Http2Session (Environment* env ,
470+ Http2Session::Http2Session (Http2State* http2_state ,
473471 Local<Object> wrap,
474472 nghttp2_session_type type)
475- : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_HTTP2SESSION),
476- session_type_(type) {
473+ : AsyncWrap(http2_state->env (), wrap, AsyncWrap::PROVIDER_HTTP2SESSION),
474+ session_type_(type),
475+ http2_state_(http2_state) {
477476 MakeWeak ();
478477 statistics_.start_time = uv_hrtime ();
479478
480479 // Capture the configuration options for this session
481- Http2Options opts (env , type);
480+ Http2Options opts (http2_state , type);
482481
483482 max_session_memory_ = opts.GetMaxSessionMemory ();
484483
@@ -521,13 +520,13 @@ Http2Session::Http2Session(Environment* env,
521520
522521 // Make the js_fields_ property accessible to JS land.
523522 js_fields_store_ =
524- ArrayBuffer::NewBackingStore (env->isolate (), sizeof (SessionJSFields));
523+ ArrayBuffer::NewBackingStore (env () ->isolate (), sizeof (SessionJSFields));
525524 js_fields_ = new (js_fields_store_->Data ()) SessionJSFields;
526525
527- Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), js_fields_store_);
526+ Local<ArrayBuffer> ab = ArrayBuffer::New (env () ->isolate (), js_fields_store_);
528527 Local<Uint8Array> uint8_arr =
529528 Uint8Array::New (ab, 0 , kSessionUint8FieldCount );
530- USE (wrap->Set (env->context (), env->fields_string (), uint8_arr));
529+ USE (wrap->Set (env () ->context (), env () ->fields_string (), uint8_arr));
531530}
532531
533532Http2Session::~Http2Session () {
@@ -551,15 +550,17 @@ inline bool HasHttp2Observer(Environment* env) {
551550}
552551
553552void Http2Stream::EmitStatistics () {
553+ CHECK_NOT_NULL (session ());
554554 if (!HasHttp2Observer (env ()))
555555 return ;
556556 auto entry =
557- std::make_unique<Http2StreamPerformanceEntry>(env (), id_, statistics_);
557+ std::make_unique<Http2StreamPerformanceEntry>(
558+ session ()->http2_state (), id_, statistics_);
558559 env ()->SetImmediate ([entry = move (entry)](Environment* env) {
559560 if (!HasHttp2Observer (env))
560561 return ;
561562 HandleScope handle_scope (env->isolate ());
562- AliasedFloat64Array& buffer = env ->http2_state ()->stream_stats_buffer ;
563+ AliasedFloat64Array& buffer = entry ->http2_state ()->stream_stats_buffer ;
563564 buffer[IDX_STREAM_STATS_ID] = entry->id ();
564565 if (entry->first_byte () != 0 ) {
565566 buffer[IDX_STREAM_STATS_TIMETOFIRSTBYTE] =
@@ -592,12 +593,12 @@ void Http2Session::EmitStatistics() {
592593 if (!HasHttp2Observer (env ()))
593594 return ;
594595 auto entry = std::make_unique<Http2SessionPerformanceEntry>(
595- env (), statistics_, session_type_);
596+ http2_state (), statistics_, session_type_);
596597 env ()->SetImmediate ([entry = std::move (entry)](Environment* env) {
597598 if (!HasHttp2Observer (env))
598599 return ;
599600 HandleScope handle_scope (env->isolate ());
600- AliasedFloat64Array& buffer = env ->http2_state ()->session_stats_buffer ;
601+ AliasedFloat64Array& buffer = entry ->http2_state ()->session_stats_buffer ;
601602 buffer[IDX_SESSION_STATS_TYPE] = entry->type ();
602603 buffer[IDX_SESSION_STATS_PINGRTT] = entry->ping_rtt () / 1e6 ;
603604 buffer[IDX_SESSION_STATS_FRAMESRECEIVED] = entry->frame_count ();
@@ -2334,24 +2335,25 @@ void HttpErrorString(const FunctionCallbackInfo<Value>& args) {
23342335// would be suitable, for instance, for creating the Base64
23352336// output for an HTTP2-Settings header field.
23362337void PackSettings (const FunctionCallbackInfo<Value>& args) {
2337- Environment* env = Environment::GetCurrent (args);
2338+ Http2State* state = Unwrap<Http2State>(args.Data ());
2339+ Environment* env = state->env ();
23382340 // TODO(addaleax): We should not be creating a full AsyncWrap for this.
23392341 Local<Object> obj;
23402342 if (!env->http2settings_constructor_template ()
23412343 ->NewInstance (env->context ())
23422344 .ToLocal (&obj)) {
23432345 return ;
23442346 }
2345- Http2Session::Http2Settings settings (env , nullptr , obj);
2347+ Http2Session::Http2Settings settings (state , nullptr , obj);
23462348 args.GetReturnValue ().Set (settings.Pack ());
23472349}
23482350
23492351// A TypedArray instance is shared between C++ and JS land to contain the
23502352// default SETTINGS. RefreshDefaultSettings updates that TypedArray with the
23512353// default values.
23522354void RefreshDefaultSettings (const FunctionCallbackInfo<Value>& args) {
2353- Environment* env = Environment::GetCurrent (args);
2354- Http2Session::Http2Settings::RefreshDefaults (env );
2355+ Http2State* state = Unwrap<Http2State> (args. Data () );
2356+ Http2Session::Http2Settings::RefreshDefaults (state );
23552357}
23562358
23572359// Sets the next stream ID the Http2Session. If successful, returns true.
@@ -2373,23 +2375,21 @@ void Http2Session::SetNextStreamID(const FunctionCallbackInfo<Value>& args) {
23732375// values established for each of the settings so those can be read in JS land.
23742376template <get_setting fn>
23752377void Http2Session::RefreshSettings (const FunctionCallbackInfo<Value>& args) {
2376- Environment* env = Environment::GetCurrent (args);
23772378 Http2Session* session;
23782379 ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
2379- Http2Settings::Update (env, session, fn);
2380+ Http2Settings::Update (session, fn);
23802381 Debug (session, " settings refreshed for session" );
23812382}
23822383
23832384// A TypedArray instance is shared between C++ and JS land to contain state
23842385// information of the current Http2Session. This updates the values in the
23852386// TypedArray so those can be read in JS land.
23862387void Http2Session::RefreshState (const FunctionCallbackInfo<Value>& args) {
2387- Environment* env = Environment::GetCurrent (args);
23882388 Http2Session* session;
23892389 ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
23902390 Debug (session, " refreshing state" );
23912391
2392- AliasedFloat64Array& buffer = env ->http2_state ()->session_state_buffer ;
2392+ AliasedFloat64Array& buffer = session ->http2_state ()->session_state_buffer ;
23932393
23942394 nghttp2_session* s = **session;
23952395
@@ -2416,11 +2416,12 @@ void Http2Session::RefreshState(const FunctionCallbackInfo<Value>& args) {
24162416
24172417// Constructor for new Http2Session instances.
24182418void Http2Session::New (const FunctionCallbackInfo<Value>& args) {
2419- Environment* env = Environment::GetCurrent (args);
2419+ Http2State* state = Unwrap<Http2State>(args.Data ());
2420+ Environment* env = state->env ();
24202421 CHECK (args.IsConstructCall ());
24212422 int32_t val = args[0 ]->Int32Value (env->context ()).ToChecked ();
24222423 nghttp2_session_type type = static_cast <nghttp2_session_type>(val);
2423- Http2Session* session = new Http2Session (env , args.This (), type);
2424+ Http2Session* session = new Http2Session (state , args.This (), type);
24242425 session->get_async_id (); // avoid compiler warning
24252426 Debug (session, " session created" );
24262427}
@@ -2645,13 +2646,14 @@ void Http2Stream::Priority(const FunctionCallbackInfo<Value>& args) {
26452646// information about the Http2Stream. This updates the values in that
26462647// TypedArray so that the state can be read by JS.
26472648void Http2Stream::RefreshState (const FunctionCallbackInfo<Value>& args) {
2648- Environment* env = Environment::GetCurrent (args);
26492649 Http2Stream* stream;
26502650 ASSIGN_OR_RETURN_UNWRAP (&stream, args.Holder ());
26512651
26522652 Debug (stream, " refreshing state" );
26532653
2654- AliasedFloat64Array& buffer = env->http2_state ()->stream_state_buffer ;
2654+ CHECK_NOT_NULL (stream->session ());
2655+ AliasedFloat64Array& buffer =
2656+ stream->session ()->http2_state ()->stream_state_buffer ;
26552657
26562658 nghttp2_stream* str = **stream;
26572659 nghttp2_session* s = **(stream->session ());
@@ -2797,7 +2799,8 @@ void Http2Session::Settings(const FunctionCallbackInfo<Value>& args) {
27972799 return ;
27982800
27992801 Http2Settings* settings = session->AddSettings (
2800- MakeDetachedBaseObject<Http2Settings>(session->env (), session, obj, 0 ));
2802+ MakeDetachedBaseObject<Http2Settings>(
2803+ session->http2_state (), session, obj, 0 ));
28012804 if (settings == nullptr ) return args.GetReturnValue ().Set (false );
28022805
28032806 settings->Send ();
@@ -2921,16 +2924,22 @@ void SetCallbackFunctions(const FunctionCallbackInfo<Value>& args) {
29212924#undef SET_FUNCTION
29222925}
29232926
2927+ void Http2State::MemoryInfo (MemoryTracker* tracker) const {
2928+ tracker->TrackField (" root_buffer" , root_buffer);
2929+ }
2930+
29242931// Set up the process.binding('http2') binding.
29252932void Initialize (Local<Object> target,
29262933 Local<Value> unused,
29272934 Local<Context> context,
29282935 void * priv) {
29292936 Environment* env = Environment::GetCurrent (context);
29302937 Isolate* isolate = env->isolate ();
2931- HandleScope scope (isolate);
2938+ HandleScope handle_scope (isolate);
29322939
2933- std::unique_ptr<Http2State> state (new Http2State (isolate));
2940+ Environment::BindingScope<Http2State> binding_scope (env);
2941+ if (!binding_scope) return ;
2942+ Http2State* state = binding_scope.data ;
29342943
29352944#define SET_STATE_TYPEDARRAY (name, field ) \
29362945 target->Set (context, \
@@ -2953,8 +2962,6 @@ void Initialize(Local<Object> target,
29532962 " sessionStats" , state->session_stats_buffer .GetJSArray ());
29542963#undef SET_STATE_TYPEDARRAY
29552964
2956- env->set_http2_state (std::move (state));
2957-
29582965 NODE_DEFINE_CONSTANT (target, kBitfield );
29592966 NODE_DEFINE_CONSTANT (target, kSessionPriorityListenerCount );
29602967 NODE_DEFINE_CONSTANT (target, kSessionFrameErrorListenerCount );
0 commit comments