http-2 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,12 +86,6 @@ module HTTP2
86
86
 
87
87
  STATIC_TABLE_SIZE = STATIC_TABLE.size
88
88
 
89
- DEFAULT_OPTIONS = {
90
- huffman: :shorter,
91
- index: :all,
92
- table_size: 4096
93
- }.freeze
94
-
95
89
  STATIC_ALL = %i[all static].freeze
96
90
 
97
91
  STATIC_NEVER = %i[never static].freeze
@@ -99,60 +93,59 @@ module HTTP2
99
93
  # Current table of header key-value pairs.
100
94
  attr_reader :table
101
95
 
102
- # Current encoding options
103
- #
104
- # :table_size Integer maximum dynamic table size in bytes
105
- # :huffman Symbol :always, :never, :shorter
106
- # :index Symbol :all, :static, :never
107
- attr_reader :options
96
+ # Current encoding settings
97
+ attr_reader :settings
108
98
 
109
99
  # Current table size in octets
110
100
  attr_reader :current_table_size
111
101
 
112
102
  # Initializes compression context with appropriate client/server
113
- # defaults and maximum size of the dynamic table.
103
+ # +settings+ and maximum size of the dynamic table.
114
104
  #
115
- # @param options [Hash] encoding options
116
- # :table_size Integer maximum dynamic table size in bytes
117
- # :huffman Symbol :always, :never, :shorter
118
- # :index Symbol :all, :static, :never
119
- def initialize(options = {})
105
+ # The dynamic table starts at +settings.table_size+ octets. The same
106
+ # value is the initial maximum size allowed for the table.
107
+ def initialize(settings = Settings.new)
120
108
  @table = []
121
109
  @table_by_field = Hash.new { |hs, k| hs[k] = [] }
122
110
  @unshifts = 0
123
- @options = DEFAULT_OPTIONS.merge(options)
124
- @limit = @options[:table_size]
125
- @_table_updated = false
111
+ @settings = settings
112
+ # Current dynamic table size, as known to both encoder and decoder.
113
+ @limit = settings.table_size
114
+ # Maximum dynamic table size allowed by SETTINGS_HEADER_TABLE_SIZE.
115
+ @max_size_limit =
116
+ # Smallest maximum size set since the last dynamic table size update.
117
+ @lowest_max_size_limit = MAX_HEADER_TABLE_SIZE
118
+ @_table_updated = @_max_table_size_updated = false
126
119
  @current_table_size = 0
127
120
  end
128
121
 
129
122
  # Duplicates current compression context
130
- # @return [EncodingContext]
131
123
  def dup
132
- other = EncodingContext.new(@options)
124
+ other = EncodingContext.new(@settings)
133
125
  t = @table
134
126
  tbf = @table_by_field.transform_values(&:dup)
135
127
  unshifts = @unshifts
136
128
  l = @limit
129
+ ml = @max_size_limit
130
+ lml = @lowest_max_size_limit
137
131
  other.instance_eval do
138
132
  @table = t.dup # shallow copy
139
133
  @table_by_field = tbf
140
134
  @unshifts = unshifts
141
135
  @limit = l
136
+ @max_size_limit = ml
137
+ @lowest_max_size_limit = lml
142
138
  end
143
139
  other
144
140
  end
145
141
 
146
- # Finds an entry in current dynamic table by index.
147
- # Note that index is zero-based in this module.
142
+ # Finds an entry in current dynamic table by +index+.
143
+ # Note that +index+ is zero-based in this module.
148
144
  #
149
- # If the index is greater than the last index in the static table,
145
+ # If the +index+ is greater than the last index in the static table,
150
146
  # an entry in the dynamic table is dereferenced.
151
147
  #
152
- # If the index is greater than the last header index, an error is raised.
153
- #
154
- # @param index [Integer] zero-based index in the dynamic table.
155
- # @return [Array] +[key, value]+
148
+ # If the +index+ is greater than the last header index, an error is raised.
156
149
  def dereference(index)
