4
4
#include " node.h"
5
5
#include " node_buffer.h"
6
6
#include " node_http2.h"
7
- #include " node_http2_state.h"
8
7
#include " node_http_common-inl.h"
9
8
#include " node_mem-inl.h"
10
9
#include " node_perf.h"
@@ -113,7 +112,7 @@ Http2Scope::~Http2Scope() {
113
112
// instances to configure an appropriate nghttp2_options struct. The class
114
113
// uses a single TypedArray instance that is shared with the JavaScript side
115
114
// 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) {
117
116
nghttp2_option* option;
118
117
CHECK_EQ (nghttp2_option_new (&option), 0 );
119
118
CHECK_NOT_NULL (option);
@@ -138,7 +137,7 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
138
137
nghttp2_option_set_builtin_recv_extension_type (option, NGHTTP2_ORIGIN);
139
138
}
140
139
141
- AliasedUint32Array& buffer = env-> http2_state () ->options_buffer ;
140
+ AliasedUint32Array& buffer = http2_state->options_buffer ;
142
141
uint32_t flags = buffer[IDX_OPTIONS_FLAGS];
143
142
144
143
if (flags & (1 << IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE)) {
@@ -213,8 +212,8 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
213
212
SetMaxSessionMemory (buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1000000 );
214
213
}
215
214
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 ;
218
217
uint32_t flags = buffer[IDX_SETTINGS_COUNT];
219
218
220
219
size_t n = 0 ;
@@ -244,14 +243,14 @@ void Http2Session::Http2Settings::Init() {
244
243
// The Http2Settings class is used to configure a SETTINGS frame that is
245
244
// to be sent to the connected peer. The settings are set using a TypedArray
246
245
// that is shared with the JavaScript side.
247
- Http2Session::Http2Settings::Http2Settings (Environment* env ,
246
+ Http2Session::Http2Settings::Http2Settings (Http2State* http2_state ,
248
247
Http2Session* session,
249
248
Local<Object> obj,
250
249
uint64_t start_time)
251
- : AsyncWrap(env, obj, PROVIDER_HTTP2SETTINGS),
250
+ : AsyncWrap(http2_state-> env () , obj, PROVIDER_HTTP2SETTINGS),
252
251
session_(session),
253
252
startTime_(start_time) {
254
- Init ();
253
+ Init (http2_state );
255
254
}
256
255
257
256
// Generates a Buffer that contains the serialized payload of a SETTINGS
@@ -272,10 +271,9 @@ Local<Value> Http2Session::Http2Settings::Pack() {
272
271
273
272
// Updates the shared TypedArray with the current remote or local settings for
274
273
// the session.
275
- void Http2Session::Http2Settings::Update (Environment* env,
276
- Http2Session* session,
274
+ void Http2Session::Http2Settings::Update (Http2Session* session,
277
275
get_setting fn) {
278
- AliasedUint32Array& buffer = env ->http2_state ()->settings_buffer ;
276
+ AliasedUint32Array& buffer = session ->http2_state ()->settings_buffer ;
279
277
buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
280
278
fn (**session, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE);
281
279
buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] =
@@ -293,8 +291,8 @@ void Http2Session::Http2Settings::Update(Environment* env,
293
291
}
294
292
295
293
// 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 ;
298
296
299
297
buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
300
298
DEFAULT_SETTINGS_HEADER_TABLE_SIZE;
@@ -469,16 +467,17 @@ void Http2Session::DecreaseAllocatedSize(size_t size) {
469
467
current_nghttp2_memory_ -= size;
470
468
}
471
469
472
- Http2Session::Http2Session (Environment* env ,
470
+ Http2Session::Http2Session (Http2State* http2_state ,
473
471
Local<Object> wrap,
474
472
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) {
477
476
MakeWeak ();
478
477
statistics_.start_time = uv_hrtime ();
479
478
480
479
// Capture the configuration options for this session
481
- Http2Options opts (env , type);
480
+ Http2Options opts (http2_state , type);
482
481
483
482
max_session_memory_ = opts.GetMaxSessionMemory ();
484
483
@@ -521,13 +520,13 @@ Http2Session::Http2Session(Environment* env,
521
520
522
521
// Make the js_fields_ property accessible to JS land.
523
522
js_fields_store_ =
524
- ArrayBuffer::NewBackingStore (env->isolate (), sizeof (SessionJSFields));
523
+ ArrayBuffer::NewBackingStore (env () ->isolate (), sizeof (SessionJSFields));
525
524
js_fields_ = new (js_fields_store_->Data ()) SessionJSFields;
526
525
527
- Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), js_fields_store_);
526
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env () ->isolate (), js_fields_store_);
528
527
Local<Uint8Array> uint8_arr =
529
528
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));
531
530
}
532
531
533
532
Http2Session::~Http2Session () {
@@ -551,15 +550,17 @@ inline bool HasHttp2Observer(Environment* env) {
551
550
}
552
551
553
552
void Http2Stream::EmitStatistics () {
553
+ CHECK_NOT_NULL (session ());
554
554
if (!HasHttp2Observer (env ()))
555
555
return ;
556
556
auto entry =
557
- std::make_unique<Http2StreamPerformanceEntry>(env (), id_, statistics_);
557
+ std::make_unique<Http2StreamPerformanceEntry>(
558
+ session ()->http2_state (), id_, statistics_);
558
559
env ()->SetImmediate ([entry = move (entry)](Environment* env) {
559
560
if (!HasHttp2Observer (env))
560
561
return ;
561
562
HandleScope handle_scope (env->isolate ());
562
- AliasedFloat64Array& buffer = env ->http2_state ()->stream_stats_buffer ;
563
+ AliasedFloat64Array& buffer = entry ->http2_state ()->stream_stats_buffer ;
563
564
buffer[IDX_STREAM_STATS_ID] = entry->id ();
564
565
if (entry->first_byte () != 0 ) {
565
566
buffer[IDX_STREAM_STATS_TIMETOFIRSTBYTE] =
@@ -592,12 +593,12 @@ void Http2Session::EmitStatistics() {
592
593
if (!HasHttp2Observer (env ()))
593
594
return ;
594
595
auto entry = std::make_unique<Http2SessionPerformanceEntry>(
595
- env (), statistics_, session_type_);
596
+ http2_state (), statistics_, session_type_);
596
597
env ()->SetImmediate ([entry = std::move (entry)](Environment* env) {
597
598
if (!HasHttp2Observer (env))
598
599
return ;
599
600
HandleScope handle_scope (env->isolate ());
600
- AliasedFloat64Array& buffer = env ->http2_state ()->session_stats_buffer ;
601
+ AliasedFloat64Array& buffer = entry ->http2_state ()->session_stats_buffer ;
601
602
buffer[IDX_SESSION_STATS_TYPE] = entry->type ();
602
603
buffer[IDX_SESSION_STATS_PINGRTT] = entry->ping_rtt () / 1e6 ;
603
604
buffer[IDX_SESSION_STATS_FRAMESRECEIVED] = entry->frame_count ();
@@ -2334,24 +2335,25 @@ void HttpErrorString(const FunctionCallbackInfo<Value>& args) {
2334
2335
// would be suitable, for instance, for creating the Base64
2335
2336
// output for an HTTP2-Settings header field.
2336
2337
void PackSettings (const FunctionCallbackInfo<Value>& args) {
2337
- Environment* env = Environment::GetCurrent (args);
2338
+ Http2State* state = Unwrap<Http2State>(args.Data ());
2339
+ Environment* env = state->env ();
2338
2340
// TODO(addaleax): We should not be creating a full AsyncWrap for this.
2339
2341
Local<Object> obj;
2340
2342
if (!env->http2settings_constructor_template ()
2341
2343
->NewInstance (env->context ())
2342
2344
.ToLocal (&obj)) {
2343
2345
return ;
2344
2346
}
2345
- Http2Session::Http2Settings settings (env , nullptr , obj);
2347
+ Http2Session::Http2Settings settings (state , nullptr , obj);
2346
2348
args.GetReturnValue ().Set (settings.Pack ());
2347
2349
}
2348
2350
2349
2351
// A TypedArray instance is shared between C++ and JS land to contain the
2350
2352
// default SETTINGS. RefreshDefaultSettings updates that TypedArray with the
2351
2353
// default values.
2352
2354
void 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 );
2355
2357
}
2356
2358
2357
2359
// Sets the next stream ID the Http2Session. If successful, returns true.
@@ -2373,23 +2375,21 @@ void Http2Session::SetNextStreamID(const FunctionCallbackInfo<Value>& args) {
2373
2375
// values established for each of the settings so those can be read in JS land.
2374
2376
template <get_setting fn>
2375
2377
void Http2Session::RefreshSettings (const FunctionCallbackInfo<Value>& args) {
2376
- Environment* env = Environment::GetCurrent (args);
2377
2378
Http2Session* session;
2378
2379
ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
2379
- Http2Settings::Update (env, session, fn);
2380
+ Http2Settings::Update (session, fn);
2380
2381
Debug (session, " settings refreshed for session" );
2381
2382
}
2382
2383
2383
2384
// A TypedArray instance is shared between C++ and JS land to contain state
2384
2385
// information of the current Http2Session. This updates the values in the
2385
2386
// TypedArray so those can be read in JS land.
2386
2387
void Http2Session::RefreshState (const FunctionCallbackInfo<Value>& args) {
2387
- Environment* env = Environment::GetCurrent (args);
2388
2388
Http2Session* session;
2389
2389
ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
2390
2390
Debug (session, " refreshing state" );
2391
2391
2392
- AliasedFloat64Array& buffer = env ->http2_state ()->session_state_buffer ;
2392
+ AliasedFloat64Array& buffer = session ->http2_state ()->session_state_buffer ;
2393
2393
2394
2394
nghttp2_session* s = **session;
2395
2395
@@ -2416,11 +2416,12 @@ void Http2Session::RefreshState(const FunctionCallbackInfo<Value>& args) {
2416
2416
2417
2417
// Constructor for new Http2Session instances.
2418
2418
void Http2Session::New (const FunctionCallbackInfo<Value>& args) {
2419
- Environment* env = Environment::GetCurrent (args);
2419
+ Http2State* state = Unwrap<Http2State>(args.Data ());
2420
+ Environment* env = state->env ();
2420
2421
CHECK (args.IsConstructCall ());
2421
2422
int32_t val = args[0 ]->Int32Value (env->context ()).ToChecked ();
2422
2423
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);
2424
2425
session->get_async_id (); // avoid compiler warning
2425
2426
Debug (session, " session created" );
2426
2427
}
@@ -2645,13 +2646,14 @@ void Http2Stream::Priority(const FunctionCallbackInfo<Value>& args) {
2645
2646
// information about the Http2Stream. This updates the values in that
2646
2647
// TypedArray so that the state can be read by JS.
2647
2648
void Http2Stream::RefreshState (const FunctionCallbackInfo<Value>& args) {
2648
- Environment* env = Environment::GetCurrent (args);
2649
2649
Http2Stream* stream;
2650
2650
ASSIGN_OR_RETURN_UNWRAP (&stream, args.Holder ());
2651
2651
2652
2652
Debug (stream, " refreshing state" );
2653
2653
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 ;
2655
2657
2656
2658
nghttp2_stream* str = **stream;
2657
2659
nghttp2_session* s = **(stream->session ());
@@ -2797,7 +2799,8 @@ void Http2Session::Settings(const FunctionCallbackInfo<Value>& args) {
2797
2799
return ;
2798
2800
2799
2801
Http2Settings* settings = session->AddSettings (
2800
- MakeDetachedBaseObject<Http2Settings>(session->env (), session, obj, 0 ));
2802
+ MakeDetachedBaseObject<Http2Settings>(
2803
+ session->http2_state (), session, obj, 0 ));
2801
2804
if (settings == nullptr ) return args.GetReturnValue ().Set (false );
2802
2805
2803
2806
settings->Send ();
@@ -2921,16 +2924,22 @@ void SetCallbackFunctions(const FunctionCallbackInfo<Value>& args) {
2921
2924
#undef SET_FUNCTION
2922
2925
}
2923
2926
2927
+ void Http2State::MemoryInfo (MemoryTracker* tracker) const {
2928
+ tracker->TrackField (" root_buffer" , root_buffer);
2929
+ }
2930
+
2924
2931
// Set up the process.binding('http2') binding.
2925
2932
void Initialize (Local<Object> target,
2926
2933
Local<Value> unused,
2927
2934
Local<Context> context,
2928
2935
void * priv) {
2929
2936
Environment* env = Environment::GetCurrent (context);
2930
2937
Isolate* isolate = env->isolate ();
2931
- HandleScope scope (isolate);
2938
+ HandleScope handle_scope (isolate);
2932
2939
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 ;
2934
2943
2935
2944
#define SET_STATE_TYPEDARRAY (name, field ) \
2936
2945
target->Set (context, \
@@ -2953,8 +2962,6 @@ void Initialize(Local<Object> target,
2953
2962
" sessionStats" , state->session_stats_buffer .GetJSArray ());
2954
2963
#undef SET_STATE_TYPEDARRAY
2955
2964
2956
- env->set_http2_state (std::move (state));
2957
-
2958
2965
NODE_DEFINE_CONSTANT (target, kBitfield );
2959
2966
NODE_DEFINE_CONSTANT (target, kSessionPriorityListenerCount );
2960
2967
NODE_DEFINE_CONSTANT (target, kSessionFrameErrorListenerCount );
0 commit comments