protocol-hpack 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8842abc9eb7e88d37fc4ed8040b6f4c6c5ec290993fd342dcc22a7d46ffcee1d
4
- data.tar.gz: 6a6a2e09a5ebf8b8e7d1a6aa0f95b3d4bfc167c0d19ca9c47535b08428bb6986
3
+ metadata.gz: b4f37a74f63435d104e330527a394230a528ac8e1739c0ec6dcab1e0d40ba2fa
4
+ data.tar.gz: 15e11514d7bf7dc987577272e73114ac0179c750f065ddde4eceb8b10f19e46a
5
5
  SHA512:
6
- metadata.gz: c43f98660e1eb5dc2508bdc95ee874699e69b21c23e12344c91f34897d50da207564cba0a61082b55cc522ffddf97fb02c2a0d59ee5f217b76fddb24559d3447
7
- data.tar.gz: 5328a19baee03e84dd3dbfec14ca5d36a7b0deaa822eadfc0bdae5e7439d73c1b12c6d9194a5202fc9ed4cf43c74a715a5e27bede8b298aa20e9ca2037d5706e
6
+ metadata.gz: 9c6cf113a2141feb408615117dfed35d13a61a297f47bd4cfd2bcc63d42b38c21f875ef1dc99a0542035a17b7cd630c05fb6fb885b9294f8dc46533efb5bb48d
7
+ data.tar.gz: d7f96e39202967a77c73a39a4ca65e582676e8b533f990e3bd02062e1fe279387d663918247aa4baf3a50ea3da42099068783359e2b0a21ed1bd94e08909a18b
@@ -1,3 +1,3 @@
1
- [submodule "spec/http/hpack/hpack-test-case"]
2
- path = spec/http/hpack/hpack-test-case
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.options[:huffman]
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 :changetablesize
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
- noindex: {prefix: 4, pattern: 0x00},
35
- neverindexed: {prefix: 4, pattern: 0x10},
36
- changetablesize: {prefix: 5, pattern: 0x20},
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
- ].each {|pair| pair.each(&:freeze).freeze}.freeze
109
-
110
- # Current table of header key-value pairs.
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 options [Hash] encoding options
124
- # :table_size Integer maximum dynamic table size in bytes
125
- # :huffman Symbol :always, :never, :shorter
126
- # :index Symbol :all, :static, :never
127
- def initialize(**options)
128
- default_options = {
129
- huffman: :shorter,
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
- @table = []
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
- other.instance_variable_set :@table, @table.dup
145
- other.instance_variable_set :@limit, @limit
122
+ @table = (table&.dup) || []
123
+ end
124
+
125
+ def initialize_copy(other)
126
+ super
146
127
 
147
- return other
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 :changetablesize
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, :noindex, :neverindexed
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 +@options [:index]+
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 :noindex when index is not used
233
- noindex = [:static, :never].include?(@options[:index])
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] = :noindex if noindex && command[:type] == :incremental
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
- # +@options [:index]+ controls whether to use the dynamic table,
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?(@options[:index])
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?(@options[:index]) && !exact
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=(size)
295
- @limit = size
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 @limit,
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 > @limit
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 <= @limit
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 :changetablesize
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
- ].each(&:freeze).freeze
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
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Protocol
22
22
  module HPACK
23
- VERSION = "1.1.0"
23
+ VERSION = "1.2.0"
24
24
  end
25
25
  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.1.0
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 00:00:00.000000000 Z
11
+ date: 2019-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: covered