157
150
  # NOTE: index is zero-based in this module.
158
151
  return STATIC_TABLE[index] if index < STATIC_TABLE_SIZE
@@ -166,12 +159,16 @@ module HTTP2
166
159
 
167
160
  # Header Block Processing
168
161
  # - http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-10#section-4.1
169
- #
170
- # @param cmd [Hash] { type:, name:, value:, index: }
171
- # @return [Array, nil] +[name, value]+ header field that is added to the decoded header list,
172
- # or nil if +cmd[:type]+ is +:changetablesize+
173
162
  def process(cmd)
174
163
  type = cmd[:type]
164
+
165
+ # The maximum size was reduced below the current table size and the
166
+ # encoder has not signalled a size that fits into it.
167
+ if type != :changetablesize && @lowest_max_size_limit < @limit
168
+ raise CompressionError,
169
+ "dynamic table size update required"
170
+ end
171
+
175
172
  name = cmd[:name]
176
173
  value = cmd[:value]
177
174
 
@@ -179,12 +176,13 @@ module HTTP2
179
176
  when :changetablesize
180
177
  raise CompressionError, "tried to change table size after adding elements to table" if @_table_updated
181
178
 
182
- # we can receive multiple table size change commands inside a header frame. However,
183
- # we should blow up if we receive another frame where the new table size is bigger.
184
- table_size_updated = @limit != @options[:table_size]
185
-
186
- raise CompressionError, "dynamic table size update exceed limit" if !table_size_updated && value > @limit
179
+ # The new maximum size MUST be lower than or equal to the limit set
180
+ # by SETTINGS_HEADER_TABLE_SIZE.
181
+ # - https://www.rfc-editor.org/rfc/rfc7541#section-6.3
182
+ raise CompressionError, "dynamic table size update exceed limit" if value > @max_size_limit
187
183
 
184
+ # The smallest maximum size set since the last update is signalled.
185
+ @lowest_max_size_limit = @max_size_limit if value <= @lowest_max_size_limit
188
186
  self.table_size = value
189
187
 
190
188
  nil
@@ -217,11 +215,12 @@ module HTTP2
217
215
  emit = [name, value]
218
216
 
219
217
  # add to table
220
- if type == :incremental && size_check?(name.bytesize + value.bytesize + 32)
218
+ cmdsize = name.bytesize + value.bytesize + 32
219
+ if type == :incremental && size_check?(cmdsize)
221
220
  @table.unshift(emit)
222
221
  @unshifts += 1
223
222
  @table_by_field[name].unshift([value, @unshifts])
224
- @current_table_size += name.bytesize + value.bytesize + 32
223
+ @current_table_size += cmdsize
225
224
  @_table_updated = true
226
225
  end
227
226
 
@@ -231,16 +230,18 @@ module HTTP2
231
230
  end
232
231
  end
233
232
 
234
- # Plan header compression according to +@options [:index]+
235
- # :never Do not use dynamic table or static table reference at all.
236
- # :static Use static table only.
237
- # :all Use all of them.
233
+ # Plan +headers+ compression.
238
234
  #
239
- # @param headers [Array] +[[name, value], ...]+
240
- # @return [Array] array of commands
241
- def encode(headers)
235
+ # Emits dynamic table size updates first when the table size has to
236
+ # change. See #max_table_size=.
237
+ def encode(headers, &block)
242
238
  # Literals commands are marked with :noindex when index is not used
243
- noindex = STATIC_NEVER.include?(@options[:index])
239
+ noindex = STATIC_NEVER.include?(@settings.index)
240
+
241
+ if @_max_table_size_updated
242
+ encode_change_table_size(&block)
243
+ @_max_table_size_updated = false
244
+ end
244
245
 
245
246
  headers.each do |field, value|
246
247
  # Literal header names MUST be translated to lowercase before
@@ -254,26 +255,17 @@ module HTTP2
254
255
  end
255
256
  end
