@@ -69,6 +69,117 @@ Http2Options::Http2Options(Environment* env) {
6969 }
7070}
7171
72+ Http2Settings::Http2Settings (Environment* env) : env_(env) {
73+ entries_.AllocateSufficientStorage (IDX_SETTINGS_COUNT);
74+ AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
75+ env->http2_state ()->settings_buffer ;
76+ uint32_t flags = buffer[IDX_SETTINGS_COUNT];
77+
78+ size_t n = 0 ;
79+
80+ if (flags & (1 << IDX_SETTINGS_HEADER_TABLE_SIZE)) {
81+ uint32_t val = buffer[IDX_SETTINGS_HEADER_TABLE_SIZE];
82+ DEBUG_HTTP2 (" Setting header table size: %d\n " , val);
83+ entries_[n].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
84+ entries_[n].value = val;
85+ n++;
86+ }
87+
88+ if (flags & (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS)) {
89+ uint32_t val = buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS];
90+ DEBUG_HTTP2 (" Setting max concurrent streams: %d\n " , val);
91+ entries_[n].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
92+ entries_[n].value = val;
93+ n++;
94+ }
95+
96+ if (flags & (1 << IDX_SETTINGS_MAX_FRAME_SIZE)) {
97+ uint32_t val = buffer[IDX_SETTINGS_MAX_FRAME_SIZE];
98+ DEBUG_HTTP2 (" Setting max frame size: %d\n " , val);
99+ entries_[n].settings_id = NGHTTP2_SETTINGS_MAX_FRAME_SIZE;
100+ entries_[n].value = val;
101+ n++;
102+ }
103+
104+ if (flags & (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE)) {
105+ uint32_t val = buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE];
106+ DEBUG_HTTP2 (" Setting initial window size: %d\n " , val);
107+ entries_[n].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
108+ entries_[n].value = val;
109+ n++;
110+ }
111+
112+ if (flags & (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) {
113+ uint32_t val = buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE];
114+ DEBUG_HTTP2 (" Setting max header list size: %d\n " , val);
115+ entries_[n].settings_id = NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE;
116+ entries_[n].value = val;
117+ n++;
118+ }
119+
120+ if (flags & (1 << IDX_SETTINGS_ENABLE_PUSH)) {
121+ uint32_t val = buffer[IDX_SETTINGS_ENABLE_PUSH];
122+ DEBUG_HTTP2 (" Setting enable push: %d\n " , val);
123+ entries_[n].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
124+ entries_[n].value = val;
125+ n++;
126+ }
127+
128+ count_ = n;
129+ }
130+
131+ inline Local<Value> Http2Settings::Pack () {
132+ const size_t len = count_ * 6 ;
133+ Local<Value> buf = Buffer::New (env_, len).ToLocalChecked ();
134+ ssize_t ret =
135+ nghttp2_pack_settings_payload (
136+ reinterpret_cast <uint8_t *>(Buffer::Data (buf)), len,
137+ *entries_, count_);
138+ if (ret >= 0 )
139+ return buf;
140+ else
141+ return Undefined (env_->isolate ());
142+ }
143+
144+ inline void Http2Settings::Update (Environment* env,
145+ Http2Session* session,
146+ get_setting fn) {
147+ AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
148+ env->http2_state ()->settings_buffer ;
149+ buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
150+ fn (session->session (), NGHTTP2_SETTINGS_HEADER_TABLE_SIZE);
151+ buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] =
152+ fn (session->session (), NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
153+ buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] =
154+ fn (session->session (), NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
155+ buffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
156+ fn (session->session (), NGHTTP2_SETTINGS_MAX_FRAME_SIZE);
157+ buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
158+ fn (session->session (), NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE);
159+ buffer[IDX_SETTINGS_ENABLE_PUSH] =
160+ fn (session->session (), NGHTTP2_SETTINGS_ENABLE_PUSH);
161+ }
162+
163+
164+ inline void Http2Settings::RefreshDefaults (Environment* env) {
165+ AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
166+ env->http2_state ()->settings_buffer ;
167+
168+ buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
169+ DEFAULT_SETTINGS_HEADER_TABLE_SIZE;
170+ buffer[IDX_SETTINGS_ENABLE_PUSH] =
171+ DEFAULT_SETTINGS_ENABLE_PUSH;
172+ buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] =
173+ DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE;
174+ buffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
175+ DEFAULT_SETTINGS_MAX_FRAME_SIZE;
176+ buffer[IDX_SETTINGS_COUNT] =
177+ (1 << IDX_SETTINGS_HEADER_TABLE_SIZE) |
178+ (1 << IDX_SETTINGS_ENABLE_PUSH) |
179+ (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE) |
180+ (1 << IDX_SETTINGS_MAX_FRAME_SIZE);
181+ }
182+
72183
73184Http2Session::Http2Session (Environment* env,
74185 Local<Object> wrap,
@@ -178,119 +289,24 @@ void HttpErrorString(const FunctionCallbackInfo<Value>& args) {
178289// output for an HTTP2-Settings header field.
179290void PackSettings (const FunctionCallbackInfo<Value>& args) {
180291 Environment* env = Environment::GetCurrent (args);
181- HandleScope scope (env->isolate ());
182-
183- std::vector<nghttp2_settings_entry> entries;
184- entries.reserve (6 );
185-
186- AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
187- env->http2_state ()->settings_buffer ;
188- uint32_t flags = buffer[IDX_SETTINGS_COUNT];
189-
190- if (flags & (1 << IDX_SETTINGS_HEADER_TABLE_SIZE)) {
191- DEBUG_HTTP2 (" Setting header table size: %d\n " ,
192- static_cast <uint32_t >(buffer[IDX_SETTINGS_HEADER_TABLE_SIZE]));
193- entries.push_back ({NGHTTP2_SETTINGS_HEADER_TABLE_SIZE,
194- buffer[IDX_SETTINGS_HEADER_TABLE_SIZE]});
195- }
196-
197- if (flags & (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS)) {
198- DEBUG_HTTP2 (" Setting max concurrent streams: %d\n " ,
199- static_cast <uint32_t >(
200- buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS]));
201- entries.push_back ({NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
202- buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS]});
203- }
204-
205- if (flags & (1 << IDX_SETTINGS_MAX_FRAME_SIZE)) {
206- DEBUG_HTTP2 (" Setting max frame size: %d\n " ,
207- static_cast <uint32_t >(buffer[IDX_SETTINGS_MAX_FRAME_SIZE]));
208- entries.push_back ({NGHTTP2_SETTINGS_MAX_FRAME_SIZE,
209- buffer[IDX_SETTINGS_MAX_FRAME_SIZE]});
210- }
211-
212- if (flags & (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE)) {
213- DEBUG_HTTP2 (" Setting initial window size: %d\n " ,
214- static_cast <uint32_t >(
215- buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE]));
216- entries.push_back ({NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
217- buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE]});
218- }
219-
220- if (flags & (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) {
221- DEBUG_HTTP2 (" Setting max header list size: %d\n " ,
222- static_cast <uint32_t >(
223- buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE]));
224- entries.push_back ({NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
225- buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE]});
226- }
227-
228- if (flags & (1 << IDX_SETTINGS_ENABLE_PUSH)) {
229- DEBUG_HTTP2 (" Setting enable push: %d\n " ,
230- static_cast <uint32_t >(buffer[IDX_SETTINGS_ENABLE_PUSH]));
231- entries.push_back ({NGHTTP2_SETTINGS_ENABLE_PUSH,
232- buffer[IDX_SETTINGS_ENABLE_PUSH]});
233- }
234-
235- const size_t len = entries.size () * 6 ;
236- MaybeStackBuffer<char > buf (len);
237- ssize_t ret =
238- nghttp2_pack_settings_payload (
239- reinterpret_cast <uint8_t *>(*buf), len, &entries[0 ], entries.size ());
240- if (ret >= 0 ) {
241- args.GetReturnValue ().Set (
242- Buffer::Copy (env, *buf, len).ToLocalChecked ());
243- }
292+ Http2Settings settings (env);
293+ args.GetReturnValue ().Set (settings.Pack ());
244294}
245295
246296// Used to fill in the spec defined initial values for each setting.
247297void RefreshDefaultSettings (const FunctionCallbackInfo<Value>& args) {
248298 DEBUG_HTTP2 (" Http2Session: refreshing default settings\n " );
249299 Environment* env = Environment::GetCurrent (args);
250- AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
251- env->http2_state ()->settings_buffer ;
252-
253- buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
254- DEFAULT_SETTINGS_HEADER_TABLE_SIZE;
255- buffer[IDX_SETTINGS_ENABLE_PUSH] =
256- DEFAULT_SETTINGS_ENABLE_PUSH;
257- buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] =
258- DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE;
259- buffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
260- DEFAULT_SETTINGS_MAX_FRAME_SIZE;
261- buffer[IDX_SETTINGS_COUNT] =
262- (1 << IDX_SETTINGS_HEADER_TABLE_SIZE) |
263- (1 << IDX_SETTINGS_ENABLE_PUSH) |
264- (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE) |
265- (1 << IDX_SETTINGS_MAX_FRAME_SIZE);
300+ Http2Settings::RefreshDefaults (env);
266301}
267302
268303template <get_setting fn>
269- void RefreshSettings (const FunctionCallbackInfo<Value>& args) {
304+ void Http2Session:: RefreshSettings (const FunctionCallbackInfo<Value>& args) {
270305 DEBUG_HTTP2 (" Http2Session: refreshing settings for session\n " );
271306 Environment* env = Environment::GetCurrent (args);
272- #if defined(DEBUG) && DEBUG
273- CHECK_EQ (args.Length (), 1 );
274- CHECK (args[0 ]->IsObject ());
275- #endif
276307 Http2Session* session;
277- ASSIGN_OR_RETURN_UNWRAP (&session, args[0 ].As <Object>());
278- nghttp2_session* s = session->session ();
279-
280- AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
281- env->http2_state ()->settings_buffer ;
282- buffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
283- fn (s, NGHTTP2_SETTINGS_HEADER_TABLE_SIZE);
284- buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] =
285- fn (s, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
286- buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] =
287- fn (s, NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
288- buffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
289- fn (s, NGHTTP2_SETTINGS_MAX_FRAME_SIZE);
290- buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
291- fn (s, NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE);
292- buffer[IDX_SETTINGS_ENABLE_PUSH] =
293- fn (s, NGHTTP2_SETTINGS_ENABLE_PUSH);
308+ ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
309+ Http2Settings::Update (env, session, fn);
294310}
295311
296312// Used to fill in the spec defined initial values for each setting.
@@ -460,65 +476,9 @@ void Http2Session::SubmitSettings(const FunctionCallbackInfo<Value>& args) {
460476 ASSIGN_OR_RETURN_UNWRAP (&session, args.Holder ());
461477 Environment* env = session->env ();
462478
463- AliasedBuffer<uint32_t , v8::Uint32Array>& buffer =
464- env->http2_state ()->settings_buffer ;
465- uint32_t flags = buffer[IDX_SETTINGS_COUNT];
466-
467- std::vector<nghttp2_settings_entry> entries;
468- entries.reserve (6 );
469-
470- if (flags & (1 << IDX_SETTINGS_HEADER_TABLE_SIZE)) {
471- DEBUG_HTTP2 (" Setting header table size: %d\n " ,
472- static_cast <uint32_t >(buffer[IDX_SETTINGS_HEADER_TABLE_SIZE]));
473- entries.push_back ({NGHTTP2_SETTINGS_HEADER_TABLE_SIZE,
474- buffer[IDX_SETTINGS_HEADER_TABLE_SIZE]});
475- }
476-
477- if (flags & (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS)) {
478- DEBUG_HTTP2 (" Setting max concurrent streams: %d\n " ,
479- static_cast <uint32_t >(
480- buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS]));
481- entries.push_back ({NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
482- buffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS]});
483- }
484-
485- if (flags & (1 << IDX_SETTINGS_MAX_FRAME_SIZE)) {
486- DEBUG_HTTP2 (" Setting max frame size: %d\n " ,
487- static_cast <uint32_t >(buffer[IDX_SETTINGS_MAX_FRAME_SIZE]));
488- entries.push_back ({NGHTTP2_SETTINGS_MAX_FRAME_SIZE,
489- buffer[IDX_SETTINGS_MAX_FRAME_SIZE]});
490- }
491-
492- if (flags & (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE)) {
493- DEBUG_HTTP2 (" Setting initial window size: %d\n " ,
494- static_cast <uint32_t >(
495- buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE]));
496- entries.push_back ({NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
497- buffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE]});
498- }
499-
500- if (flags & (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) {
501- DEBUG_HTTP2 (" Setting max header list size: %d\n " ,
502- static_cast <uint32_t >(
503- buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE]));
504- entries.push_back ({NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
505- buffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE]});
506- }
507-
508- if (flags & (1 << IDX_SETTINGS_ENABLE_PUSH)) {
509- DEBUG_HTTP2 (" Setting enable push: %d\n " ,
510- static_cast <uint32_t >(buffer[IDX_SETTINGS_ENABLE_PUSH]));
511- entries.push_back ({NGHTTP2_SETTINGS_ENABLE_PUSH,
512- buffer[IDX_SETTINGS_ENABLE_PUSH]});
513- }
514-
515- if (entries.size () > 0 ) {
516- args.GetReturnValue ().Set (
517- session->Nghttp2Session ::SubmitSettings (&entries[0 ], entries.size ()));
518- } else {
519- args.GetReturnValue ().Set (
520- session->Nghttp2Session ::SubmitSettings (nullptr , 0 ));
521- }
479+ Http2Settings settings (env);
480+ args.GetReturnValue ().Set (
481+ session->Nghttp2Session ::SubmitSettings (*settings, settings.length ()));
522482}
523483
524484void Http2Session::SubmitRstStream (const FunctionCallbackInfo<Value>& args) {
@@ -1327,6 +1287,12 @@ void Initialize(Local<Object> target,
13271287 Http2Session::FlushData);
13281288 env->SetProtoMethod (session, " updateChunksSent" ,
13291289 Http2Session::UpdateChunksSent);
1290+ env->SetProtoMethod (
1291+ session, " refreshLocalSettings" ,
1292+ Http2Session::RefreshSettings<nghttp2_session_get_local_settings>);
1293+ env->SetProtoMethod (
1294+ session, " refreshRemoteSettings" ,
1295+ Http2Session::RefreshSettings<nghttp2_session_get_remote_settings>);
13301296 StreamBase::AddMethods<Http2Session>(env, session,
13311297 StreamBase::kFlagHasWritev |
13321298 StreamBase::kFlagNoShutdown );
@@ -1416,10 +1382,6 @@ HTTP_KNOWN_METHODS(STRING_CONSTANT)
14161382HTTP_STATUS_CODES (V)
14171383#undef V
14181384
1419- env->SetMethod (target, " refreshLocalSettings" ,
1420- RefreshSettings<nghttp2_session_get_local_settings>);
1421- env->SetMethod (target, " refreshRemoteSettings" ,
1422- RefreshSettings<nghttp2_session_get_remote_settings>);
14231385 env->SetMethod (target, " refreshDefaultSettings" , RefreshDefaultSettings);
14241386 env->SetMethod (target, " refreshSessionState" , RefreshSessionState);
14251387 env->SetMethod (target, " refreshStreamState" , RefreshStreamState);
0 commit comments