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.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/lib/http/2/base64.rb +8 -8
- data/lib/http/2/client.rb +1 -1
- data/lib/http/2/connection.rb +70 -60
- data/lib/http/2/framer.rb +3 -3
- data/lib/http/2/header/compressor.rb +13 -39
- data/lib/http/2/header/decompressor.rb +29 -32
- data/lib/http/2/header/encoding_context.rb +90 -63
- data/lib/http/2/header/huffman.rb +3 -10
- data/lib/http/2/server.rb +2 -5
- data/lib/http/2/settings.rb +23 -6
- data/lib/http/2/stream.rb +7 -6
- data/lib/http/2/version.rb +1 -1
- data/lib/http/2.rb +2 -0
- data/sig/2.rbs +7 -15
- data/sig/connection.rbs +7 -13
- data/sig/header/compressor.rbs +3 -3
- data/sig/header/decompressor.rbs +10 -3
- data/sig/header/encoding_context.rbs +14 -6
- data/sig/header.rbs +3 -2
- data/sig/server.rbs +2 -0
- data/sig/settings.rbs +73 -0
- data/sig/stream.rbs +2 -0
- metadata +3 -1
|
@@ -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
|
|
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
|
-
#
|
|
103
|
+
# +settings+ and maximum size of the dynamic table.
|
|
114
104
|
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
|
|
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
|
-
@
|
|
124
|
-
|
|
125
|
-
@
|
|
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(@
|
|
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
|
-
#
|
|
183
|
-
#
|
|
184
|
-
|
|
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
|
-
|
|
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 +=
|
|
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
|
|
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
|
-
#
|
|
240
|
-
#
|
|
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?(@
|
|
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 = @
|
|
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
|
|
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
|
-
#
|
|
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] |=
|
|
100
|
+
headers_frame[:flags] |= END_STREAM
|
|
104
101
|
stream << headers_frame
|
|
105
102
|
else
|
|
106
103
|
stream << headers_frame
|
data/lib/http/2/settings.rb
CHANGED
|
@@ -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:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
49
|
+
def connection_settings
|
|
50
|
+
return enum_for(__method__) unless block_given?
|
|
51
|
+
|
|
35
52
|
each_pair do |k, v|
|
|
36
|
-
next if
|
|
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:
|
|
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
|
|
92
|
-
@local_window = connection.local_settings
|
|
93
|
-
@remote_window = connection.remote_settings
|
|
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
|
data/lib/http/2/version.rb
CHANGED
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:
|
|
25
|
-
attr_reader local_settings:
|
|
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: (
|
|
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
|
data/sig/header/compressor.rbs
CHANGED
|
@@ -6,19 +6,19 @@ module HTTP2
|
|
|
6
6
|
|
|
7
7
|
@cc: EncodingContext
|
|
8
8
|
|
|
9
|
-
def
|
|
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: (?
|
|
21
|
+
def initialize: (?Settings settings) -> void
|
|
22
22
|
|
|
23
23
|
def huffman_string: (String str, ?String buffer) -> String
|
|
24
24
|
|
data/sig/header/decompressor.rbs
CHANGED
|
@@ -7,19 +7,26 @@ module HTTP2
|
|
|
7
7
|
|
|
8
8
|
@cc: EncodingContext
|
|
9
9
|
|
|
10
|
-
|
|
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: (?
|
|
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
|
|
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: (?
|
|
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
|
|