256
257
 
257
- # Emits command for a header.
258
+ # Emits command for a +field+/+value+ header.
258
259
  # Prefer static table over dynamic table.
259
260
  # Prefer exact match over name-only match.
260
261
  #
261
- # +@options [:index]+ controls whether to use the dynamic table,
262
- # static table, or both.
263
- # :never Do not use dynamic table or static table reference at all.
264
- # :static Use static table only.
265
- # :all Use all of them.
266
- #
267
- # @param field [String] the header field
268
- # @param value [String] the header value
269
- # @return [Hash] command
270
262
  def addcmd(field, value)
271
263
  # @type var exact: Integer?
272
264
  exact = nil
273
265
  # @type var name_only: Integer?
274
266
  name_only = nil
275
267
 
276
- index_type = @options[:index]
268
+ index_type = @settings.index
277
269
 
278
270
  if STATIC_ALL.include?(index_type) &&
279
271
  STATIC_TABLE_BY_FIELD.key?(field)
@@ -313,6 +305,26 @@ module HTTP2
313
305
  resize_table(0)
314
306
  end
315
307
 
308
+ # Set the maximum dynamic table +size+ allowed by
309
+ # SETTINGS_HEADER_TABLE_SIZE.
310
+ #
311
+ # The current table size does not change here. It changes only with a
312
+ # dynamic table size update at the beginning of a header block:
313
+ # - an encoder emits the update in the next #encode call. It uses
314
+ # +settings.table_size+, capped by this maximum.
315
+ # - a decoder requires the update in the next header block when the
316
+ # current table size exceeds this maximum.
317
+ #
318
+ # When the maximum is reduced and then increased again before the next
319
+ # header block, the smallest maximum has to be signalled first.
320
+ # - https://www.rfc-editor.org/rfc/rfc7541#section-4.2
321
+ def max_table_size=(size)
322
+ @max_size_limit = size
323
+ # alternative: clamp size based on @max_size_limit, instead of failing later on #process
324
+ @lowest_max_size_limit = size if size < @lowest_max_size_limit
325
+ @_max_table_size_updated = true
326
+ end
327
+
316
328
  def listen_on_table
317
329
  yield
318
330
  ensure
@@ -321,6 +333,22 @@ module HTTP2
321
333
 
322
334
  private
323
335
 
336
+ def encode_change_table_size
337
+ if @lowest_max_size_limit < @limit
338
+ self.table_size = @lowest_max_size_limit
339
+ yield({ type: :changetablesize, value: @lowest_max_size_limit })
340
+ end
341
+ @lowest_max_size_limit = @max_size_limit
342
+
343
+ max_table_size = MAX_HEADER_TABLE_SIZE
344
+ max_table_size = @max_size_limit if @max_size_limit < max_table_size
345
+
346
+ return unless max_table_size != @limit
347
+
348
+ self.table_size = max_table_size
349
+ yield({ type: :changetablesize, value: max_table_size })
350
+ end
351
+
324
352
  def resize_table(cmdsize)
325
353
  return if @table.empty?
326
354
 
@@ -337,11 +365,10 @@ module HTTP2
337
365
  end
338
366
  end
339
367
 
368
+ # whether +cmd+ fits in the dynamic table.
369
+ #
340
370
  # To keep the dynamic table size lower than or equal to @limit,
341
371
  # remove one or more entries at the end of the dynamic table.
342
- #
343
- # @param cmdsize [Integer]
344
- # @return [Boolean] whether +cmd+ fits in the dynamic table.
345
372
  def size_check?(cmdsize)
346
373
  resize_table(cmdsize)
347
374
  cmdsize <= @limit
@@ -22,12 +22,7 @@ module HTTP2
22
22
 
23
23
  EOS_PADDING = (0..7).map { |n| ("1" * n).b.freeze }.freeze
24
24
 
