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 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