protocol-hpack 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +2 -2
- data/lib/protocol/hpack/compressor.rb +2 -2
- data/lib/protocol/hpack/context.rb +44 -54
- data/lib/protocol/hpack/decompressor.rb +11 -4
- data/lib/protocol/hpack/huffman.rb +2 -2
- data/lib/protocol/hpack/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4f37a74f63435d104e330527a394230a528ac8e1739c0ec6dcab1e0d40ba2fa
|
4
|
+
data.tar.gz: 15e11514d7bf7dc987577272e73114ac0179c750f065ddde4eceb8b10f19e46a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c6cf113a2141feb408615117dfed35d13a61a297f47bd4cfd2bcc63d42b38c21f875ef1dc99a0542035a17b7cd630c05fb6fb885b9294f8dc46533efb5bb48d
|
7
|
+
data.tar.gz: d7f96e39202967a77c73a39a4ca65e582676e8b533f990e3bd02062e1fe279387d663918247aa4baf3a50ea3da42099068783359e2b0a21ed1bd94e08909a18b
|
data/.gitmodules
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
[submodule "spec/
|
2
|
-
path = spec/
|
1
|
+
[submodule "spec/protocol/hpack/fixtures"]
|
2
|
+
path = spec/protocol/hpack/fixtures
|
3
3
|
url = https://github.com/http2jp/hpack-test-case.git
|
@@ -100,7 +100,7 @@ module Protocol
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def huffman
|
103
|
-
@context.
|
103
|
+
@context.huffman
|
104
104
|
end
|
105
105
|
|
106
106
|
# Encodes provided value via string literal representation.
|
@@ -158,7 +158,7 @@ module Protocol
|
|
158
158
|
case command[:type]
|
159
159
|
when :indexed
|
160
160
|
write_integer(command[:name] + 1, representation[:prefix])
|
161
|
-
when :
|
161
|
+
when :change_table_size
|
162
162
|
write_integer(command[:value], representation[:prefix])
|
163
163
|
else
|
164
164
|
if command[:name].is_a? Integer
|
@@ -31,9 +31,9 @@ module Protocol
|
|
31
31
|
HEADER_REPRESENTATION = {
|
32
32
|
indexed: {prefix: 7, pattern: 0x80},
|
33
33
|
incremental: {prefix: 6, pattern: 0x40},
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
no_index: {prefix: 4, pattern: 0x00},
|
35
|
+
never_indexed: {prefix: 4, pattern: 0x10},
|
36
|
+
change_table_size: {prefix: 5, pattern: 0x20},
|
37
37
|
}
|
38
38
|
|
39
39
|
# To decompress header blocks, a decoder only needs to maintain a
|
@@ -105,48 +105,38 @@ module Protocol
|
|
105
105
|
['vary', ''],
|
106
106
|
['via', ''],
|
107
107
|
['www-authenticate', ''],
|
108
|
-
|
109
|
-
|
110
|
-
#
|
111
|
-
attr_reader :table
|
112
|
-
|
113
|
-
# Current encoding options
|
114
|
-
#
|
115
|
-
# :table_size Integer maximum dynamic table size in bytes
|
116
|
-
# :huffman Symbol :always, :never, :shorter
|
117
|
-
# :index Symbol :all, :static, :never
|
118
|
-
attr_reader :options
|
119
|
-
|
120
|
-
# Initializes compression context with appropriate client/server
|
121
|
-
# defaults and maximum size of the dynamic table.
|
108
|
+
].each {|pair| pair.each(&:freeze).freeze}.freeze
|
109
|
+
|
110
|
+
# Initializes compression context with appropriate client/server defaults and maximum size of the dynamic table.
|
122
111
|
#
|
123
|
-
# @param
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
def initialize(
|
128
|
-
|
129
|
-
|
130
|
-
index: :all,
|
131
|
-
table_size: 4096,
|
132
|
-
}
|
112
|
+
# @param table [Array] Table of header key-value pairs.
|
113
|
+
# @option huffman [Symbol] One of `:always`, `:never`, `:shorter`. Controls use of compression.
|
114
|
+
# @option index [Symbol] One of `:all`, `:static`, `:never`. Controls use of static/dynamic tables.
|
115
|
+
# @option table_size [Integer] The current maximum dynamic table size.
|
116
|
+
def initialize(table = nil, huffman: :shorter, index: :all, table_size: 4096)
|
117
|
+
@huffman = huffman
|
118
|
+
@index = index
|
133
119
|
|
134
|
-
@
|
135
|
-
@options = default_options.merge(options)
|
136
|
-
@limit = @options[:table_size]
|
137
|
-
end
|
138
|
-
|
139
|
-
# Duplicates current compression context
|
140
|
-
# @return [Context]
|
141
|
-
def dup
|
142
|
-
other = Context.new(@options)
|
120
|
+
@table_size = table_size
|
143
121
|
|
144
|
-
|
145
|
-
|
122
|
+
@table = (table&.dup) || []
|
123
|
+
end
|
124
|
+
|
125
|
+
def initialize_copy(other)
|
126
|
+
super
|
146
127
|
|
147
|
-
|
128
|
+
# This is the only mutable state:
|
129
|
+
@table = @table.dup
|
148
130
|
end
|
149
|
-
|
131
|
+
|
132
|
+
# Current table of header key-value pairs.
|
133
|
+
attr :table
|
134
|
+
|
135
|
+
attr :huffman
|
136
|
+
attr :index
|
137
|
+
|
138
|
+
attr :table_size
|
139
|
+
|
150
140
|
# Finds an entry in current dynamic table by index.
|
151
141
|
# Note that index is zero-based in this module.
|
152
142
|
#
|
@@ -175,7 +165,7 @@ module Protocol
|
|
175
165
|
emit = nil
|
176
166
|
|
177
167
|
case command[:type]
|
178
|
-
when :
|
168
|
+
when :change_table_size
|
179
169
|
self.table_size = command[:value]
|
180
170
|
|
181
171
|
when :indexed
|
@@ -189,7 +179,7 @@ module Protocol
|
|
189
179
|
k, v = dereference(idx)
|
190
180
|
emit = [k, v]
|
191
181
|
|
192
|
-
when :incremental, :
|
182
|
+
when :incremental, :no_index, :never_indexed
|
193
183
|
# A _literal representation_ that is _not added_ to the dynamic table
|
194
184
|
# entails the following action:
|
195
185
|
# o The header field is added to the decoded header list.
|
@@ -219,7 +209,7 @@ module Protocol
|
|
219
209
|
return emit
|
220
210
|
end
|
221
211
|
|
222
|
-
# Plan header compression according to +@
|
212
|
+
# Plan header compression according to +@index+
|
223
213
|
# :never Do not use dynamic table or static table reference at all.
|
224
214
|
# :static Use static table only.
|
225
215
|
# :all Use all of them.
|
@@ -229,12 +219,12 @@ module Protocol
|
|
229
219
|
def encode(headers)
|
230
220
|
commands = []
|
231
221
|
|
232
|
-
# Literals commands are marked with :
|
233
|
-
|
222
|
+
# Literals commands are marked with :no_index when index is not used
|
223
|
+
no_index = [:static, :never].include?(@index)
|
234
224
|
|
235
225
|
headers.each do |field, value|
|
236
226
|
command = add_command(field, value)
|
237
|
-
command[:type] = :
|
227
|
+
command[:type] = :no_index if no_index && command[:type] == :incremental
|
238
228
|
commands << command
|
239
229
|
|
240
230
|
decode(command)
|
@@ -247,7 +237,7 @@ module Protocol
|
|
247
237
|
# Prefer static table over dynamic table.
|
248
238
|
# Prefer exact match over name-only match.
|
249
239
|
#
|
250
|
-
# +@
|
240
|
+
# +@index+ controls whether to use the dynamic table,
|
251
241
|
# static table, or both.
|
252
242
|
# :never Do not use dynamic table or static table reference at all.
|
253
243
|
# :static Use static table only.
|
@@ -259,7 +249,7 @@ module Protocol
|
|
259
249
|
exact = nil
|
260
250
|
name_only = nil
|
261
251
|
|
262
|
-
if [:all, :static].include?(@
|
252
|
+
if [:all, :static].include?(@index)
|
263
253
|
STATIC_TABLE.each_index do |i|
|
264
254
|
if STATIC_TABLE[i] == header
|
265
255
|
exact ||= i
|
@@ -269,7 +259,7 @@ module Protocol
|
|
269
259
|
end
|
270
260
|
end
|
271
261
|
end
|
272
|
-
if [:all].include?(@
|
262
|
+
if [:all].include?(@index) && !exact
|
273
263
|
@table.each_index do |i|
|
274
264
|
if @table[i] == header
|
275
265
|
exact ||= i + STATIC_TABLE.size
|
@@ -291,8 +281,8 @@ module Protocol
|
|
291
281
|
|
292
282
|
# Alter dynamic table size.
|
293
283
|
# When the size is reduced, some headers might be evicted.
|
294
|
-
def table_size=
|
295
|
-
@
|
284
|
+
def table_size= size
|
285
|
+
@table_size = size
|
296
286
|
size_check(nil)
|
297
287
|
end
|
298
288
|
|
@@ -314,7 +304,7 @@ module Protocol
|
|
314
304
|
@table.unshift(command)
|
315
305
|
end
|
316
306
|
|
317
|
-
# To keep the dynamic table size lower than or equal to @
|
307
|
+
# To keep the dynamic table size lower than or equal to @table_size,
|
318
308
|
# remove one or more entries at the end of the dynamic table.
|
319
309
|
#
|
320
310
|
# @param command [Hash]
|
@@ -323,14 +313,14 @@ module Protocol
|
|
323
313
|
cursize = current_table_size
|
324
314
|
cmdsize = command.nil? ? 0 : command[0].bytesize + command[1].bytesize + 32
|
325
315
|
|
326
|
-
while cursize + cmdsize > @
|
316
|
+
while cursize + cmdsize > @table_size
|
327
317
|
break if @table.empty?
|
328
318
|
|
329
319
|
e = @table.pop
|
330
320
|
cursize -= e[0].bytesize + e[1].bytesize + 32
|
331
321
|
end
|
332
322
|
|
333
|
-
cmdsize <= @
|
323
|
+
cmdsize <= @table_size
|
334
324
|
end
|
335
325
|
end
|
336
326
|
end
|
@@ -28,16 +28,20 @@ module Protocol
|
|
28
28
|
# context of the opposing peer. Decompressor must be initialized with
|
29
29
|
# appropriate starting context based on local role: client or server.
|
30
30
|
class Decompressor
|
31
|
-
def initialize(buffer, context = Context.new)
|
31
|
+
def initialize(buffer, context = Context.new, table_size_limit: nil)
|
32
32
|
@buffer = buffer
|
33
33
|
@context = context
|
34
34
|
@offset = 0
|
35
|
+
|
36
|
+
@table_size_limit = table_size_limit
|
35
37
|
end
|
36
38
|
|
37
39
|
attr :buffer
|
38
40
|
attr :context
|
39
41
|
attr :offset
|
40
|
-
|
42
|
+
|
43
|
+
attr :table_size_limit
|
44
|
+
|
41
45
|
def end?
|
42
46
|
@offset >= @buffer.bytesize
|
43
47
|
end
|
@@ -50,7 +54,6 @@ module Protocol
|
|
50
54
|
return byte
|
51
55
|
end
|
52
56
|
|
53
|
-
|
54
57
|
def peek_byte
|
55
58
|
@buffer.getbyte(@offset)
|
56
59
|
end
|
@@ -121,8 +124,12 @@ module Protocol
|
|
121
124
|
when :indexed
|
122
125
|
raise CompressionError if header[:name].zero?
|
123
126
|
header[:name] -= 1
|
124
|
-
when :
|
127
|
+
when :change_table_size
|
125
128
|
header[:value] = header[:name]
|
129
|
+
|
130
|
+
if @table_size_limit and header[:value] > @table_size_limit
|
131
|
+
raise CompressionError, "Table size #{header[:value]} exceeds limit #{@table_size_limit}!"
|
132
|
+
end
|
126
133
|
else
|
127
134
|
if (header[:name]).zero?
|
128
135
|
header[:name] = read_string
|
@@ -333,8 +333,8 @@ module Protocol
|
|
333
333
|
[0x7fffff0, 27],
|
334
334
|
[0x3ffffee, 26],
|
335
335
|
[0x3fffffff, 30],
|
336
|
-
|
337
|
-
|
336
|
+
].each(&:freeze).freeze
|
337
|
+
|
338
338
|
ENCODE_TABLE = CODES.map {|c, l| [c].pack('N').unpack('B*').first[-l..-1]}.each(&:freeze).freeze
|
339
339
|
end
|
340
340
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocol-hpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: covered
|