GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_http2.h Lines: 201 209 96.2 %
Date: 2020-06-24 22:13:30 Branches: 33 40 82.5 %

Line Branch Exec Source
1
#ifndef SRC_NODE_HTTP2_H_
2
#define SRC_NODE_HTTP2_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
// FIXME(joyeecheung): nghttp2.h needs stdint.h to compile on Windows
7
#include <cstdint>
8
#include "nghttp2/nghttp2.h"
9
10
#include "allocated_buffer.h"
11
#include "aliased_struct.h"
12
#include "node_http2_state.h"
13
#include "node_http_common.h"
14
#include "node_mem.h"
15
#include "node_perf.h"
16
#include "stream_base.h"
17
#include "string_bytes.h"
18
19
#include <algorithm>
20
#include <queue>
21
22
namespace node {
23
namespace http2 {
24
25
// Constants in all caps are exported as user-facing constants
26
// in JavaScript. Constants using the kName pattern are internal
27
// only.
28
29
// We strictly limit the number of outstanding unacknowledged PINGS a user
30
// may send in order to prevent abuse. The current default cap is 10. The
31
// user may set a different limit using a per Http2Session configuration
32
// option.
33
constexpr size_t kDefaultMaxPings = 10;
34
35
// Also strictly limit the number of outstanding SETTINGS frames a user sends
36
constexpr size_t kDefaultMaxSettings = 10;
37
38
// Default maximum total memory cap for Http2Session.
39
constexpr uint64_t kDefaultMaxSessionMemory = 10000000;
40
41
// These are the standard HTTP/2 defaults as specified by the RFC
42
constexpr uint32_t DEFAULT_SETTINGS_HEADER_TABLE_SIZE = 4096;
43
constexpr uint32_t DEFAULT_SETTINGS_ENABLE_PUSH = 1;
44
constexpr uint32_t DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS = 0xffffffffu;
45
constexpr uint32_t DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE = 65535;
46
constexpr uint32_t DEFAULT_SETTINGS_MAX_FRAME_SIZE = 16384;
47
constexpr uint32_t DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE = 65535;
48
constexpr uint32_t DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0;
49
constexpr uint32_t MAX_MAX_FRAME_SIZE = 16777215;
50
constexpr uint32_t MIN_MAX_FRAME_SIZE = DEFAULT_SETTINGS_MAX_FRAME_SIZE;
51
constexpr uint32_t MAX_INITIAL_WINDOW_SIZE = 2147483647;
52
53
// Stream is not going to have any DATA frames
54
constexpr int STREAM_OPTION_EMPTY_PAYLOAD = 0x1;
55
56
// Stream might have trailing headers
57
constexpr int STREAM_OPTION_GET_TRAILERS = 0x2;
58
59
// Http2Stream internal states
60
constexpr int kStreamStateNone = 0x0;
61
constexpr int kStreamStateShut = 0x1;
62
constexpr int kStreamStateReadStart = 0x2;
63
constexpr int kStreamStateReadPaused = 0x4;
64
constexpr int kStreamStateClosed = 0x8;
65
constexpr int kStreamStateDestroyed = 0x10;
66
constexpr int kStreamStateTrailers = 0x20;
67
68
// Http2Session internal states
69
constexpr int kSessionStateNone = 0x0;
70
constexpr int kSessionStateHasScope = 0x1;
71
constexpr int kSessionStateWriteScheduled = 0x2;
72
constexpr int kSessionStateClosed = 0x4;
73
constexpr int kSessionStateClosing = 0x8;
74
constexpr int kSessionStateSending = 0x10;
75
constexpr int kSessionStateWriteInProgress = 0x20;
76
constexpr int kSessionStateReadingStopped = 0x40;
77
constexpr int kSessionStateReceivePaused = 0x80;
78
79
// The Padding Strategy determines the method by which extra padding is
80
// selected for HEADERS and DATA frames. These are configurable via the
81
// options passed in to a Http2Session object.
82
enum PaddingStrategy {
83
  // No padding strategy. This is the default.
84
  PADDING_STRATEGY_NONE,
85
  // Attempts to ensure that the frame is 8-byte aligned
86
  PADDING_STRATEGY_ALIGNED,
87
  // Padding will ensure all data frames are maxFrameSize
88
  PADDING_STRATEGY_MAX,
89
  // Removed and turned into an alias because it is unreasonably expensive for
90
  // very little benefit.
91
  PADDING_STRATEGY_CALLBACK = PADDING_STRATEGY_ALIGNED
92
};
93
94
enum SessionType {
95
  NGHTTP2_SESSION_SERVER,
96
  NGHTTP2_SESSION_CLIENT
97
};
98
99
template <typename T, void(*fn)(T*)>
100
struct Nghttp2Deleter {
101
10028
  void operator()(T* ptr) const noexcept { fn(ptr); }
102
};
103
104
using Nghttp2OptionPointer =
105
    std::unique_ptr<nghttp2_option,
106
                    Nghttp2Deleter<nghttp2_option, nghttp2_option_del>>;
107
108
using Nghttp2SessionPointer =
109
    std::unique_ptr<nghttp2_session,
110
                    Nghttp2Deleter<nghttp2_session, nghttp2_session_del>>;
111
112
using Nghttp2SessionCallbacksPointer =
113
    std::unique_ptr<nghttp2_session_callbacks,
114
                    Nghttp2Deleter<nghttp2_session_callbacks,
115
                                   nghttp2_session_callbacks_del>>;
116
117
struct Http2HeadersTraits {
118
  typedef nghttp2_nv nv_t;
119
  static const uint8_t kNoneFlag = NGHTTP2_NV_FLAG_NONE;
120
};
121
122
struct Http2RcBufferPointerTraits {
123
  typedef nghttp2_rcbuf rcbuf_t;
124
  typedef nghttp2_vec vector_t;
125
126
312287
  static void inc(rcbuf_t* buf) {
127
312287
    CHECK_NOT_NULL(buf);
128
312287
    nghttp2_rcbuf_incref(buf);
129
312287
  }
130
312287
  static void dec(rcbuf_t* buf) {
131
312287
    CHECK_NOT_NULL(buf);
132
312287
    nghttp2_rcbuf_decref(buf);
133
312287
  }
134
513576
  static vector_t get_vec(rcbuf_t* buf) {
135
513576
    CHECK_NOT_NULL(buf);
136
513576
    return nghttp2_rcbuf_get_buf(buf);
137
  }
138
143464
  static bool is_static(const rcbuf_t* buf) {
139
143464
    CHECK_NOT_NULL(buf);
140
143464
    return nghttp2_rcbuf_is_static(buf);
141
  }
142
};
143
144
using Http2Headers = NgHeaders<Http2HeadersTraits>;
145
using Http2RcBufferPointer = NgRcBufPointer<Http2RcBufferPointerTraits>;
146
147
481482
struct NgHttp2StreamWrite : public MemoryRetainer {
148
  WriteWrap* req_wrap = nullptr;
149
  uv_buf_t buf;
150
151
65615
  inline explicit NgHttp2StreamWrite(uv_buf_t buf_) : buf(buf_) {}
152
27497
  inline NgHttp2StreamWrite(WriteWrap* req, uv_buf_t buf_) :
153
27497
      req_wrap(req), buf(buf_) {}
154
155
  void MemoryInfo(MemoryTracker* tracker) const override;
156
  SET_MEMORY_INFO_NAME(NgHttp2StreamWrite)
157
  SET_SELF_SIZE(NgHttp2StreamWrite)
158
};
159
160
typedef uint32_t(*get_setting)(nghttp2_session* session,
161
                               nghttp2_settings_id id);
162
163
class Http2Ping;
164
class Http2Session;
165
class Http2Settings;
166
class Http2Stream;
167
class Origins;
168
169
// This scope should be present when any call into nghttp2 that may schedule
170
// data to be written to the underlying transport is made, and schedules
171
// such a write automatically once the scope is exited.
172
class Http2Scope {
173
 public:
174
  explicit Http2Scope(Http2Stream* stream);
175
  explicit Http2Scope(Http2Session* session);
176
  ~Http2Scope();
177
178
 private:
179
  BaseObjectPtr<Http2Session> session_;
180
};
181
182
// The Http2Options class is used to parse the options object passed in to
183
// a Http2Session object and convert those into an appropriate nghttp2_option
184
// struct. This is the primary mechanism by which the Http2Session object is
185
// configured.
186
class Http2Options {
187
 public:
188
  Http2Options(Http2State* http2_state,
189
               SessionType type);
190
191
615
  ~Http2Options() = default;
192
193
615
  nghttp2_option* operator*() const {
194
615
    return options_.get();
195
  }
196
197
1
  void set_max_header_pairs(uint32_t max) {
198
1
    max_header_pairs_ = max;
199
1
  }
200
201
615
  uint32_t max_header_pairs() const {
202
615
    return max_header_pairs_;
203
  }
204
205
2
  void set_padding_strategy(PaddingStrategy val) {
206
2
    padding_strategy_ = val;
207
2
  }
208
209
615
  PaddingStrategy padding_strategy() const {
210
615
    return padding_strategy_;
211
  }
212
213
2
  void set_max_outstanding_pings(size_t max) {
214
2
    max_outstanding_pings_ = max;
215
2
  }
216
217
615
  size_t max_outstanding_pings() const {
218
615
    return max_outstanding_pings_;
219
  }
220
221
2
  void set_max_outstanding_settings(size_t max) {
222
2
    max_outstanding_settings_ = max;
223
2
  }
224
225
615
  size_t max_outstanding_settings() const {
226
615
    return max_outstanding_settings_;
227
  }
228
229
6
  void set_max_session_memory(uint64_t max) {
230
6
    max_session_memory_ = max;
231
6
  }
232
233
615
  uint64_t max_session_memory() const {
234
615
    return max_session_memory_;
235
  }
236
237
 private:
238
  Nghttp2OptionPointer options_;
239
  uint64_t max_session_memory_ = kDefaultMaxSessionMemory;
240
  uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS;
241
  PaddingStrategy padding_strategy_ = PADDING_STRATEGY_NONE;
242
  size_t max_outstanding_pings_ = kDefaultMaxPings;
243
  size_t max_outstanding_settings_ = kDefaultMaxSettings;
244
};
245
246
struct Http2Priority : public nghttp2_priority_spec {
247
  Http2Priority(Environment* env,
248
                v8::Local<v8::Value> parent,
249
                v8::Local<v8::Value> weight,
250
                v8::Local<v8::Value> exclusive);
251
};
252
253
47528
class Http2StreamListener : public StreamListener {
254
 public:
255
  uv_buf_t OnStreamAlloc(size_t suggested_size) override;
256
  void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override;
257
};
258
259
struct Http2HeaderTraits {
260
  typedef Http2RcBufferPointer rcbufferpointer_t;
261
  typedef Http2Session allocator_t;
262
263
  // HTTP/2 does not support identifying header names by token id.
264
  // HTTP/3 will, however, so we prepare for that now.
265
71732
  static const char* ToHttpHeaderName(int32_t token) { return nullptr; }
266
};
267
268
using Http2Header = NgHeader<Http2HeaderTraits>;
269
270
class Http2Stream : public AsyncWrap,
271
                    public StreamBase {
272
 public:
273
  static Http2Stream* New(
274
      Http2Session* session,
275
      int32_t id,
276
      nghttp2_headers_category category = NGHTTP2_HCAT_HEADERS,
277
      int options = 0);
278
  ~Http2Stream() override;
279
280
  nghttp2_stream* operator*() const;
281
282
  nghttp2_stream* stream() const;
283
284
160866
  Http2Session* session() { return session_.get(); }
285
18
  const Http2Session* session() const { return session_.get(); }
286
287
  // Required for StreamBase
288
  int ReadStart() override;
289
290
  // Required for StreamBase
291
  int ReadStop() override;
292
293
  // Required for StreamBase
294
  ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override;
295
  int DoShutdown(ShutdownWrap* req_wrap) override;
296
297
15
  bool HasWantsWrite() const override { return true; }
298
299
  // Initiate a response on this stream.
300
  int SubmitResponse(const Http2Headers& headers, int options);
301
302
  // Submit informational headers for this stream
303
  int SubmitInfo(const Http2Headers& headers);
304
305
  // Submit trailing headers for this stream
306
  int SubmitTrailers(const Http2Headers& headers);
307
  void OnTrailers();
308
309
  // Submit a PRIORITY frame for this stream
310
  int SubmitPriority(const Http2Priority& priority, bool silent = false);
311
312
  // Submits an RST_STREAM frame using the given code
313
  void SubmitRstStream(const uint32_t code);
314
315
  void FlushRstStream();
316
317
  // Submits a PUSH_PROMISE frame with this stream as the parent.
318
  Http2Stream* SubmitPushPromise(
319
      const Http2Headers& headers,
320
      int32_t* ret,
321
      int options = 0);
322
323
324
  void Close(int32_t code);
325
326
  // Destroy this stream instance and free all held memory.
327
  void Destroy();
328
329
388848
  bool is_destroyed() const {
330
388848
    return flags_ & kStreamStateDestroyed;
331
  }
332
333
51759
  bool is_writable() const {
334
51759
    return !(flags_ & kStreamStateShut);
335
  }
336
337
23499
  bool is_paused() const {
338
23499
    return flags_ & kStreamStateReadPaused;
339
  }
340
341
  bool is_closed() const {
342
    return flags_ & kStreamStateClosed;
343
  }
344
345
12614
  bool has_trailers() const {
346
12614
    return flags_ & kStreamStateTrailers;
347
  }
348
349
210
  void set_has_trailers(bool on = true) {
350
210
    if (on)
351
176
      flags_ |= kStreamStateTrailers;
352
    else
353
34
      flags_ &= ~kStreamStateTrailers;
354
210
  }
355
356
23666
  void set_closed() {
357
23666
    flags_ |= kStreamStateClosed;
358
23666
  }
359
360
23745
  void set_destroyed() {
361
23745
    flags_ |= kStreamStateDestroyed;
362
23745
  }
363
364
24079
  void set_not_writable() {
365
24079
    flags_ |= kStreamStateShut;
366
24079
  }
367
368
23494
  void set_reading(bool on = true) {
369
23494
    if (on) {
370
23494
      flags_ |= kStreamStateReadStart;
371
23494
      set_paused(false);
372
    } else {}
373
23494
  }
374
375
34055
  void set_paused(bool on = true) {
376
34055
    if (on)
377
10561
      flags_ |= kStreamStateReadPaused;
378
    else
379
23494
      flags_ &= ~kStreamStateReadPaused;
380
34055
  }
381
382
  // Returns true if this stream is in the reading state, which occurs when
383
  // the kStreamStateReadStart flag has been set and the
384
  // kStreamStateReadPaused flag is *not* set.
385
26574
  bool is_reading() const {
386

26574
    return flags_ & kStreamStateReadStart && !is_paused();
387
  }
388
389
  // Returns the RST_STREAM code used to close this stream
390
  int32_t code() const { return code_; }
391
392
  // Returns the stream identifier for this stream
393
76562
  int32_t id() const { return id_; }
394
395
  void IncrementAvailableOutboundLength(size_t amount);
396
  void DecrementAvailableOutboundLength(size_t amount);
397
398
  bool AddHeader(nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t flags);
399
400
  template <typename Fn>
401
23445
  void TransferHeaders(Fn&& fn) {
402
23445
    size_t i = 0;
403
95177
    for (const auto& header : current_headers_ )
404
71732
      fn(header, i++);
405
23445
    current_headers_.clear();
406
23445
  }
407
408
46890
  size_t headers_count() const {
409
46890
    return current_headers_.size();
410
  }
411
412
23445
  nghttp2_headers_category headers_category() const {
413
23445
    return current_headers_category_;
414
  }
415
416
  void StartHeaders(nghttp2_headers_category category);
417
418
  // Required for StreamBase
419
63299
  bool IsAlive() override {
420
63299
    return true;
421
  }
422
423
  // Required for StreamBase
424
  bool IsClosing() override {
425
    return false;
426
  }
427
428
144803
  AsyncWrap* GetAsyncWrap() override { return this; }
429
430
  int DoWrite(WriteWrap* w, uv_buf_t* bufs, size_t count,
431
              uv_stream_t* send_handle) override;
432
433
  void MemoryInfo(MemoryTracker* tracker) const override;
434
  SET_MEMORY_INFO_NAME(Http2Stream)
435
  SET_SELF_SIZE(Http2Stream)
436
437
  std::string diagnostic_name() const override;
438
439
  // JavaScript API
440
  static void GetID(const v8::FunctionCallbackInfo<v8::Value>& args);
441
  static void Destroy(const v8::FunctionCallbackInfo<v8::Value>& args);
442
  static void Priority(const v8::FunctionCallbackInfo<v8::Value>& args);
443
  static void PushPromise(const v8::FunctionCallbackInfo<v8::Value>& args);
444
  static void RefreshState(const v8::FunctionCallbackInfo<v8::Value>& args);
445
  static void Info(const v8::FunctionCallbackInfo<v8::Value>& args);
446
  static void Trailers(const v8::FunctionCallbackInfo<v8::Value>& args);
447
  static void Respond(const v8::FunctionCallbackInfo<v8::Value>& args);
448
  static void RstStream(const v8::FunctionCallbackInfo<v8::Value>& args);
449
450
  class Provider;
451
452
  struct Statistics {
453
    uint64_t start_time;
454
    uint64_t end_time;
455
    uint64_t first_header;     // Time first header was received
456
    uint64_t first_byte;       // Time first DATA frame byte was received
457
    uint64_t first_byte_sent;  // Time first DATA frame byte was sent
458
    uint64_t sent_bytes;
459
    uint64_t received_bytes;
460
  };
461
462
  Statistics statistics_ = {};
463
464
 private:
465
  Http2Stream(Http2Session* session,
466
              v8::Local<v8::Object> obj,
467
              int32_t id,
468
              nghttp2_headers_category category,
469
              int options);
470
471
  void EmitStatistics();
472
473
  BaseObjectWeakPtr<Http2Session> session_;     // The Parent HTTP/2 Session
474
  int32_t id_ = 0;                              // The Stream Identifier
475
  int32_t code_ = NGHTTP2_NO_ERROR;             // The RST_STREAM code (if any)
476
  int flags_ = kStreamStateNone;        // Internal state flags
477
478
  uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS;
479
  uint32_t max_header_length_ = DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE;
480
481
  // The Current Headers block... As headers are received for this stream,
482
  // they are temporarily stored here until the OnFrameReceived is called
483
  // signalling the end of the HEADERS frame
484
  nghttp2_headers_category current_headers_category_ = NGHTTP2_HCAT_HEADERS;
485
  uint32_t current_headers_length_ = 0;  // total number of octets
486
  std::vector<Http2Header> current_headers_;
487
488
  // This keeps track of the amount of data read from the socket while the
489
  // socket was in paused mode. When `ReadStart()` is called (and not before
490
  // then), we tell nghttp2 that we consumed that data to get proper
491
  // backpressure handling.
492
  size_t inbound_consumed_data_while_paused_ = 0;
493
494
  // Outbound Data... This is the data written by the JS layer that is
495
  // waiting to be written out to the socket.
496
  std::queue<NgHttp2StreamWrite> queue_;
497
  size_t available_outbound_length_ = 0;
498
499
  Http2StreamListener stream_listener_;
500
501
  friend class Http2Session;
502
};
503
504
class Http2Stream::Provider {
505
 public:
506
  Provider(Http2Stream* stream, int options);
507
  explicit Provider(int options);
508
  virtual ~Provider();
509
510
23499
  nghttp2_data_provider* operator*() {
511
23499
    return !empty_ ? &provider_ : nullptr;
512
  }
513
514
  class FD;
515
  class Stream;
516
 protected:
517
  nghttp2_data_provider provider_;
518
519
 private:
520
  bool empty_ = false;
521
};
522
523
23499
class Http2Stream::Provider::Stream : public Http2Stream::Provider {
524
 public:
525
  Stream(Http2Stream* stream, int options);
526
  explicit Stream(int options);
527
528
  static ssize_t OnRead(nghttp2_session* session,
529
                        int32_t id,
530
                        uint8_t* buf,
531
                        size_t length,
532
                        uint32_t* flags,
533
                        nghttp2_data_source* source,
534
                        void* user_data);
535
};
536
537
615
struct SessionJSFields {
538
  uint8_t bitfield;
539
  uint8_t priority_listener_count;
540
  uint8_t frame_error_listener_count;
541
  uint32_t max_invalid_frames = 1000;
542
  uint32_t max_rejected_streams = 100;
543
};
544
545
// Indices for js_fields_, which serves as a way to communicate data with JS
546
// land fast. In particular, we store information about the number/presence
547
// of certain event listeners in JS, and skip calls from C++ into JS if they
548
// are missing.
549
enum SessionUint8Fields {
550
  kBitfield = offsetof(SessionJSFields, bitfield),  // See below
551
  kSessionPriorityListenerCount =
552
      offsetof(SessionJSFields, priority_listener_count),
553
  kSessionFrameErrorListenerCount =
554
      offsetof(SessionJSFields, frame_error_listener_count),
555
  kSessionMaxInvalidFrames = offsetof(SessionJSFields, max_invalid_frames),
556
  kSessionMaxRejectedStreams = offsetof(SessionJSFields, max_rejected_streams),
557
  kSessionUint8FieldCount = sizeof(SessionJSFields)
558
};
559
560
enum SessionBitfieldFlags {
561
  kSessionHasRemoteSettingsListeners,
562
  kSessionRemoteSettingsIsUpToDate,
563
  kSessionHasPingListeners,
564
  kSessionHasAltsvcListeners
565
};
566
567
class Http2Session : public AsyncWrap,
568
                     public StreamListener,
569
                     public mem::NgLibMemoryManager<Http2Session, nghttp2_mem> {
570
 public:
571
  Http2Session(Http2State* http2_state,
572
               v8::Local<v8::Object> wrap,
573
               SessionType type = NGHTTP2_SESSION_SERVER);
574
  ~Http2Session() override;
575
576
32283
  StreamBase* underlying_stream() {
577
32283
    return static_cast<StreamBase*>(stream_);
578
  }
579
580
  void Close(uint32_t code = NGHTTP2_NO_ERROR,
581
             bool socket_closed = false);
582
583
  void Consume(v8::Local<v8::Object> stream);
584
585
  void Goaway(uint32_t code, int32_t lastStreamID,
586
              const uint8_t* data, size_t len);
587
588
  void AltSvc(int32_t id,
589
              uint8_t* origin,
590
              size_t origin_len,
591
              uint8_t* value,
592
              size_t value_len);
593
594
  void Origin(const Origins& origins);
595
596
  uint8_t SendPendingData();
597
598
  // Submits a new request. If the request is a success, assigned
599
  // will be a pointer to the Http2Stream instance assigned.
600
  // This only works if the session is a client session.
601
  Http2Stream* SubmitRequest(
602
      const Http2Priority& priority,
603
      const Http2Headers& headers,
604
      int32_t* ret,
605
      int options = 0);
606
607
  SessionType type() const { return session_type_; }
608
609
91404
  nghttp2_session* session() const { return session_.get(); }
610
611
  nghttp2_session* operator*() { return session_.get(); }
612
613
23764
  uint32_t max_header_pairs() const { return max_header_pairs_; }
614
615
  const char* TypeName() const;
616
617
66376
  bool is_destroyed() {
618

66376
    return (flags_ & kSessionStateClosed) || session_ == nullptr;
619
  }
620
621
593
  void set_destroyed() {
622
593
    flags_ |= kSessionStateClosed;
623
593
  }
624
625
#define IS_FLAG(name, flag)                                                    \
626
  bool is_##name() const { return flags_ & flag; }                             \
627
  void set_##name(bool on = true) {                                            \
628
    if (on)                                                                    \
629
      flags_ |= flag;                                                          \
630
    else                                                                       \
631
      flags_ &= ~flag;                                                         \
632
  }
633
634
173178
  IS_FLAG(in_scope, kSessionStateHasScope)
635
110937
  IS_FLAG(write_scheduled, kSessionStateWriteScheduled)
636
1186
  IS_FLAG(closing, kSessionStateClosing)
637
133286
  IS_FLAG(sending, kSessionStateSending)
638
174726
  IS_FLAG(write_in_progress, kSessionStateWriteInProgress)
639
69186
  IS_FLAG(reading_stopped, kSessionStateReadingStopped)
640
63556
  IS_FLAG(receive_paused, kSessionStateReceivePaused)
641
642
#undef IS_FLAG
643
644
  // Schedule a write if nghttp2 indicates it wants to write to the socket.
645
  void MaybeScheduleWrite();
646
647
  // Stop reading if nghttp2 doesn't want to anymore.
648
  void MaybeStopReading();
649
650
  // Returns pointer to the stream, or nullptr if stream does not exist
651
  BaseObjectPtr<Http2Stream> FindStream(int32_t id);
652
653
  bool CanAddStream();
654
655
  // Adds a stream instance to this session
656
  void AddStream(Http2Stream* stream);
657
658
  // Removes a stream instance from this session
659
  BaseObjectPtr<Http2Stream> RemoveStream(int32_t id);
660
661
  // Indicates whether there currently exist outgoing buffers for this stream.
662
  bool HasWritesOnSocketForStream(Http2Stream* stream);
663
664
  // Write data from stream_buf_ to the session
665
  ssize_t ConsumeHTTP2Data();
666
667
  void MemoryInfo(MemoryTracker* tracker) const override;
668
4
  SET_MEMORY_INFO_NAME(Http2Session)
669
4
  SET_SELF_SIZE(Http2Session)
670
671
  std::string diagnostic_name() const override;
672
673
  // Schedule an RstStream for after the current write finishes.
674
8
  void AddPendingRstStream(int32_t stream_id) {
675
8
    pending_rst_streams_.emplace_back(stream_id);
676
8
  }
677
678
23745
  bool has_pending_rststream(int32_t stream_id) {
679
47490
    return pending_rst_streams_.end() !=
680
47490
        std::find(pending_rst_streams_.begin(),
681
            pending_rst_streams_.end(),
682
71235
            stream_id);
683
  }
684
685
  // Handle reads/writes from the underlying network transport.
686
  uv_buf_t OnStreamAlloc(size_t suggested_size) override;
687
  void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override;
688
  void OnStreamAfterWrite(WriteWrap* w, int status) override;
689
690
  // Implementation for mem::NgLibMemoryManager
691
  void CheckAllocatedSize(size_t previous_size) const;
692
  void IncreaseAllocatedSize(size_t size);
693
  void DecreaseAllocatedSize(size_t size);
694
695
  // The JavaScript API
696
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
697
  static void Consume(const v8::FunctionCallbackInfo<v8::Value>& args);
698
  static void Destroy(const v8::FunctionCallbackInfo<v8::Value>& args);
699
  static void Settings(const v8::FunctionCallbackInfo<v8::Value>& args);
700
  static void Request(const v8::FunctionCallbackInfo<v8::Value>& args);
701
  static void SetNextStreamID(const v8::FunctionCallbackInfo<v8::Value>& args);
702
  static void Goaway(const v8::FunctionCallbackInfo<v8::Value>& args);
703
  static void UpdateChunksSent(const v8::FunctionCallbackInfo<v8::Value>& args);
704
  static void RefreshState(const v8::FunctionCallbackInfo<v8::Value>& args);
705
  static void Ping(const v8::FunctionCallbackInfo<v8::Value>& args);
706
  static void AltSvc(const v8::FunctionCallbackInfo<v8::Value>& args);
707
  static void Origin(const v8::FunctionCallbackInfo<v8::Value>& args);
708
709
  template <get_setting fn>
710
  static void RefreshSettings(const v8::FunctionCallbackInfo<v8::Value>& args);
711
712
  uv_loop_t* event_loop() const {
713
    return env()->event_loop();
714
  }
715
716
1173
  Http2State* http2_state() const { return http2_state_.get(); }
717
718
  BaseObjectPtr<Http2Ping> PopPing();
719
  bool AddPing(const uint8_t* data, v8::Local<v8::Function> callback);
720
721
  BaseObjectPtr<Http2Settings> PopSettings();
722
  bool AddSettings(v8::Local<v8::Function> callback);
723
724
154953
  void IncrementCurrentSessionMemory(uint64_t amount) {
725
154953
    current_session_memory_ += amount;
726
154953
  }
727
728
103296
  void DecrementCurrentSessionMemory(uint64_t amount) {
729
    DCHECK_LE(amount, current_session_memory_);
730
103296
    current_session_memory_ -= amount;
731
103296
  }
732
733
  // Tell our custom memory allocator that this rcbuf is independent of
734
  // this session now, and may outlive it.
735
  void StopTrackingRcbuf(nghttp2_rcbuf* buf);
736
737
  // Returns the current session memory including memory allocated by nghttp2,
738
  // the current outbound storage queue, and pending writes.
739
83827
  uint64_t current_session_memory() const {
740
83827
    uint64_t total = current_session_memory_ + sizeof(Http2Session);
741
83827
    total += current_nghttp2_memory_;
742
83827
    total += outgoing_storage_.size();
743
83827
    return total;
744
  }
745
746
  // Return true if current_session_memory + amount is less than the max
747
83827
  bool has_available_session_memory(uint64_t amount) const {
748
83827
    return current_session_memory() + amount <= max_session_memory_;
749
  }
750
751
  struct Statistics {
752
    uint64_t start_time;
753
    uint64_t end_time;
754
    uint64_t ping_rtt;
755
    uint64_t data_sent;
756
    uint64_t data_received;
757
    uint32_t frame_count;
758
    uint32_t frame_sent;
759
    int32_t stream_count;
760
    size_t max_concurrent_streams;
761
    double stream_average_duration;
762
  };
763
764
  Statistics statistics_ = {};
765
766
 private:
767
  void EmitStatistics();
768
769
  // Frame Padding Strategies
770
  ssize_t OnDWordAlignedPadding(size_t frameLength,
771
                                size_t maxPayloadLen);
772
  ssize_t OnMaxFrameSizePadding(size_t frameLength,
773
                                size_t maxPayloadLen);
774
775
  // Frame Handler
776
  int HandleDataFrame(const nghttp2_frame* frame);
777
  void HandleGoawayFrame(const nghttp2_frame* frame);
778
  void HandleHeadersFrame(const nghttp2_frame* frame);
779
  void HandlePriorityFrame(const nghttp2_frame* frame);
780
  void HandleSettingsFrame(const nghttp2_frame* frame);
781
  void HandlePingFrame(const nghttp2_frame* frame);
782
  void HandleAltSvcFrame(const nghttp2_frame* frame);
783
  void HandleOriginFrame(const nghttp2_frame* frame);
784
785
  // nghttp2 callbacks
786
  static int OnBeginHeadersCallback(
787
      nghttp2_session* session,
788
      const nghttp2_frame* frame,
789
      void* user_data);
790
  static int OnHeaderCallback(
791
      nghttp2_session* session,
792
      const nghttp2_frame* frame,
793
      nghttp2_rcbuf* name,
794
      nghttp2_rcbuf* value,
795
      uint8_t flags,
796
      void* user_data);
797
  static int OnFrameReceive(
798
      nghttp2_session* session,
799
      const nghttp2_frame* frame,
800
      void* user_data);
801
  static int OnFrameNotSent(
802
      nghttp2_session* session,
803
      const nghttp2_frame* frame,
804
      int error_code,
805
      void* user_data);
806
  static int OnFrameSent(
807
      nghttp2_session* session,
808
      const nghttp2_frame* frame,
809
      void* user_data);
810
  static int OnStreamClose(
811
      nghttp2_session* session,
812
      int32_t id,
813
      uint32_t code,
814
      void* user_data);
815
  static int OnInvalidHeader(
816
      nghttp2_session* session,
817
      const nghttp2_frame* frame,
818
      nghttp2_rcbuf* name,
819
      nghttp2_rcbuf* value,
820
      uint8_t flags,
821
      void* user_data);
822
  static int OnDataChunkReceived(
823
      nghttp2_session* session,
824
      uint8_t flags,
825
      int32_t id,
826
      const uint8_t* data,
827
      size_t len,
828
      void* user_data);
829
  static ssize_t OnSelectPadding(
830
      nghttp2_session* session,
831
      const nghttp2_frame* frame,
832
      size_t maxPayloadLen,
833
      void* user_data);
834
  static int OnNghttpError(
835
      nghttp2_session* session,
836
      const char* message,
837
      size_t len,
838
      void* user_data);
839
  static int OnSendData(
840
      nghttp2_session* session,
841
      nghttp2_frame* frame,
842
      const uint8_t* framehd,
843
      size_t length,
844
      nghttp2_data_source* source,
845
      void* user_data);
846
  static int OnInvalidFrame(
847
      nghttp2_session* session,
848
      const nghttp2_frame* frame,
849
      int lib_error_code,
850
      void* user_data);
851
852
8798
  struct Callbacks {
853
    explicit Callbacks(bool kHasGetPaddingCallback);
854
855
    Nghttp2SessionCallbacksPointer callbacks;
856
  };
857
858
  /* Use callback_struct_saved[kHasGetPaddingCallback ? 1 : 0] */
859
  static const Callbacks callback_struct_saved[2];
860
861
  // The underlying nghttp2_session handle
862
  Nghttp2SessionPointer session_;
863
864
  // JS-accessible numeric fields, as indexed by SessionUint8Fields.
865
  AliasedStruct<SessionJSFields> js_fields_;
866
867
  // The session type: client or server
868
  SessionType session_type_;
869
870
  // The maximum number of header pairs permitted for streams on this session
871
  uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS;
872
873
  // The maximum amount of memory allocated for this session
874
  uint64_t max_session_memory_ = kDefaultMaxSessionMemory;
875
  uint64_t current_session_memory_ = 0;
876
  // The amount of memory allocated by nghttp2 internals
877
  uint64_t current_nghttp2_memory_ = 0;
878
879
  // The collection of active Http2Streams associated with this session
880
  std::unordered_map<int32_t, BaseObjectPtr<Http2Stream>> streams_;
881
882
  int flags_ = kSessionStateNone;
883
884
  // The StreamBase instance being used for i/o
885
  PaddingStrategy padding_strategy_ = PADDING_STRATEGY_NONE;
886
887
  // use this to allow timeout tracking during long-lasting writes
888
  uint32_t chunks_sent_since_last_write_ = 0;
889
890
  uv_buf_t stream_buf_ = uv_buf_init(nullptr, 0);
891
  // When processing input data, either stream_buf_ab_ or stream_buf_allocation_
892
  // will be set. stream_buf_ab_ is lazily created from stream_buf_allocation_.
893
  v8::Global<v8::ArrayBuffer> stream_buf_ab_;
894
  AllocatedBuffer stream_buf_allocation_;
895
  size_t stream_buf_offset_ = 0;
896
897
  size_t max_outstanding_pings_ = kDefaultMaxPings;
898
  std::queue<BaseObjectPtr<Http2Ping>> outstanding_pings_;
899
900
  size_t max_outstanding_settings_ = kDefaultMaxSettings;
901
  std::queue<BaseObjectPtr<Http2Settings>> outstanding_settings_;
902
903
  std::vector<NgHttp2StreamWrite> outgoing_buffers_;
904
  std::vector<uint8_t> outgoing_storage_;
905
  size_t outgoing_length_ = 0;
906
  std::vector<int32_t> pending_rst_streams_;
907
  // Count streams that have been rejected while being opened. Exceeding a fixed
908
  // limit will result in the session being destroyed, as an indication of a
909
  // misbehaving peer. This counter is reset once new streams are being
910
  // accepted again.
911
  uint32_t rejected_stream_count_ = 0;
912
  // Also use the invalid frame count as a measure for rejecting input frames.
913
  uint32_t invalid_frame_count_ = 0;
914
915
  void PushOutgoingBuffer(NgHttp2StreamWrite&& write);
916
917
  BaseObjectPtr<Http2State> http2_state_;
918
919
  void CopyDataIntoOutgoing(const uint8_t* src, size_t src_length);
920
  void ClearOutgoing(int status);
921
922
  friend class Http2Scope;
923
  friend class Http2StreamListener;
924
};
925
926
4
class Http2SessionPerformanceEntry : public performance::PerformanceEntry {
927
 public:
928
2
  Http2SessionPerformanceEntry(
929
      Http2State* http2_state,
930
      const Http2Session::Statistics& stats,
931
2
      SessionType type) :
932
          performance::PerformanceEntry(
933
              http2_state->env(), "Http2Session", "http2",
934
2
              stats.start_time,
935
2
              stats.end_time),
936
2
          ping_rtt_(stats.ping_rtt),
937
2
          data_sent_(stats.data_sent),
938
2
          data_received_(stats.data_received),
939
2
          frame_count_(stats.frame_count),
940
2
          frame_sent_(stats.frame_sent),
941
2
          stream_count_(stats.stream_count),
942
2
          max_concurrent_streams_(stats.max_concurrent_streams),
943
2
          stream_average_duration_(stats.stream_average_duration),
944
          session_type_(type),
945
18
          http2_state_(http2_state) { }
946
947
2
  uint64_t ping_rtt() const { return ping_rtt_; }
948
2
  uint64_t data_sent() const { return data_sent_; }
949
2
  uint64_t data_received() const { return data_received_; }
950
2
  uint32_t frame_count() const { return frame_count_; }
951
2
  uint32_t frame_sent() const { return frame_sent_; }
952
2
  int32_t stream_count() const { return stream_count_; }
953
2
  size_t max_concurrent_streams() const { return max_concurrent_streams_; }
954
2
  double stream_average_duration() const { return stream_average_duration_; }
955
2
  SessionType type() const { return session_type_; }
956
2
  Http2State* http2_state() const { return http2_state_.get(); }
957
958
2
  void Notify(v8::Local<v8::Value> obj) {
959
2
    performance::PerformanceEntry::Notify(env(), kind(), obj);
960
2
  }
961
962
 private:
963
  uint64_t ping_rtt_;
964
  uint64_t data_sent_;
965
  uint64_t data_received_;
966
  uint32_t frame_count_;
967
  uint32_t frame_sent_;
968
  int32_t stream_count_;
969
  size_t max_concurrent_streams_;
970
  double stream_average_duration_;
971
  SessionType session_type_;
972
  BaseObjectPtr<Http2State> http2_state_;
973
};
974
975
4
class Http2StreamPerformanceEntry
976
    : public performance::PerformanceEntry {
977
 public:
978
2
  Http2StreamPerformanceEntry(
979
      Http2State* http2_state,
980
      int32_t id,
981
2
      const Http2Stream::Statistics& stats) :
982
          performance::PerformanceEntry(
983
              http2_state->env(), "Http2Stream", "http2",
984
2
              stats.start_time,
985
2
              stats.end_time),
986
          id_(id),
987
2
          first_header_(stats.first_header),
988
2
          first_byte_(stats.first_byte),
989
2
          first_byte_sent_(stats.first_byte_sent),
990
2
          sent_bytes_(stats.sent_bytes),
991
2
          received_bytes_(stats.received_bytes),
992
12
          http2_state_(http2_state) { }
993
994
2
  int32_t id() const { return id_; }
995
4
  uint64_t first_header() const { return first_header_; }
996
2
  uint64_t first_byte() const { return first_byte_; }
997
3
  uint64_t first_byte_sent() const { return first_byte_sent_; }
998
2
  uint64_t sent_bytes() const { return sent_bytes_; }
999
2
  uint64_t received_bytes() const { return received_bytes_; }
1000
2
  Http2State* http2_state() const { return http2_state_.get(); }
1001
1002
2
  void Notify(v8::Local<v8::Value> obj) {
1003
2
    performance::PerformanceEntry::Notify(env(), kind(), obj);
1004
2
  }
1005
1006
 private:
1007
  int32_t id_;
1008
  uint64_t first_header_;
1009
  uint64_t first_byte_;
1010
  uint64_t first_byte_sent_;
1011
  uint64_t sent_bytes_;
1012
  uint64_t received_bytes_;
1013
  BaseObjectPtr<Http2State> http2_state_;
1014
};
1015
1016
39
class Http2Ping : public AsyncWrap {
1017
 public:
1018
  explicit Http2Ping(
1019
      Http2Session* session,
1020
      v8::Local<v8::Object> obj,
1021
      v8::Local<v8::Function> callback);
1022
1023
  void MemoryInfo(MemoryTracker* tracker) const override;
1024
  SET_MEMORY_INFO_NAME(Http2Ping)
1025
  SET_SELF_SIZE(Http2Ping)
1026
1027
  void Send(const uint8_t* payload);
1028
  void Done(bool ack, const uint8_t* payload = nullptr);
1029
  void DetachFromSession();
1030
1031
  v8::Local<v8::Function> callback() const;
1032
1033
 private:
1034
  BaseObjectWeakPtr<Http2Session> session_;
1035
  v8::Global<v8::Function> callback_;
1036
  uint64_t startTime_;
1037
};
1038
1039
// The Http2Settings class is used to parse the settings passed in for
1040
// an Http2Session, converting those into an array of nghttp2_settings_entry
1041
// structs.
1042
1875
class Http2Settings : public AsyncWrap {
1043
 public:
1044
  Http2Settings(Http2Session* session,
1045
                v8::Local<v8::Object> obj,
1046
                v8::Local<v8::Function> callback,
1047
                uint64_t start_time = uv_hrtime());
1048
1049
  void MemoryInfo(MemoryTracker* tracker) const override;
1050
4
  SET_MEMORY_INFO_NAME(Http2Settings)
1051
4
  SET_SELF_SIZE(Http2Settings)
1052
1053
  void Send();
1054
  void Done(bool ack);
1055
1056
  v8::Local<v8::Function> callback() const;
1057
1058
  // Returns a Buffer instance with the serialized SETTINGS payload
1059
  v8::Local<v8::Value> Pack();
1060
1061
  static v8::Local<v8::Value> Pack(Http2State* state);
1062
1063
  // Resets the default values in the settings buffer
1064
  static void RefreshDefaults(Http2State* http2_state);
1065
1066
  // Update the local or remote settings for the given session
1067
  static void Update(Http2Session* session,
1068
                     get_setting fn);
1069
1070
 private:
1071
  static size_t Init(
1072
      Http2State* http2_state,
1073
      nghttp2_settings_entry* entries);
1074
1075
  static v8::Local<v8::Value> Pack(
1076
      Environment* env,
1077
      size_t count,
1078
      const nghttp2_settings_entry* entries);
1079
1080
  BaseObjectWeakPtr<Http2Session> session_;
1081
  v8::Global<v8::Function> callback_;
1082
  uint64_t startTime_;
1083
  size_t count_ = 0;
1084
  nghttp2_settings_entry entries_[IDX_SETTINGS_COUNT];
1085
};
1086
1087
class Origins {
1088
 public:
1089
  Origins(Environment* env,
1090
          v8::Local<v8::String> origin_string,
1091
          size_t origin_count);
1092
5
  ~Origins() = default;
1093
1094
5
  const nghttp2_origin_entry* operator*() const {
1095
5
    return reinterpret_cast<const nghttp2_origin_entry*>(buf_.data());
1096
  }
1097
1098
5
  size_t length() const {
1099
5
    return count_;
1100
  }
1101
1102
 private:
1103
  size_t count_;
1104
  AllocatedBuffer buf_;
1105
};
1106
1107
#define HTTP2_HIDDEN_CONSTANTS(V)                                              \
1108
  V(NGHTTP2_HCAT_REQUEST)                                                      \
1109
  V(NGHTTP2_HCAT_RESPONSE)                                                     \
1110
  V(NGHTTP2_HCAT_PUSH_RESPONSE)                                                \
1111
  V(NGHTTP2_HCAT_HEADERS)                                                      \
1112
  V(NGHTTP2_NV_FLAG_NONE)                                                      \
1113
  V(NGHTTP2_NV_FLAG_NO_INDEX)                                                  \
1114
  V(NGHTTP2_ERR_DEFERRED)                                                      \
1115
  V(NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE)                                       \
1116
  V(NGHTTP2_ERR_INVALID_ARGUMENT)                                              \
1117
  V(NGHTTP2_ERR_STREAM_CLOSED)                                                 \
1118
  V(STREAM_OPTION_EMPTY_PAYLOAD)                                               \
1119
  V(STREAM_OPTION_GET_TRAILERS)
1120
1121
#define HTTP2_ERROR_CODES(V)                                                   \
1122
  V(NGHTTP2_NO_ERROR)                                                          \
1123
  V(NGHTTP2_PROTOCOL_ERROR)                                                    \
1124
  V(NGHTTP2_INTERNAL_ERROR)                                                    \
1125
  V(NGHTTP2_FLOW_CONTROL_ERROR)                                                \
1126
  V(NGHTTP2_SETTINGS_TIMEOUT)                                                  \
1127
  V(NGHTTP2_STREAM_CLOSED)                                                     \
1128
  V(NGHTTP2_FRAME_SIZE_ERROR)                                                  \
1129
  V(NGHTTP2_REFUSED_STREAM)                                                    \
1130
  V(NGHTTP2_CANCEL)                                                            \
1131
  V(NGHTTP2_COMPRESSION_ERROR)                                                 \
1132
  V(NGHTTP2_CONNECT_ERROR)                                                     \
1133
  V(NGHTTP2_ENHANCE_YOUR_CALM)                                                 \
1134
  V(NGHTTP2_INADEQUATE_SECURITY)                                               \
1135
  V(NGHTTP2_HTTP_1_1_REQUIRED)                                                 \
1136
1137
#define HTTP2_CONSTANTS(V)                                                     \
1138
  V(NGHTTP2_ERR_FRAME_SIZE_ERROR)                                              \
1139
  V(NGHTTP2_SESSION_SERVER)                                                    \
1140
  V(NGHTTP2_SESSION_CLIENT)                                                    \
1141
  V(NGHTTP2_STREAM_STATE_IDLE)                                                 \
1142
  V(NGHTTP2_STREAM_STATE_OPEN)                                                 \
1143
  V(NGHTTP2_STREAM_STATE_RESERVED_LOCAL)                                       \
1144
  V(NGHTTP2_STREAM_STATE_RESERVED_REMOTE)                                      \
1145
  V(NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL)                                    \
1146
  V(NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE)                                   \
1147
  V(NGHTTP2_STREAM_STATE_CLOSED)                                               \
1148
  V(NGHTTP2_FLAG_NONE)                                                         \
1149
  V(NGHTTP2_FLAG_END_STREAM)                                                   \
1150
  V(NGHTTP2_FLAG_END_HEADERS)                                                  \
1151
  V(NGHTTP2_FLAG_ACK)                                                          \
1152
  V(NGHTTP2_FLAG_PADDED)                                                       \
1153
  V(NGHTTP2_FLAG_PRIORITY)                                                     \
1154
  V(DEFAULT_SETTINGS_HEADER_TABLE_SIZE)                                        \
1155
  V(DEFAULT_SETTINGS_ENABLE_PUSH)                                              \
1156
  V(DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS)                                   \
1157
  V(DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE)                                      \
1158
  V(DEFAULT_SETTINGS_MAX_FRAME_SIZE)                                           \
1159
  V(DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE)                                     \
1160
  V(DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL)                                  \
1161
  V(MAX_MAX_FRAME_SIZE)                                                        \
1162
  V(MIN_MAX_FRAME_SIZE)                                                        \
1163
  V(MAX_INITIAL_WINDOW_SIZE)                                                   \
1164
  V(NGHTTP2_SETTINGS_HEADER_TABLE_SIZE)                                        \
1165
  V(NGHTTP2_SETTINGS_ENABLE_PUSH)                                              \
1166
  V(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS)                                   \
1167
  V(NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE)                                      \
1168
  V(NGHTTP2_SETTINGS_MAX_FRAME_SIZE)                                           \
1169
  V(NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)                                     \
1170
  V(NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL)                                  \
1171
  V(PADDING_STRATEGY_NONE)                                                     \
1172
  V(PADDING_STRATEGY_ALIGNED)                                                  \
1173
  V(PADDING_STRATEGY_MAX)                                                      \
1174
  V(PADDING_STRATEGY_CALLBACK)                                                 \
1175
  HTTP2_ERROR_CODES(V)
1176
1177
#define HTTP2_SETTINGS(V)                                                      \
1178
  V(HEADER_TABLE_SIZE)                                                         \
1179
  V(ENABLE_PUSH)                                                               \
1180
  V(MAX_CONCURRENT_STREAMS)                                                    \
1181
  V(INITIAL_WINDOW_SIZE)                                                       \
1182
  V(MAX_FRAME_SIZE)                                                            \
1183
  V(MAX_HEADER_LIST_SIZE)                                                      \
1184
  V(ENABLE_CONNECT_PROTOCOL)                                                   \
1185
1186
}  // namespace http2
1187
}  // namespace node
1188
1189
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1190
1191
#endif  // SRC_NODE_HTTP2_H_