biryani 0.0.4 → 0.0.6
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/.ruby-version +1 -1
- data/Rakefile +7 -0
- data/conformance/server_spec.rb +31 -0
- data/conformance/spec_helper.rb +14 -0
- data/example/echo.rb +0 -1
- data/example/raise_error.rb +19 -0
- data/lib/biryani/connection.rb +23 -18
- data/lib/biryani/data_buffer.rb +1 -1
- data/lib/biryani/error.rb +8 -0
- data/lib/biryani/frame/continuation.rb +4 -7
- data/lib/biryani/frame/data.rb +9 -12
- data/lib/biryani/frame/goaway.rb +6 -6
- data/lib/biryani/frame/headers.rb +25 -18
- data/lib/biryani/frame/ping.rb +5 -7
- data/lib/biryani/frame/priority.rb +6 -5
- data/lib/biryani/frame/push_promise.rb +14 -15
- data/lib/biryani/frame/rst_stream.rb +5 -5
- data/lib/biryani/frame/settings.rb +5 -5
- data/lib/biryani/frame/unknown.rb +1 -15
- data/lib/biryani/frame/window_update.rb +5 -5
- data/lib/biryani/frame.rb +10 -4
- data/lib/biryani/hpack/field.rb +42 -42
- data/lib/biryani/hpack/fields.rb +2 -1
- data/lib/biryani/hpack/huffman.rb +290 -21
- data/lib/biryani/hpack/integer.rb +10 -6
- data/lib/biryani/hpack/string.rb +6 -6
- data/lib/biryani/http_request.rb +3 -2
- data/lib/biryani/http_response.rb +23 -2
- data/lib/biryani/server.rb +1 -1
- data/lib/biryani/state.rb +14 -7
- data/lib/biryani/stream.rb +10 -3
- data/lib/biryani/streams_context.rb +12 -6
- data/lib/biryani/version.rb +1 -1
- data/lib/biryani.rb +1 -1
- data/spec/connection/handle_data_spec.rb +2 -2
- data/spec/connection/handle_headers_spec.rb +1 -1
- data/spec/connection/{transition_state_send_spec.rb → transition_stream_state_send_spec.rb} +3 -3
- data/spec/frame/continuation_spec.rb +2 -2
- data/spec/frame/data_spec.rb +1 -1
- data/spec/frame/goaway_spec.rb +1 -1
- data/spec/frame/headers_spec.rb +2 -2
- data/spec/frame/ping_spec.rb +1 -1
- data/spec/frame/priority_spec.rb +1 -1
- data/spec/frame/push_promise_spec.rb +1 -1
- data/spec/frame/rst_stream_spec.rb +1 -1
- data/spec/frame/settings_spec.rb +1 -1
- data/spec/frame/window_update_spec.rb +1 -1
- data/spec/hpack/field_spec.rb +10 -9
- data/spec/hpack/huffman_spec.rb +4 -4
- data/spec/hpack/integer_spec.rb +5 -5
- data/spec/hpack/string_spec.rb +2 -2
- data/spec/http_response_spec.rb +12 -0
- metadata +9 -3
data/lib/biryani/hpack/field.rb
CHANGED
|
@@ -98,7 +98,7 @@ module Biryani
|
|
|
98
98
|
"\x40#{String.encode(name)}#{String.encode(value)}"
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
# @param
|
|
101
|
+
# @param io [IO::Buffer]
|
|
102
102
|
# @param cursor [Integer]
|
|
103
103
|
# @param dynamic_table [DynamicTable]
|
|
104
104
|
#
|
|
@@ -106,24 +106,24 @@ module Biryani
|
|
|
106
106
|
# @return [Integer]
|
|
107
107
|
# rubocop: disable Metrics/CyclomaticComplexity
|
|
108
108
|
# rubocop: disable Metrics/PerceivedComplexity
|
|
109
|
-
def self.decode(
|
|
110
|
-
byte =
|
|
109
|
+
def self.decode(io, cursor, dynamic_table)
|
|
110
|
+
byte = io.get_value(:U8, cursor)
|
|
111
111
|
if (byte & 0b10000000).positive?
|
|
112
|
-
decode_indexed(
|
|
112
|
+
decode_indexed(io, cursor, dynamic_table)
|
|
113
113
|
elsif byte == 0b01000000
|
|
114
|
-
decode_literal_field_incremental_indexing(
|
|
114
|
+
decode_literal_field_incremental_indexing(io, cursor, dynamic_table)
|
|
115
115
|
elsif (byte & 0b01000000).positive?
|
|
116
|
-
decode_literal_value_incremental_indexing(
|
|
116
|
+
decode_literal_value_incremental_indexing(io, cursor, dynamic_table)
|
|
117
117
|
elsif (byte & 0b00100000).positive?
|
|
118
|
-
decode_dynamic_table_size_update(
|
|
118
|
+
decode_dynamic_table_size_update(io, cursor, dynamic_table)
|
|
119
119
|
elsif byte == 0b00010000
|
|
120
|
-
decode_literal_field_never_indexed(
|
|
120
|
+
decode_literal_field_never_indexed(io, cursor)
|
|
121
121
|
elsif (byte & 0b00010000).positive?
|
|
122
|
-
decode_literal_value_never_indexed(
|
|
122
|
+
decode_literal_value_never_indexed(io, cursor, dynamic_table)
|
|
123
123
|
elsif byte.zero?
|
|
124
|
-
decode_literal_field_without_indexing(
|
|
124
|
+
decode_literal_field_without_indexing(io, cursor)
|
|
125
125
|
elsif (byte & 0b11110000).zero?
|
|
126
|
-
decode_literal_value_without_indexing(
|
|
126
|
+
decode_literal_value_without_indexing(io, cursor, dynamic_table)
|
|
127
127
|
else
|
|
128
128
|
raise 'unreachable'
|
|
129
129
|
end
|
|
@@ -137,14 +137,14 @@ module Biryani
|
|
|
137
137
|
# +---+---------------------------+
|
|
138
138
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.1
|
|
139
139
|
#
|
|
140
|
-
# @param
|
|
140
|
+
# @param io [IO::Buffer]
|
|
141
141
|
# @param cursor [Integer]
|
|
142
142
|
# @param dynamic_table [DynamicTable]
|
|
143
143
|
#
|
|
144
144
|
# @return [Array]
|
|
145
145
|
# @return [Integer]
|
|
146
|
-
def self.decode_indexed(
|
|
147
|
-
index, c = Integer.decode(
|
|
146
|
+
def self.decode_indexed(io, cursor, dynamic_table)
|
|
147
|
+
index, c = Integer.decode(io, 7, cursor)
|
|
148
148
|
raise Error::HPACKDecodeError if index.zero?
|
|
149
149
|
raise Error::HPACKDecodeError if index > STATIC_TABLE_SIZE + dynamic_table.count_entries
|
|
150
150
|
|
|
@@ -171,15 +171,15 @@ module Biryani
|
|
|
171
171
|
# +-------------------------------+
|
|
172
172
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.2.1
|
|
173
173
|
#
|
|
174
|
-
# @param
|
|
174
|
+
# @param io [IO::Buffer]
|
|
175
175
|
# @param cursor [Integer]
|
|
176
176
|
# @param dynamic_table [DynamicTable]
|
|
177
177
|
#
|
|
178
178
|
# @return [Array]
|
|
179
179
|
# @return [Integer]
|
|
180
|
-
def self.decode_literal_field_incremental_indexing(
|
|
181
|
-
name, c = String.decode(
|
|
182
|
-
value, c = String.decode(
|
|
180
|
+
def self.decode_literal_field_incremental_indexing(io, cursor, dynamic_table)
|
|
181
|
+
name, c = String.decode(io, cursor + 1)
|
|
182
|
+
value, c = String.decode(io, c)
|
|
183
183
|
dynamic_table.store(name, value)
|
|
184
184
|
|
|
185
185
|
[[name, value], c]
|
|
@@ -195,14 +195,14 @@ module Biryani
|
|
|
195
195
|
# +-------------------------------+
|
|
196
196
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.2.1
|
|
197
197
|
#
|
|
198
|
-
# @param
|
|
198
|
+
# @param io [IO::Buffer]
|
|
199
199
|
# @param cursor [Integer]
|
|
200
200
|
# @param dynamic_table [DynamicTable]
|
|
201
201
|
#
|
|
202
202
|
# @return [Array]
|
|
203
203
|
# @return [Integer]
|
|
204
|
-
def self.decode_literal_value_incremental_indexing(
|
|
205
|
-
index, c = Integer.decode(
|
|
204
|
+
def self.decode_literal_value_incremental_indexing(io, cursor, dynamic_table)
|
|
205
|
+
index, c = Integer.decode(io, 6, cursor)
|
|
206
206
|
raise Error::HPACKDecodeError if index.zero?
|
|
207
207
|
raise Error::HPACKDecodeError if index > STATIC_TABLE_SIZE + dynamic_table.count_entries
|
|
208
208
|
|
|
@@ -211,7 +211,7 @@ module Biryani
|
|
|
211
211
|
else
|
|
212
212
|
dynamic_table[index - 1 - STATIC_TABLE_SIZE][0]
|
|
213
213
|
end
|
|
214
|
-
value, c = String.decode(
|
|
214
|
+
value, c = String.decode(io, c)
|
|
215
215
|
dynamic_table.store(name, value)
|
|
216
216
|
|
|
217
217
|
[[name, value], c]
|
|
@@ -223,16 +223,16 @@ module Biryani
|
|
|
223
223
|
# +---+---------------------------+
|
|
224
224
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.3
|
|
225
225
|
#
|
|
226
|
-
# @param
|
|
226
|
+
# @param io [IO::Buffer]
|
|
227
227
|
# @param cursor [Integer]
|
|
228
228
|
# @param dynamic_table [DynamicTable]
|
|
229
229
|
#
|
|
230
230
|
# @return [nil]
|
|
231
231
|
# @return [Integer]
|
|
232
|
-
def self.decode_dynamic_table_size_update(
|
|
233
|
-
raise Error::HPACKDecodeError unless cursor.zero? || (
|
|
232
|
+
def self.decode_dynamic_table_size_update(io, cursor, dynamic_table)
|
|
233
|
+
raise Error::HPACKDecodeError unless cursor.zero? || (io.get_value(:U8, 0) & 0b00100000).positive? && Integer.decode(io, 5, 0)[1] == cursor
|
|
234
234
|
|
|
235
|
-
max_size, c = Integer.decode(
|
|
235
|
+
max_size, c = Integer.decode(io, 5, cursor)
|
|
236
236
|
raise Error::HPACKDecodeError if max_size > dynamic_table.limit
|
|
237
237
|
|
|
238
238
|
dynamic_table.chomp!(max_size)
|
|
@@ -253,14 +253,14 @@ module Biryani
|
|
|
253
253
|
# +-------------------------------+
|
|
254
254
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.2.3
|
|
255
255
|
#
|
|
256
|
-
# @param
|
|
256
|
+
# @param io [IO::Buffer]
|
|
257
257
|
# @param cursor [Integer]
|
|
258
258
|
#
|
|
259
259
|
# @return [Array]
|
|
260
260
|
# @return [Integer]
|
|
261
|
-
def self.decode_literal_field_never_indexed(
|
|
262
|
-
name, c = String.decode(
|
|
263
|
-
value, c = String.decode(
|
|
261
|
+
def self.decode_literal_field_never_indexed(io, cursor)
|
|
262
|
+
name, c = String.decode(io, cursor + 1)
|
|
263
|
+
value, c = String.decode(io, c)
|
|
264
264
|
|
|
265
265
|
[[name, value], c]
|
|
266
266
|
end
|
|
@@ -275,14 +275,14 @@ module Biryani
|
|
|
275
275
|
# +-------------------------------+
|
|
276
276
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.2.3
|
|
277
277
|
#
|
|
278
|
-
# @param
|
|
278
|
+
# @param io [IO::Buffer]
|
|
279
279
|
# @param cursor [Integer]
|
|
280
280
|
# @param dynamic_table [DynamicTable]
|
|
281
281
|
#
|
|
282
282
|
# @return [Array]
|
|
283
283
|
# @return [Integer]
|
|
284
|
-
def self.decode_literal_value_never_indexed(
|
|
285
|
-
index, c = Integer.decode(
|
|
284
|
+
def self.decode_literal_value_never_indexed(io, cursor, dynamic_table)
|
|
285
|
+
index, c = Integer.decode(io, 4, cursor)
|
|
286
286
|
raise Error::HPACKDecodeError if index.zero?
|
|
287
287
|
raise Error::HPACKDecodeError if index > STATIC_TABLE_SIZE + dynamic_table.count_entries
|
|
288
288
|
|
|
@@ -291,7 +291,7 @@ module Biryani
|
|
|
291
291
|
else
|
|
292
292
|
dynamic_table[index - 1 - STATIC_TABLE_SIZE][0]
|
|
293
293
|
end
|
|
294
|
-
value, c = String.decode(
|
|
294
|
+
value, c = String.decode(io, c)
|
|
295
295
|
|
|
296
296
|
[[name, value], c]
|
|
297
297
|
end
|
|
@@ -310,14 +310,14 @@ module Biryani
|
|
|
310
310
|
# +-------------------------------+
|
|
311
311
|
# https://datatracker.ietf.org/doc/html/rfc7541#section-6.2.2
|
|
312
312
|
#
|
|
313
|
-
# @param
|
|
313
|
+
# @param io [IO::Buffer]
|
|
314
314
|
# @param cursor [Integer]
|
|
315
315
|
#
|
|
316
316
|
# @return [Array]
|
|
317
317
|
# @return [Integer]
|
|
318
|
-
def self.decode_literal_field_without_indexing(
|
|
319
|
-
name, c = String.decode(
|
|
320
|
-
value, c = String.decode(
|
|
318
|
+
def self.decode_literal_field_without_indexing(io, cursor)
|
|
319
|
+
name, c = String.decode(io, cursor + 1)
|
|
320
|
+
value, c = String.decode(io, c)
|
|
321
321
|
|
|
322
322
|
[[name, value], c]
|
|
323
323
|
end
|
|
@@ -331,14 +331,14 @@ module Biryani
|
|
|
331
331
|
# | Value String (Length octets) |
|
|
332
332
|
# +-------------------------------+
|
|
333
333
|
#
|
|
334
|
-
# @param
|
|
334
|
+
# @param io [IO::Buffer]
|
|
335
335
|
# @param cursor [Integer]
|
|
336
336
|
# @param dynamic_table [DynamicTable]
|
|
337
337
|
#
|
|
338
338
|
# @return [Array]
|
|
339
339
|
# @return [Integer]
|
|
340
|
-
def self.decode_literal_value_without_indexing(
|
|
341
|
-
index, c = Integer.decode(
|
|
340
|
+
def self.decode_literal_value_without_indexing(io, cursor, dynamic_table)
|
|
341
|
+
index, c = Integer.decode(io, 4, cursor)
|
|
342
342
|
raise Error::HPACKDecodeError if index.zero?
|
|
343
343
|
raise Error::HPACKDecodeError if index > STATIC_TABLE_SIZE + dynamic_table.count_entries
|
|
344
344
|
|
|
@@ -347,7 +347,7 @@ module Biryani
|
|
|
347
347
|
else
|
|
348
348
|
dynamic_table[index - 1 - STATIC_TABLE_SIZE][0]
|
|
349
349
|
end
|
|
350
|
-
value, c = String.decode(
|
|
350
|
+
value, c = String.decode(io, c)
|
|
351
351
|
|
|
352
352
|
[[name, value], c]
|
|
353
353
|
end
|
data/lib/biryani/hpack/fields.rb
CHANGED
|
@@ -14,10 +14,11 @@ module Biryani
|
|
|
14
14
|
#
|
|
15
15
|
# @return [Array]
|
|
16
16
|
def self.decode(s, dynamic_table)
|
|
17
|
+
io = IO::Buffer.for(s)
|
|
17
18
|
cursor = 0
|
|
18
19
|
fields = []
|
|
19
20
|
while cursor < s.bytesize
|
|
20
|
-
field, cursor = Field.decode(
|
|
21
|
+
field, cursor = Field.decode(io, cursor, dynamic_table)
|
|
21
22
|
fields << field unless field.nil?
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -262,46 +262,315 @@ module Biryani
|
|
|
262
262
|
11111111111111111111101110
|
|
263
263
|
111111111111111111111111111111
|
|
264
264
|
].freeze
|
|
265
|
-
DECODE_TABLE =
|
|
266
|
-
|
|
265
|
+
DECODE_TABLE = [
|
|
266
|
+
[0b1111111111000, 13],
|
|
267
|
+
[0b11111111111111111011000, 23],
|
|
268
|
+
[0b1111111111111111111111100010, 28],
|
|
269
|
+
[0b1111111111111111111111100011, 28],
|
|
270
|
+
[0b1111111111111111111111100100, 28],
|
|
271
|
+
[0b1111111111111111111111100101, 28],
|
|
272
|
+
[0b1111111111111111111111100110, 28],
|
|
273
|
+
[0b1111111111111111111111100111, 28],
|
|
274
|
+
[0b1111111111111111111111101000, 28],
|
|
275
|
+
[0b111111111111111111101010, 24],
|
|
276
|
+
[0b111111111111111111111111111100, 30],
|
|
277
|
+
[0b1111111111111111111111101001, 28],
|
|
278
|
+
[0b1111111111111111111111101010, 28],
|
|
279
|
+
[0b111111111111111111111111111101, 30],
|
|
280
|
+
[0b1111111111111111111111101011, 28],
|
|
281
|
+
[0b1111111111111111111111101100, 28],
|
|
282
|
+
[0b1111111111111111111111101101, 28],
|
|
283
|
+
[0b1111111111111111111111101110, 28],
|
|
284
|
+
[0b1111111111111111111111101111, 28],
|
|
285
|
+
[0b1111111111111111111111110000, 28],
|
|
286
|
+
[0b1111111111111111111111110001, 28],
|
|
287
|
+
[0b1111111111111111111111110010, 28],
|
|
288
|
+
[0b111111111111111111111111111110, 30],
|
|
289
|
+
[0b1111111111111111111111110011, 28],
|
|
290
|
+
[0b1111111111111111111111110100, 28],
|
|
291
|
+
[0b1111111111111111111111110101, 28],
|
|
292
|
+
[0b1111111111111111111111110110, 28],
|
|
293
|
+
[0b1111111111111111111111110111, 28],
|
|
294
|
+
[0b1111111111111111111111111000, 28],
|
|
295
|
+
[0b1111111111111111111111111001, 28],
|
|
296
|
+
[0b1111111111111111111111111010, 28],
|
|
297
|
+
[0b1111111111111111111111111011, 28],
|
|
298
|
+
[0b010100, 6],
|
|
299
|
+
[0b1111111000, 10],
|
|
300
|
+
[0b1111111001, 10],
|
|
301
|
+
[0b111111111010, 12],
|
|
302
|
+
[0b1111111111001, 13],
|
|
303
|
+
[0b010101, 6],
|
|
304
|
+
[0b11111000, 8],
|
|
305
|
+
[0b11111111010, 11],
|
|
306
|
+
[0b1111111010, 10],
|
|
307
|
+
[0b1111111011, 10],
|
|
308
|
+
[0b11111001, 8],
|
|
309
|
+
[0b11111111011, 11],
|
|
310
|
+
[0b11111010, 8],
|
|
311
|
+
[0b010110, 6],
|
|
312
|
+
[0b010111, 6],
|
|
313
|
+
[0b011000, 6],
|
|
314
|
+
[0b00000, 5],
|
|
315
|
+
[0b00001, 5],
|
|
316
|
+
[0b00010, 5],
|
|
317
|
+
[0b011001, 6],
|
|
318
|
+
[0b011010, 6],
|
|
319
|
+
[0b011011, 6],
|
|
320
|
+
[0b011100, 6],
|
|
321
|
+
[0b011101, 6],
|
|
322
|
+
[0b011110, 6],
|
|
323
|
+
[0b011111, 6],
|
|
324
|
+
[0b1011100, 7],
|
|
325
|
+
[0b11111011, 8],
|
|
326
|
+
[0b111111111111100, 15],
|
|
327
|
+
[0b100000, 6],
|
|
328
|
+
[0b111111111011, 12],
|
|
329
|
+
[0b1111111100, 10],
|
|
330
|
+
[0b1111111111010, 13],
|
|
331
|
+
[0b100001, 6],
|
|
332
|
+
[0b1011101, 7],
|
|
333
|
+
[0b1011110, 7],
|
|
334
|
+
[0b1011111, 7],
|
|
335
|
+
[0b1100000, 7],
|
|
336
|
+
[0b1100001, 7],
|
|
337
|
+
[0b1100010, 7],
|
|
338
|
+
[0b1100011, 7],
|
|
339
|
+
[0b1100100, 7],
|
|
340
|
+
[0b1100101, 7],
|
|
341
|
+
[0b1100110, 7],
|
|
342
|
+
[0b1100111, 7],
|
|
343
|
+
[0b1101000, 7],
|
|
344
|
+
[0b1101001, 7],
|
|
345
|
+
[0b1101010, 7],
|
|
346
|
+
[0b1101011, 7],
|
|
347
|
+
[0b1101100, 7],
|
|
348
|
+
[0b1101101, 7],
|
|
349
|
+
[0b1101110, 7],
|
|
350
|
+
[0b1101111, 7],
|
|
351
|
+
[0b1110000, 7],
|
|
352
|
+
[0b1110001, 7],
|
|
353
|
+
[0b1110010, 7],
|
|
354
|
+
[0b11111100, 8],
|
|
355
|
+
[0b1110011, 7],
|
|
356
|
+
[0b11111101, 8],
|
|
357
|
+
[0b1111111111011, 13],
|
|
358
|
+
[0b1111111111111110000, 19],
|
|
359
|
+
[0b1111111111100, 13],
|
|
360
|
+
[0b11111111111100, 14],
|
|
361
|
+
[0b100010, 6],
|
|
362
|
+
[0b111111111111101, 15],
|
|
363
|
+
[0b00011, 5],
|
|
364
|
+
[0b100011, 6],
|
|
365
|
+
[0b00100, 5],
|
|
366
|
+
[0b100100, 6],
|
|
367
|
+
[0b00101, 5],
|
|
368
|
+
[0b100101, 6],
|
|
369
|
+
[0b100110, 6],
|
|
370
|
+
[0b100111, 6],
|
|
371
|
+
[0b00110, 5],
|
|
372
|
+
[0b1110100, 7],
|
|
373
|
+
[0b1110101, 7],
|
|
374
|
+
[0b101000, 6],
|
|
375
|
+
[0b101001, 6],
|
|
376
|
+
[0b101010, 6],
|
|
377
|
+
[0b00111, 5],
|
|
378
|
+
[0b101011, 6],
|
|
379
|
+
[0b1110110, 7],
|
|
380
|
+
[0b101100, 6],
|
|
381
|
+
[0b01000, 5],
|
|
382
|
+
[0b01001, 5],
|
|
383
|
+
[0b101101, 6],
|
|
384
|
+
[0b1110111, 7],
|
|
385
|
+
[0b1111000, 7],
|
|
386
|
+
[0b1111001, 7],
|
|
387
|
+
[0b1111010, 7],
|
|
388
|
+
[0b1111011, 7],
|
|
389
|
+
[0b111111111111110, 15],
|
|
390
|
+
[0b11111111100, 11],
|
|
391
|
+
[0b11111111111101, 14],
|
|
392
|
+
[0b1111111111101, 13],
|
|
393
|
+
[0b1111111111111111111111111100, 28],
|
|
394
|
+
[0b11111111111111100110, 20],
|
|
395
|
+
[0b1111111111111111010010, 22],
|
|
396
|
+
[0b11111111111111100111, 20],
|
|
397
|
+
[0b11111111111111101000, 20],
|
|
398
|
+
[0b1111111111111111010011, 22],
|
|
399
|
+
[0b1111111111111111010100, 22],
|
|
400
|
+
[0b1111111111111111010101, 22],
|
|
401
|
+
[0b11111111111111111011001, 23],
|
|
402
|
+
[0b1111111111111111010110, 22],
|
|
403
|
+
[0b11111111111111111011010, 23],
|
|
404
|
+
[0b11111111111111111011011, 23],
|
|
405
|
+
[0b11111111111111111011100, 23],
|
|
406
|
+
[0b11111111111111111011101, 23],
|
|
407
|
+
[0b11111111111111111011110, 23],
|
|
408
|
+
[0b111111111111111111101011, 24],
|
|
409
|
+
[0b11111111111111111011111, 23],
|
|
410
|
+
[0b111111111111111111101100, 24],
|
|
411
|
+
[0b111111111111111111101101, 24],
|
|
412
|
+
[0b1111111111111111010111, 22],
|
|
413
|
+
[0b11111111111111111100000, 23],
|
|
414
|
+
[0b111111111111111111101110, 24],
|
|
415
|
+
[0b11111111111111111100001, 23],
|
|
416
|
+
[0b11111111111111111100010, 23],
|
|
417
|
+
[0b11111111111111111100011, 23],
|
|
418
|
+
[0b11111111111111111100100, 23],
|
|
419
|
+
[0b111111111111111011100, 21],
|
|
420
|
+
[0b1111111111111111011000, 22],
|
|
421
|
+
[0b11111111111111111100101, 23],
|
|
422
|
+
[0b1111111111111111011001, 22],
|
|
423
|
+
[0b11111111111111111100110, 23],
|
|
424
|
+
[0b11111111111111111100111, 23],
|
|
425
|
+
[0b111111111111111111101111, 24],
|
|
426
|
+
[0b1111111111111111011010, 22],
|
|
427
|
+
[0b111111111111111011101, 21],
|
|
428
|
+
[0b11111111111111101001, 20],
|
|
429
|
+
[0b1111111111111111011011, 22],
|
|
430
|
+
[0b1111111111111111011100, 22],
|
|
431
|
+
[0b11111111111111111101000, 23],
|
|
432
|
+
[0b11111111111111111101001, 23],
|
|
433
|
+
[0b111111111111111011110, 21],
|
|
434
|
+
[0b11111111111111111101010, 23],
|
|
435
|
+
[0b1111111111111111011101, 22],
|
|
436
|
+
[0b1111111111111111011110, 22],
|
|
437
|
+
[0b111111111111111111110000, 24],
|
|
438
|
+
[0b111111111111111011111, 21],
|
|
439
|
+
[0b1111111111111111011111, 22],
|
|
440
|
+
[0b11111111111111111101011, 23],
|
|
441
|
+
[0b11111111111111111101100, 23],
|
|
442
|
+
[0b111111111111111100000, 21],
|
|
443
|
+
[0b111111111111111100001, 21],
|
|
444
|
+
[0b1111111111111111100000, 22],
|
|
445
|
+
[0b111111111111111100010, 21],
|
|
446
|
+
[0b11111111111111111101101, 23],
|
|
447
|
+
[0b1111111111111111100001, 22],
|
|
448
|
+
[0b11111111111111111101110, 23],
|
|
449
|
+
[0b11111111111111111101111, 23],
|
|
450
|
+
[0b11111111111111101010, 20],
|
|
451
|
+
[0b1111111111111111100010, 22],
|
|
452
|
+
[0b1111111111111111100011, 22],
|
|
453
|
+
[0b1111111111111111100100, 22],
|
|
454
|
+
[0b11111111111111111110000, 23],
|
|
455
|
+
[0b1111111111111111100101, 22],
|
|
456
|
+
[0b1111111111111111100110, 22],
|
|
457
|
+
[0b11111111111111111110001, 23],
|
|
458
|
+
[0b11111111111111111111100000, 26],
|
|
459
|
+
[0b11111111111111111111100001, 26],
|
|
460
|
+
[0b11111111111111101011, 20],
|
|
461
|
+
[0b1111111111111110001, 19],
|
|
462
|
+
[0b1111111111111111100111, 22],
|
|
463
|
+
[0b11111111111111111110010, 23],
|
|
464
|
+
[0b1111111111111111101000, 22],
|
|
465
|
+
[0b1111111111111111111101100, 25],
|
|
466
|
+
[0b11111111111111111111100010, 26],
|
|
467
|
+
[0b11111111111111111111100011, 26],
|
|
468
|
+
[0b11111111111111111111100100, 26],
|
|
469
|
+
[0b111111111111111111111011110, 27],
|
|
470
|
+
[0b111111111111111111111011111, 27],
|
|
471
|
+
[0b11111111111111111111100101, 26],
|
|
472
|
+
[0b111111111111111111110001, 24],
|
|
473
|
+
[0b1111111111111111111101101, 25],
|
|
474
|
+
[0b1111111111111110010, 19],
|
|
475
|
+
[0b111111111111111100011, 21],
|
|
476
|
+
[0b11111111111111111111100110, 26],
|
|
477
|
+
[0b111111111111111111111100000, 27],
|
|
478
|
+
[0b111111111111111111111100001, 27],
|
|
479
|
+
[0b11111111111111111111100111, 26],
|
|
480
|
+
[0b111111111111111111111100010, 27],
|
|
481
|
+
[0b111111111111111111110010, 24],
|
|
482
|
+
[0b111111111111111100100, 21],
|
|
483
|
+
[0b111111111111111100101, 21],
|
|
484
|
+
[0b11111111111111111111101000, 26],
|
|
485
|
+
[0b11111111111111111111101001, 26],
|
|
486
|
+
[0b1111111111111111111111111101, 28],
|
|
487
|
+
[0b111111111111111111111100011, 27],
|
|
488
|
+
[0b111111111111111111111100100, 27],
|
|
489
|
+
[0b111111111111111111111100101, 27],
|
|
490
|
+
[0b11111111111111101100, 20],
|
|
491
|
+
[0b111111111111111111110011, 24],
|
|
492
|
+
[0b11111111111111101101, 20],
|
|
493
|
+
[0b111111111111111100110, 21],
|
|
494
|
+
[0b1111111111111111101001, 22],
|
|
495
|
+
[0b111111111111111100111, 21],
|
|
496
|
+
[0b111111111111111101000, 21],
|
|
497
|
+
[0b11111111111111111110011, 23],
|
|
498
|
+
[0b1111111111111111101010, 22],
|
|
499
|
+
[0b1111111111111111101011, 22],
|
|
500
|
+
[0b1111111111111111111101110, 25],
|
|
501
|
+
[0b1111111111111111111101111, 25],
|
|
502
|
+
[0b111111111111111111110100, 24],
|
|
503
|
+
[0b111111111111111111110101, 24],
|
|
504
|
+
[0b11111111111111111111101010, 26],
|
|
505
|
+
[0b11111111111111111110100, 23],
|
|
506
|
+
[0b11111111111111111111101011, 26],
|
|
507
|
+
[0b111111111111111111111100110, 27],
|
|
508
|
+
[0b11111111111111111111101100, 26],
|
|
509
|
+
[0b11111111111111111111101101, 26],
|
|
510
|
+
[0b111111111111111111111100111, 27],
|
|
511
|
+
[0b111111111111111111111101000, 27],
|
|
512
|
+
[0b111111111111111111111101001, 27],
|
|
513
|
+
[0b111111111111111111111101010, 27],
|
|
514
|
+
[0b111111111111111111111101011, 27],
|
|
515
|
+
[0b1111111111111111111111111110, 28],
|
|
516
|
+
[0b111111111111111111111101100, 27],
|
|
517
|
+
[0b111111111111111111111101101, 27],
|
|
518
|
+
[0b111111111111111111111101110, 27],
|
|
519
|
+
[0b111111111111111111111101111, 27],
|
|
520
|
+
[0b111111111111111111111110000, 27],
|
|
521
|
+
[0b11111111111111111111101110, 26],
|
|
522
|
+
[0b111111111111111111111111111111, 30]
|
|
523
|
+
].each_with_index.to_h.freeze
|
|
524
|
+
EOS = (1 << 30) - 1
|
|
267
525
|
|
|
268
526
|
private_constant :ENCODE_TABLE, :DECODE_TABLE, :EOS
|
|
269
527
|
Ractor.make_shareable(ENCODE_TABLE)
|
|
270
528
|
Ractor.make_shareable(DECODE_TABLE)
|
|
271
|
-
Ractor.make_shareable(EOS)
|
|
272
529
|
|
|
273
530
|
# @param s [String]
|
|
274
531
|
#
|
|
275
532
|
# @return [String]
|
|
276
533
|
def self.encode(s)
|
|
277
|
-
bits = s.bytes.map { |sym| ENCODE_TABLE[sym] }
|
|
278
|
-
bits << '1' * ((8 - bits.bytesize) % 8)
|
|
279
|
-
[bits].pack('B*')
|
|
280
|
-
end
|
|
534
|
+
bits = s.bytes.map { |sym| ENCODE_TABLE[sym] }
|
|
281
535
|
|
|
282
|
-
|
|
536
|
+
acc = IO::Buffer.new(bits.sum(&:bytesize))
|
|
537
|
+
offset = 0
|
|
538
|
+
bits.each do |s|
|
|
539
|
+
acc.set_string(s, offset)
|
|
540
|
+
offset += s.bytesize
|
|
541
|
+
end
|
|
283
542
|
|
|
284
|
-
|
|
543
|
+
[acc.get_string.ljust((acc.size + 7) & ~7, '1')].pack('B*')
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# @param io [IO::Buffer]
|
|
547
|
+
# @param cursor [Integer]
|
|
548
|
+
# @param length [Integer]
|
|
285
549
|
#
|
|
286
550
|
# @raise [HuffmanDecodeError]
|
|
287
551
|
#
|
|
288
552
|
# @return [String]
|
|
289
|
-
def self.decode(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
553
|
+
def self.decode(io, cursor, length)
|
|
554
|
+
res = ''.b
|
|
555
|
+
bits = 0
|
|
556
|
+
bits_len = 0
|
|
557
|
+
bytes = io.get_values([:U8] * length, cursor)
|
|
558
|
+
(length * 8).times do |i|
|
|
559
|
+
bits_len += 1
|
|
560
|
+
bits += 1 if (bytes[i / 8] & (1 << 7 - (i % 8))).positive?
|
|
561
|
+
raise Error::HuffmanDecodeError if bits == EOS
|
|
294
562
|
|
|
295
|
-
if (chr = DECODE_TABLE[
|
|
296
|
-
|
|
297
|
-
|
|
563
|
+
if (chr = DECODE_TABLE[[bits, bits_len]])
|
|
564
|
+
res << chr
|
|
565
|
+
bits = 0
|
|
566
|
+
bits_len = 0
|
|
567
|
+
else
|
|
568
|
+
bits <<= 1
|
|
298
569
|
end
|
|
299
|
-
|
|
300
|
-
acc
|
|
301
570
|
end
|
|
302
|
-
raise Error::HuffmanDecodeError if
|
|
571
|
+
raise Error::HuffmanDecodeError if bits_len.positive? && bits != (2 << bits_len) - 2 || bits_len >= 8
|
|
303
572
|
|
|
304
|
-
res
|
|
573
|
+
res
|
|
305
574
|
end
|
|
306
575
|
end
|
|
307
576
|
# rubocop: enable Metrics/ModuleLength
|
|
@@ -40,26 +40,30 @@ module Biryani
|
|
|
40
40
|
bytes.pack('C*')
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
# @param
|
|
43
|
+
# @param io [IO::Buffer]
|
|
44
44
|
# @param cursor [Integer]
|
|
45
45
|
# @param n [Integer]
|
|
46
46
|
#
|
|
47
47
|
# @return [Integer]
|
|
48
48
|
# @return [Integer]
|
|
49
|
-
def self.decode(
|
|
49
|
+
def self.decode(io, n, cursor)
|
|
50
50
|
limit = (1 << n) - 1
|
|
51
|
-
h =
|
|
51
|
+
h = io.get_value(:U8, cursor)
|
|
52
52
|
return [h & limit, cursor + 1] if (h & limit) != limit
|
|
53
53
|
|
|
54
54
|
res = limit
|
|
55
|
-
|
|
55
|
+
c = cursor + 1
|
|
56
|
+
i = 0
|
|
57
|
+
loop do
|
|
58
|
+
byte = io.get_value(:U8, c + i)
|
|
56
59
|
res += (byte & 127) * 2**(i * 7)
|
|
57
|
-
cursor += 1
|
|
58
60
|
|
|
59
61
|
break if (byte & 128).zero?
|
|
62
|
+
|
|
63
|
+
i += 1
|
|
60
64
|
end
|
|
61
65
|
|
|
62
|
-
[res,
|
|
66
|
+
[res, c + i + 1]
|
|
63
67
|
end
|
|
64
68
|
end
|
|
65
69
|
end
|
data/lib/biryani/hpack/string.rb
CHANGED
|
@@ -23,17 +23,17 @@ module Biryani
|
|
|
23
23
|
Integer.encode(res.bytesize, 7, mask) + res
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# @param
|
|
26
|
+
# @param io [IO::Buffer]
|
|
27
27
|
# @param cursor [Integer]
|
|
28
28
|
#
|
|
29
29
|
# @return [String]
|
|
30
30
|
# @return [Integer]
|
|
31
|
-
def self.decode(
|
|
32
|
-
h = (
|
|
33
|
-
len, c = Integer.decode(
|
|
34
|
-
return [Huffman.decode(
|
|
31
|
+
def self.decode(io, cursor)
|
|
32
|
+
h = (io.get_value(:U8, cursor) & 0b10000000).positive?
|
|
33
|
+
len, c = Integer.decode(io, 7, cursor)
|
|
34
|
+
return [Huffman.decode(io, c, len), c + len] if h
|
|
35
35
|
|
|
36
|
-
[
|
|
36
|
+
[io.get_string(c, len), c + len]
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
data/lib/biryani/http_request.rb
CHANGED
|
@@ -39,7 +39,7 @@ module Biryani
|
|
|
39
39
|
# TODO: trailers
|
|
40
40
|
|
|
41
41
|
if name == 'cookie' && @h.key?('cookie')
|
|
42
|
-
@h[name]
|
|
42
|
+
@h[name] << "; #{value}"
|
|
43
43
|
else
|
|
44
44
|
@h[name] = value
|
|
45
45
|
end
|
|
@@ -65,7 +65,8 @@ module Biryani
|
|
|
65
65
|
#
|
|
66
66
|
# @return [HTTPRequest]
|
|
67
67
|
def build(s)
|
|
68
|
-
|
|
68
|
+
h = @h.transform_values(&:dup)
|
|
69
|
+
self.class.http_request(h, s)
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
# @param fields [Hash<String, String>]
|