25
- # Encodes provided value via huffman encoding.
26
- # Length is not encoded in this method.
27
- #
28
- # @param str [String]
29
- # @param buffer [String]
30
- # @return [String] binary string
25
+ # Encodes provided +str+ via huffman encoding into +buffer+ .
31
26
  def encode(str, buffer = "".b)
32
27
  bitstring = String.new("", encoding: Encoding::BINARY, capacity: (str.bytesize * 30) + ((8 - str.size) % 8))
33
28
  str.each_byte { |chr| append_str(bitstring, ENCODE_TABLE[chr]) }
@@ -35,11 +30,9 @@ module HTTP2
35
30
  pack([bitstring], "B*", buffer: buffer)
36
31
  end
37
32
 
38
- # Decodes provided Huffman coded string.
33
+ # Decodes provided Huffman coded string in +buf+.
39
34
  #
40
- # @param buf [Buffer]
41
- # @return [String] binary string
42
- # @raise [CompressionError] when Huffman coded string is malformed
35
+ # raises CompressionError when Huffman coded string is malformed
43
36
  def decode(buf)
44
37
  emit = "".b
45
38
  state = 0 # start state
data/lib/http/2/server.rb CHANGED
@@ -93,14 +93,11 @@ module HTTP2
93
93
  type: :headers,
94
94
  flags: END_HEADERS,
95
95
  stream: 1,
96
- weight: DEFAULT_WEIGHT,
97
- dependency: 0,
98
- exclusive: false,
99
96
  payload: headers
100
- }
97
+ } #: headers_frame
101
98
 
102
99
  if body.empty?
103
- headers_frame[:flags] |= END_HEADERS
100
+ headers_frame[:flags] |= END_STREAM
104
101
  stream << headers_frame
105
102
  else
106
103
  stream << headers_frame
@@ -1,39 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP2
4
+ MAX_HEADER_LIST_SIZE = (2 << 30) - 1
5
+ MAX_HEADER_TABLE_SIZE = 4096
6
+
4
7
  # Default values for SETTINGS frame, as defined by the spec.
5
8
  SPEC_DEFAULT_CONNECTION_SETTINGS = {
6
- settings_header_table_size: 4096,
9
+ settings_header_table_size: MAX_HEADER_TABLE_SIZE,
7
10
  settings_enable_push: 1, # enabled for servers
8
11
  settings_max_concurrent_streams: Framer::MAX_STREAM_ID, # unlimited
9
12
  settings_initial_window_size: 65_535,
10
13
  settings_max_frame_size: 16_384,
11
- settings_max_header_list_size: (2 << 30) - 1 # unlimited
14
+ settings_max_header_list_size: MAX_HEADER_LIST_SIZE # unlimited
12
15
  }.freeze
13
16
 
17
+ ENCODING_CONTEXT_SETTINGS = %i[huffman index table_size].freeze
18
+
14
19
  Settings = Struct.new(
20
+ # connection settings
15
21
  :settings_header_table_size,
16
22
  :settings_enable_push,
17
23
  :settings_max_concurrent_streams,
18
24
  :settings_initial_window_size,
19
25
  :settings_max_frame_size,
20
26
  :settings_max_header_list_size,
27
+ # encoding context settings
28
+ :huffman,
29
+ :index,
30
+ :table_size,
21
31
  keyword_init: true
22
32
  ) do
23
33
  def initialize(
24
- settings_header_table_size: 4096,
34
+ # connection settings
35
+ settings_header_table_size: MAX_HEADER_TABLE_SIZE,
25
36
  settings_enable_push: 1,
26
37
  settings_max_concurrent_streams: 100,
27
38
  settings_initial_window_size: 65_535,
28
39
  settings_max_frame_size: 16_384,
29
- settings_max_header_list_size: (2 << 30) - 1
40
+ settings_max_header_list_size: MAX_HEADER_LIST_SIZE,
41
+ # encoding context settings
42
+ huffman: :shorter,
43
+ index: :all,
44
+ table_size: MAX_HEADER_TABLE_SIZE
30
45
  )
31
46
  super
