@@ -113,53 +113,56 @@ Http2Scope::~Http2Scope() {
113113// uses a single TypedArray instance that is shared with the JavaScript side
114114// to more efficiently pass values back and forth.
115115Http2Options::Http2Options (Environment* env, nghttp2_session_type type) {
116- nghttp2_option_new (&options_);
116+ nghttp2_option* option;
117+ CHECK_EQ (nghttp2_option_new (&option), 0 );
118+ CHECK_NOT_NULL (option);
119+ options_.reset (option);
117120
118121 // Make sure closed connections aren't kept around, taking up memory.
119122 // Note that this breaks the priority tree, which we don't use.
120- nghttp2_option_set_no_closed_streams (options_ , 1 );
123+ nghttp2_option_set_no_closed_streams (option , 1 );
121124
122125 // We manually handle flow control within a session in order to
123126 // implement backpressure -- that is, we only send WINDOW_UPDATE
124127 // frames to the remote peer as data is actually consumed by user
125128 // code. This ensures that the flow of data over the connection
126129 // does not move too quickly and limits the amount of data we
127130 // are required to buffer.
128- nghttp2_option_set_no_auto_window_update (options_ , 1 );
131+ nghttp2_option_set_no_auto_window_update (option , 1 );
129132
130133 // Enable built in support for receiving ALTSVC and ORIGIN frames (but
131134 // only on client side sessions
132135 if (type == NGHTTP2_SESSION_CLIENT) {
133- nghttp2_option_set_builtin_recv_extension_type (options_ , NGHTTP2_ALTSVC);
134- nghttp2_option_set_builtin_recv_extension_type (options_ , NGHTTP2_ORIGIN);
136+ nghttp2_option_set_builtin_recv_extension_type (option , NGHTTP2_ALTSVC);
137+ nghttp2_option_set_builtin_recv_extension_type (option , NGHTTP2_ORIGIN);
135138 }
136139
137140 AliasedUint32Array& buffer = env->http2_state ()->options_buffer ;
138141 uint32_t flags = buffer[IDX_OPTIONS_FLAGS];
139142
140143 if (flags & (1 << IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE)) {
141144 nghttp2_option_set_max_deflate_dynamic_table_size (
142- options_ ,
145+ option ,
143146 buffer[IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE]);
144147 }
145148
146149 if (flags & (1 << IDX_OPTIONS_MAX_RESERVED_REMOTE_STREAMS)) {
147150 nghttp2_option_set_max_reserved_remote_streams (
148- options_ ,
151+ option ,
149152 buffer[IDX_OPTIONS_MAX_RESERVED_REMOTE_STREAMS]);
150153 }
151154
152155 if (flags & (1 << IDX_OPTIONS_MAX_SEND_HEADER_BLOCK_LENGTH)) {
153156 nghttp2_option_set_max_send_header_block_length (
154- options_ ,
157+ option ,
155158 buffer[IDX_OPTIONS_MAX_SEND_HEADER_BLOCK_LENGTH]);
156159 }
157160
158161 // Recommended default
159- nghttp2_option_set_peer_max_concurrent_streams (options_ , 100 );
162+ nghttp2_option_set_peer_max_concurrent_streams (option , 100 );
160163 if (flags & (1 << IDX_OPTIONS_PEER_MAX_CONCURRENT_STREAMS)) {
161164 nghttp2_option_set_peer_max_concurrent_streams (
162- options_ ,
165+ option ,
163166 buffer[IDX_OPTIONS_PEER_MAX_CONCURRENT_STREAMS]);
164167 }
165168
@@ -178,27 +181,24 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
178181 // header pairs the session may accept. This is a hard limit.. that is,
179182 // if the remote peer sends more than this amount, the stream will be
180183 // automatically closed with an RST_STREAM.
181- if (flags & (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS)) {
184+ if (flags & (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS))
182185 SetMaxHeaderPairs (buffer[IDX_OPTIONS_MAX_HEADER_LIST_PAIRS]);
183- }
184186
185187 // The HTTP2 specification places no limits on the number of HTTP2
186188 // PING frames that can be sent. In order to prevent PINGS from being
187189 // abused as an attack vector, however, we place a strict upper limit
188190 // on the number of unacknowledged PINGS that can be sent at any given
189191 // time.
190- if (flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_PINGS)) {
192+ if (flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_PINGS))
191193 SetMaxOutstandingPings (buffer[IDX_OPTIONS_MAX_OUTSTANDING_PINGS]);
192- }
193194
194195 // The HTTP2 specification places no limits on the number of HTTP2
195196 // SETTINGS frames that can be sent. In order to prevent PINGS from being
196197 // abused as an attack vector, however, we place a strict upper limit
197198 // on the number of unacknowledged SETTINGS that can be sent at any given
198199 // time.
199- if (flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS)) {
200+ if (flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS))
200201 SetMaxOutstandingSettings (buffer[IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS]);
201- }
202202
203203 // The HTTP2 specification places no limits on the amount of memory
204204 // that a session can consume. In order to prevent abuse, we place a
@@ -208,9 +208,8 @@ Http2Options::Http2Options(Environment* env, nghttp2_session_type type) {
208208 // created.
209209 // Important: The maxSessionMemory option in javascript is expressed in
210210 // terms of MB increments (i.e. the value 1 == 1 MB)
211- if (flags & (1 << IDX_OPTIONS_MAX_SESSION_MEMORY)) {
211+ if (flags & (1 << IDX_OPTIONS_MAX_SESSION_MEMORY))
212212 SetMaxSessionMemory (buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1e6 );
213- }
214213}
215214
216215void Http2Session::Http2Settings::Init () {
@@ -420,42 +419,39 @@ Origins::Origins(Isolate* isolate,
420419// Sets the various callback functions that nghttp2 will use to notify us
421420// about significant events while processing http2 stuff.
422421Http2Session::Callbacks::Callbacks (bool kHasGetPaddingCallback ) {
423- CHECK_EQ (nghttp2_session_callbacks_new (&callbacks), 0 );
422+ nghttp2_session_callbacks* callbacks_;
423+ CHECK_EQ (nghttp2_session_callbacks_new (&callbacks_), 0 );
424+ callbacks.reset (callbacks_);
424425
425426 nghttp2_session_callbacks_set_on_begin_headers_callback (
426- callbacks , OnBeginHeadersCallback);
427+ callbacks_ , OnBeginHeadersCallback);
427428 nghttp2_session_callbacks_set_on_header_callback2 (
428- callbacks , OnHeaderCallback);
429+ callbacks_ , OnHeaderCallback);
429430 nghttp2_session_callbacks_set_on_frame_recv_callback (
430- callbacks , OnFrameReceive);
431+ callbacks_ , OnFrameReceive);
431432 nghttp2_session_callbacks_set_on_stream_close_callback (
432- callbacks , OnStreamClose);
433+ callbacks_ , OnStreamClose);
433434 nghttp2_session_callbacks_set_on_data_chunk_recv_callback (
434- callbacks , OnDataChunkReceived);
435+ callbacks_ , OnDataChunkReceived);
435436 nghttp2_session_callbacks_set_on_frame_not_send_callback (
436- callbacks , OnFrameNotSent);
437+ callbacks_ , OnFrameNotSent);
437438 nghttp2_session_callbacks_set_on_invalid_header_callback2 (
438- callbacks , OnInvalidHeader);
439+ callbacks_ , OnInvalidHeader);
439440 nghttp2_session_callbacks_set_error_callback (
440- callbacks , OnNghttpError);
441+ callbacks_ , OnNghttpError);
441442 nghttp2_session_callbacks_set_send_data_callback (
442- callbacks , OnSendData);
443+ callbacks_ , OnSendData);
443444 nghttp2_session_callbacks_set_on_invalid_frame_recv_callback (
444- callbacks , OnInvalidFrame);
445+ callbacks_ , OnInvalidFrame);
445446 nghttp2_session_callbacks_set_on_frame_send_callback (
446- callbacks , OnFrameSent);
447+ callbacks_ , OnFrameSent);
447448
448449 if (kHasGetPaddingCallback ) {
449450 nghttp2_session_callbacks_set_select_padding_callback (
450- callbacks , OnSelectPadding);
451+ callbacks_ , OnSelectPadding);
451452 }
452453}
453454
454-
455- Http2Session::Callbacks::~Callbacks () {
456- nghttp2_session_callbacks_del (callbacks);
457- }
458-
459455void Http2Session::StopTrackingRcbuf (nghttp2_rcbuf* buf) {
460456 StopTrackingMemory (buf);
461457}
@@ -499,9 +495,6 @@ Http2Session::Http2Session(Environment* env,
499495 bool hasGetPaddingCallback =
500496 padding_strategy_ != PADDING_STRATEGY_NONE;
501497
502- nghttp2_session_callbacks* callbacks
503- = callback_struct_saved[hasGetPaddingCallback ? 1 : 0 ].callbacks ;
504-
505498 auto fn = type == NGHTTP2_SESSION_SERVER ?
506499 nghttp2_session_server_new3 :
507500 nghttp2_session_client_new3;
@@ -513,7 +506,14 @@ Http2Session::Http2Session(Environment* env,
513506 // of the options are out of acceptable range, which we should
514507 // be catching before it gets this far. Either way, crash if this
515508 // fails.
516- CHECK_EQ (fn (&session_, callbacks, this , *opts, &alloc_info), 0 );
509+ nghttp2_session* session;
510+ CHECK_EQ (fn (
511+ &session,
512+ callback_struct_saved[hasGetPaddingCallback ? 1 : 0 ].callbacks .get (),
513+ this ,
514+ *opts,
515+ &alloc_info), 0 );
516+ session_.reset (session);
517517
518518 outgoing_storage_.reserve (1024 );
519519 outgoing_buffers_.reserve (32 );
@@ -533,7 +533,9 @@ Http2Session::Http2Session(Environment* env,
533533Http2Session::~Http2Session () {
534534 CHECK_EQ (flags_ & SESSION_STATE_HAS_SCOPE, 0 );
535535 Debug (this , " freeing nghttp2 session" );
536- nghttp2_session_del (session_);
536+ // Explicitly reset session_ so the subsequent
537+ // current_nghttp2_memory_ check passes.
538+ session_.reset ();
537539 CHECK_EQ (current_nghttp2_memory_, 0 );
538540}
539541
@@ -629,7 +631,7 @@ void Http2Session::Close(uint32_t code, bool socket_closed) {
629631 // make a best effort.
630632 if (!socket_closed) {
631633 Debug (this , " terminating session with code %d" , code);
632- CHECK_EQ (nghttp2_session_terminate_session (session_, code), 0 );
634+ CHECK_EQ (nghttp2_session_terminate_session (session_. get () , code), 0 );
633635 SendPendingData ();
634636 } else if (stream_ != nullptr ) {
635637 stream_->RemoveStreamListener (this );
@@ -669,7 +671,7 @@ inline Http2Stream* Http2Session::FindStream(int32_t id) {
669671inline bool Http2Session::CanAddStream () {
670672 uint32_t maxConcurrentStreams =
671673 nghttp2_session_get_local_settings (
672- session_, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
674+ session_. get () , NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
673675 size_t maxSize =
674676 std::min (streams_.max_size (), static_cast <size_t >(maxConcurrentStreams));
675677 // We can add a new stream so long as we are less than the current
@@ -735,10 +737,10 @@ ssize_t Http2Session::ConsumeHTTP2Data() {
735737 // multiple side effects.
736738 Debug (this , " receiving %d bytes [wants data? %d]" ,
737739 read_len,
738- nghttp2_session_want_read (session_));
740+ nghttp2_session_want_read (session_. get () ));
739741 flags_ &= ~SESSION_STATE_NGHTTP2_RECV_PAUSED;
740742 ssize_t ret =
741- nghttp2_session_mem_recv (session_,
743+ nghttp2_session_mem_recv (session_. get () ,
742744 reinterpret_cast <uint8_t *>(stream_buf_.base ) +
743745 stream_buf_offset_,
744746 read_len);
@@ -1437,7 +1439,7 @@ void Http2Session::OnStreamAfterWrite(WriteWrap* w, int status) {
14371439
14381440 if ((flags_ & SESSION_STATE_READING_STOPPED) &&
14391441 !(flags_ & SESSION_STATE_WRITE_IN_PROGRESS) &&
1440- nghttp2_session_want_read (session_)) {
1442+ nghttp2_session_want_read (session_. get () )) {
14411443 flags_ &= ~SESSION_STATE_READING_STOPPED;
14421444 stream_->ReadStart ();
14431445 }
@@ -1465,16 +1467,16 @@ void Http2Session::OnStreamAfterWrite(WriteWrap* w, int status) {
14651467// queue), but only if a write has not already been scheduled.
14661468void Http2Session::MaybeScheduleWrite () {
14671469 CHECK_EQ (flags_ & SESSION_STATE_WRITE_SCHEDULED, 0 );
1468- if (UNLIKELY (session_ == nullptr ))
1470+ if (UNLIKELY (! session_))
14691471 return ;
14701472
1471- if (nghttp2_session_want_write (session_)) {
1473+ if (nghttp2_session_want_write (session_. get () )) {
14721474 HandleScope handle_scope (env ()->isolate ());
14731475 Debug (this , " scheduling write" );
14741476 flags_ |= SESSION_STATE_WRITE_SCHEDULED;
14751477 BaseObjectPtr<Http2Session> strong_ref{this };
14761478 env ()->SetImmediate ([this , strong_ref](Environment* env) {
1477- if (session_ == nullptr || !(flags_ & SESSION_STATE_WRITE_SCHEDULED)) {
1479+ if (! session_ || !(flags_ & SESSION_STATE_WRITE_SCHEDULED)) {
14781480 // This can happen e.g. when a stream was reset before this turn
14791481 // of the event loop, in which case SendPendingData() is called early,
14801482 // or the session was destroyed in the meantime.
@@ -1492,7 +1494,7 @@ void Http2Session::MaybeScheduleWrite() {
14921494
14931495void Http2Session::MaybeStopReading () {
14941496 if (flags_ & SESSION_STATE_READING_STOPPED) return ;
1495- int want_read = nghttp2_session_want_read (session_);
1497+ int want_read = nghttp2_session_want_read (session_. get () );
14961498 Debug (this , " wants read? %d" , want_read);
14971499 if (want_read == 0 || (flags_ & SESSION_STATE_WRITE_IN_PROGRESS)) {
14981500 flags_ |= SESSION_STATE_READING_STOPPED;
@@ -1590,7 +1592,7 @@ uint8_t Http2Session::SendPendingData() {
15901592
15911593 // Part One: Gather data from nghttp2
15921594
1593- while ((src_length = nghttp2_session_mem_send (session_, &src)) > 0 ) {
1595+ while ((src_length = nghttp2_session_mem_send (session_. get () , &src)) > 0 ) {
15941596 Debug (this , " nghttp2 has %d bytes to send" , src_length);
15951597 CopyDataIntoOutgoing (src, src_length);
15961598 }
@@ -1715,7 +1717,7 @@ Http2Stream* Http2Session::SubmitRequest(
17151717 Http2Stream* stream = nullptr ;
17161718 Http2Stream::Provider::Stream prov (options);
17171719 *ret = nghttp2_submit_request (
1718- session_,
1720+ session_. get () ,
17191721 prispec,
17201722 headers.data (),
17211723 headers.length (),
@@ -2485,9 +2487,9 @@ void Http2Session::Goaway(uint32_t code,
24852487 Http2Scope h2scope (this );
24862488 // the last proc stream id is the most recently created Http2Stream.
24872489 if (lastStreamID <= 0 )
2488- lastStreamID = nghttp2_session_get_last_proc_stream_id (session_);
2490+ lastStreamID = nghttp2_session_get_last_proc_stream_id (session_. get () );
24892491 Debug (this , " submitting goaway" );
2490- nghttp2_submit_goaway (session_, NGHTTP2_FLAG_NONE,
2492+ nghttp2_submit_goaway (session_. get () , NGHTTP2_FLAG_NONE,
24912493 lastStreamID, code, data, len);
24922494}
24932495
@@ -2676,13 +2678,16 @@ void Http2Session::AltSvc(int32_t id,
26762678 uint8_t * value,
26772679 size_t value_len) {
26782680 Http2Scope h2scope (this );
2679- CHECK_EQ (nghttp2_submit_altsvc (session_, NGHTTP2_FLAG_NONE, id,
2681+ CHECK_EQ (nghttp2_submit_altsvc (session_. get () , NGHTTP2_FLAG_NONE, id,
26802682 origin, origin_len, value, value_len), 0 );
26812683}
26822684
26832685void Http2Session::Origin (nghttp2_origin_entry* ov, size_t count) {
26842686 Http2Scope h2scope (this );
2685- CHECK_EQ (nghttp2_submit_origin (session_, NGHTTP2_FLAG_NONE, ov, count), 0 );
2687+ CHECK_EQ (nghttp2_submit_origin (
2688+ session_.get (),
2689+ NGHTTP2_FLAG_NONE,
2690+ ov, count), 0 );
26862691}
26872692
26882693// Submits an AltSvc frame to be sent to the connected peer.
0 commit comments