32
47
  end
33
48
 
34
- def each_setting
49
+ def connection_settings
50
+ return enum_for(__method__) unless block_given?
51
+
35
52
  each_pair do |k, v|
36
- next if v == SPEC_DEFAULT_CONNECTION_SETTINGS[k]
53
+ next if ENCODING_CONTEXT_SETTINGS.include?(k)
37
54
 
38
55
  yield k, v
39
56
  end
data/lib/http/2/stream.rb CHANGED
@@ -40,6 +40,9 @@ module HTTP2
40
40
  include Emitter
41
41
  include Error
42
42
 
43
+ # Default stream priority (lower values are higher priority).
44
+ DEFAULT_WEIGHT = 16
45
+
43
46
  STREAM_OPEN_STATES = %i[open half_closed_local half_closing closing].freeze
44
47
 
45
48
  # Stream ID (odd for client initiated streams, even otherwise).
@@ -75,9 +78,7 @@ module HTTP2
75
78
  # @param window [Integer]
76
79
  # @param parent [Stream]
77
80
  # @param state [Symbol]
78
- def initialize(connection:, id:, weight: 16, dependency: 0, exclusive: false, parent: nil, state: :idle)
79
- stream_error(:protocol_error, msg: "stream can't depend on itself") if id == dependency
80
-
81
+ def initialize(connection:, id:, weight: DEFAULT_WEIGHT, dependency: 0, exclusive: false, parent: nil, state: :idle)
81
82
  @connection = connection
82
83
  @id = id
83
84
  @weight = weight
@@ -88,9 +89,9 @@ module HTTP2
88
89
  @send_buffer = FrameBuffer.new
89
90
 
90
91
  process_priority(weight: weight, dependency: dependency, exclusive: exclusive)
91
- @local_window_max_size = connection.local_settings[:settings_initial_window_size]
92
- @local_window = connection.local_settings[:settings_initial_window_size]
93
- @remote_window = connection.remote_settings[:settings_initial_window_size]
92
+ @local_window_max_size = connection.local_settings.settings_initial_window_size
93
+ @local_window = connection.local_settings.settings_initial_window_size
94
+ @remote_window = connection.remote_settings.settings_initial_window_size
94
95
  @parent = parent
95
96
  @state = state
96
97
  @error = false
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP2
4
- VERSION = "1.2.2"
4
+ VERSION = "1.3.0"
5
5
  end
data/lib/http/2.rb CHANGED
@@ -4,6 +4,7 @@ require "http/2/version"
4
4
 
5
5
  module HTTP2
6
6
  EMPTY = [].freeze
7
+ EMPTY_HASH = {}.freeze
7
8
  end
8
9
 
9
10
  require "http/2/extensions"
@@ -13,6 +14,7 @@ require "http/2/emitter"
13
14
  require "http/2/flow_buffer"
14
15
  require "http/2/header"
15
16
  require "http/2/framer"
17
+ require "http/2/settings"
16
18
  require "http/2/connection"
17
19
  require "http/2/client"
18
20
  require "http/2/server"
data/sig/2.rbs CHANGED
@@ -8,34 +8,26 @@ module HTTP2
8
8
  DEFAULT_MAX_CONCURRENT_STREAMS: Integer
9
9
 
10
10
  EMPTY: []
11
+ EMPTY_HASH: {}
11
12
 
12
13
  type connection_opts = Hash[Symbol, untyped]
13
14
 
14
- type settings_hash = {
15
- settings_header_table_size: Integer,
16
- settings_enable_push: Integer,
17
- settings_max_concurrent_streams: Integer,
18
- settings_initial_window_size: Integer,
19
- settings_max_frame_size: Integer,
20
- settings_max_header_list_size: Integer
21
- }
22
-
23
15
  type settings_ary = Array[settings_enum]
24
16
 
25
17
  type settings_enum = Enumerable[[Symbol, Integer]]
26
18
 
27
- SPEC_DEFAULT_CONNECTION_SETTINGS: settings_hash
28
-
29
- DEFAULT_CONNECTION_SETTINGS: settings_hash
30
-
31
- DEFAULT_WEIGHT: Integer
32
-
33
19
  CONNECTION_PREFACE_MAGIC: String
34
20
 
35
21
  REQUEST_MANDATORY_HEADERS: Array[String]
36
22
 
37
23
  RESPONSE_MANDATORY_HEADERS: Array[String]
38
24
 
25
+ CONNECTION_FRAME_TYPES: Array[Symbol]
26
+
27
+ STREAM_OPEN_STATES: Array[Symbol]
28
+
29
+ HEADERS_FRAME_TYPES: Array[Symbol]
30
+
39
31
  # Frame flags
40
32
  END_STREAM: Integer
41
33
  ACK: Integer
data/sig/connection.rbs CHANGED
@@ -4,16 +4,6 @@ module HTTP2
4
4
  include Emitter
5
5
  include BufferUtils
6
6
 
7
- REQUEST_MANDATORY_HEADERS: Array[String]
8
-
9
- RESPONSE_MANDATORY_HEADERS: Array[String]
10
-
11
- CONNECTION_FRAME_TYPES: Array[Symbol]
12
-
13
- HEADERS_FRAME_TYPES: Array[Symbol]
14
-
15
- STREAM_OPEN_STATES: Array[Symbol]
16
-
17
7
  attr_reader state: Symbol
18
8
 
19
9
  attr_reader local_window: Integer
@@ -21,19 +11,21 @@ module HTTP2
21
11
 
22
12
  alias window local_window
23
13
 
24
- attr_reader remote_settings: settings_hash
25
- attr_reader local_settings: settings_hash
14
+ attr_reader remote_settings: Settings
15
+ attr_reader local_settings: Settings
26
16
  attr_reader pending_settings: settings_ary
27
17
 
28
18
  attr_accessor active_stream_count: Integer
29
19
 
30
20
  @stream_id: Integer
31
21
  @active_stream_count: Integer
22
+ @promised_stream_count: Integer
32
23
  @last_stream_id: Integer
33
24
 
34
25
  @streams: Hash[Integer, Stream]
35
26
  @streams_recently_closed: Hash[Integer, Numeric]
36
27
  @oldest_stream_recently_closed: Numeric
28
+ @last_promised_stream_id: Integer
37
29
 
38
30
  @framer: Framer
39
31
 
@@ -87,10 +79,12 @@ module HTTP2
87
79
 
88
80
  def connection_frame?: (frame) -> bool
89
81
 
90
- def connection_management: (connection_frame frame) -> void
82
+ def connection_management: (frame frame) -> void
91
83
 
92
84
  def ping_management: (frame) -> void
93
85
 
86
+ def validate_push_promise: (Integer stream_id) -> void
87
+
94
88
  def validate_settings: (role_type, settings_enum) -> void
95
89
 
96
90
  def connection_settings: (settings_frame) -> void
@@ -6,19 +6,19 @@ module HTTP2
6
6
 
7
7
  @cc: EncodingContext
8
8
 
9
- def table_size=: (Integer) -> void
9
+ def max_table_size=: (Integer) -> void
10
10
 
11
11
  def integer: (Integer, Integer, buffer: String, ?offset: Integer) -> String
12
12
 
13
13
  def string: (String, ?String buffer) -> String
14
14
 
15
- def header: (header_command, ?String) -> String
15
+ def header: (change_table_size_command | header_command, ?String) -> String
16
16
 
17
17
  def encode: (Enumerable[header_pair]) -> String
18
18
 
19
19
  private
20
20
 
21
- def initialize: (?connection_opts options) -> void
21
+ def initialize: (?Settings settings) -> void
22
22
 
23
23
  def huffman_string: (String str, ?String buffer) -> String
24
24
 
@@ -7,19 +7,26 @@ module HTTP2
7
7
 
8
8
  @cc: EncodingContext
9
9
 
10
- def table_size=: (Integer) -> void
10
+ @accept_invalid_headers: bool
11
+
12
+ attr_writer max_header_list_size: Integer
13
+
14
+ def max_table_size=: (Integer) -> void
11
15
 
12
16
  def integer: (String, Integer) -> Integer
13
17
 
14
18
  def string: (String) -> String
15
19
 
16
- def header: (String) -> header_command
20
+ def header: (String) -> (change_table_size_command | header_command)
17
21
 
18
22
  def decode: (String, frame?) -> Array[header_pair]
19
23
  | (String) -> Array[header_pair]
24
+
25
+ def accept_invalid_headers!: () -> void
26
+
20
27
  private
21
28
 
22
- def initialize: (?connection_opts options) -> void
29
+ def initialize: (?Settings settings) -> void
23
30
  end
24
31
  end
25
32
  end
@@ -11,14 +11,12 @@ module HTTP2
11
11
 
12
12
  STATIC_NEVER: Array[Symbol]
13
13
 
14
- DEFAULT_OPTIONS: context_hash
15
-
16
14
  UPPER: Regexp
17
15
 
18
16
 
19
17
  attr_reader table: Array[header_pair]
20
18
 
21
- attr_reader options: context_hash
19
+ attr_reader settings: Settings
22
20
 
23
21
  attr_reader current_table_size: Integer
24
22
 
@@ -28,25 +26,35 @@ module HTTP2
28
26
 
29
27
  @limit: Integer
30
28
 
29
+ @max_size_limit: Integer
30
+
31
+ @lowest_max_size_limit: Integer
32
+
31
33
  @_table_updated: bool
32
34
 
35
+ @_max_table_size_updated: bool
36
+
33
37
  def dup: () -> EncodingContext
34
38
 
35
39
  def dereference: (Integer) -> header_pair
36
40
 
37
- def process: (header_command cmd) -> header_pair?
41
+ def process: (change_table_size_command | header_command cmd) -> header_pair?
38
42
 
39
- def encode: (_Each[header_pair]) { (header_command) -> void } -> void
43
+ def encode: (_Each[header_pair]) { (change_table_size_command | header_command) -> void } -> void
40
44
 
41
45
  def addcmd: (String name, String value) -> header_command
42
46
 
43
47
  def table_size=: (Integer) -> void
44
48
 
49
+ def max_table_size=: (Integer) -> void
50
+
45
51
  def listen_on_table: { () -> void } -> void
46
52
 
47
53
  private
48
54
 
49
- def initialize: (?connection_opts options) -> void
55
+ def initialize: (?Settings settings) -> void
56
+
57
+ def encode_change_table_size: () { (change_table_size_command) -> void } -> void
50
58
 
51
59
  def add_to_table: (string name, string value) -> void
52
60
 
data/sig/header.rbs CHANGED
@@ -11,9 +11,10 @@ module HTTP2
11
11
 
12
12
  type header_type = :indexed | :incremental | :noindex | :neverindexed | :changetablesize
13
13
 
14
+ type change_table_size_command = { type: :changetablesize, ?name: Integer, value: Integer }
15
+
14
16
  type header_command = { type: :indexed , name: Integer } |
15
- { type: (:incremental | :noindex | :neverindexed), name: Integer | String, value: String } |
16
- { type: :changetablesize, ?name: Integer, value: Integer }
17
+ { type: (:incremental | :noindex | :neverindexed), name: Integer | String, value: String }
17
18
 
18
19
  HEADREP: Hash[header_type, { prefix: Integer, pattern: Integer }]
19
20
 
data/sig/server.rbs CHANGED
@@ -1,5 +1,7 @@
1
1
  module HTTP2
2
2
  class Server < Connection
3
+ @origin_set: Array[String]
4
+ @origins_sent: bool
3
5
 
4
6
  def upgrade: (String settings, Enumerable[header_pair] headers, String body) -> void
5
7