http-2 1.1.0 → 1.1.2

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: b5f246529e7f64c9b6c841e7733a8bcc74ce34452fa0569c48bf1a858d47d659
4
- data.tar.gz: ae38ca8cb1814c168fa2e90f729b12b0a3017a41d35406472dfe425308adb107
3
+ metadata.gz: 05c943cd91ee0339a8542cde981636d694618d64c80e30ff0f6ccb55fc636d45
4
+ data.tar.gz: 325abe52e215d7d7007f9fe383a3e8ebd8b1cdfae1a004fc227b5371efb637b8
5
5
  SHA512:
6
- metadata.gz: 5cc781007b5fa286344fb6ebc1495b4caaddc5c25749ae1ab6fb938f18f17ac50624bbf0160cb3e6661b91d1290ea350a550696e6ed28db20f6bb34c0ca0b6c7
7
- data.tar.gz: 2bbcd46df4b28f59f7b64c68338998bae8d5199ee71942704ae32fb8e643c328b888b2579db4d8bf1b8ed220e76ea1bc27d9ef14ecc5ad21c05cb35252f2e4d1
6
+ metadata.gz: 88a97115e7d09b247b669c304fd3bced538c8be53263ca4f2650ddae125e7d7a3fa6b97419e2f8dbac9dcd3c95a0c581a494fc4b185664ae5d2d64bee9da3d7c
7
+ data.tar.gz: f8f257ed1e984d82c8209677d2496c21f000c9dc23ca6f754fe50b1309c4c2b92491fb4d6dfb608eb5f54923cf47fb1a2f508bbb97fa4ec2b1d62b5f51dbb145
@@ -403,8 +403,9 @@ module HTTP2
403
403
  # endpoints MAY choose to treat frames that arrive a significant
404
404
  # time after sending END_STREAM as a connection error.
405
405
  when :rst_stream
406
- stream = @streams_recently_closed[stream_id]
407
- connection_error(:protocol_error, msg: "sent window update on idle stream") unless stream
406
+ unless @streams_recently_closed.key?(stream_id)
407
+ connection_error(:protocol_error, msg: "sent window update on idle stream")
408
+ end
408
409
  else
409
410
  # An endpoint that receives an unexpected stream identifier
410
411
  # MUST respond with a connection error of type PROTOCOL_ERROR.
@@ -524,7 +525,8 @@ module HTTP2
524
525
  when :closed
525
526
  case frame_type
526
527
  when :goaway
527
- connection_error
528
+ # 6.8. GOAWAY
529
+ # An endpoint MAY send multiple GOAWAY frames if circumstances change.
528
530
  when :ping
529
531
  ping_management(frame)
530
532
  else
@@ -25,7 +25,7 @@ module HTTP2
25
25
  def read_str(str, n)
26
26
  return "".b if n == 0
27
27
 
28
- chunk = str.byteslice(0..n - 1)
28
+ chunk = str.byteslice(0..(n - 1))
29
29
  remaining = str.byteslice(n..-1)
30
30
  remaining ? str.replace(remaining) : str.clear
31
31
  chunk
data/lib/http/2/framer.rb CHANGED
@@ -148,9 +148,12 @@ module HTTP2
148
148
 
149
149
  header = buffer
150
150
 
151
+ # make sure the buffer is binary and unfrozen
151
152
  if buffer.frozen?
152
153
  header = String.new("", encoding: Encoding::BINARY, capacity: buffer.bytesize + 9) # header length
153
- header << buffer
154
+ append_str(header, buffer)
155
+ else
156
+ header.force_encoding(Encoding::BINARY)
154
157
  end
155
158
 
156
159
  pack([
@@ -182,7 +185,7 @@ module HTTP2
182
185
  {
183
186
  type: type,
184
187
  flags: FRAME_FLAGS[type].filter_map do |name, pos|
185
- name if flags.anybits?((1 << pos))
188
+ name if flags.anybits?(1 << pos)
186
189
  end,
187
190
  length: length,
188
191
  stream: stream & RBIT
@@ -268,7 +271,7 @@ module HTTP2
268
271
  append_str(bytes, frame[:payload])
269
272
 
270
273
  when :ping
271
- bytes = frame[:payload]
274
+ bytes = frame[:payload].b
272
275
  raise CompressionError, "Invalid payload size (#{bytes.size} != 8 bytes)" if bytes.bytesize != 8
273
276
 
274
277
  length = 8
@@ -342,6 +345,13 @@ module HTTP2
342
345
  raise CompressionError, "Invalid padding #{padlen}"
343
346
  end
344
347
 
348
+ # make sure the buffer is binary and unfrozen
349
+ if bytes.frozen?
350
+ bytes = bytes.b
351
+ else
352
+ bytes.force_encoding(Encoding::BINARY)
353
+ end
354
+
345
355
  length += padlen
346
356
  pack([padlen -= 1], UINT8, buffer: bytes, offset: 0)
347
357
  frame[:flags] += [:padded]
@@ -349,7 +359,7 @@ module HTTP2
349
359
  # Padding: Padding octets that contain no application semantic value.
350
360
  # Padding octets MUST be set to zero when sending and ignored when
351
361
  # receiving.
352
- append_str(bytes, ("\0" * padlen))
362
+ append_str(bytes, "\0" * padlen)
353
363
  end
354
364
 
355
365
  frame[:length] = length
@@ -211,7 +211,7 @@ module HTTP2
211
211
  emit = [name, value]
212
212
 
213
213
  # add to table
214
- if type == :incremental && size_check(name.bytesize + value.bytesize + 32)
214
+ if type == :incremental && size_check?(name.bytesize + value.bytesize + 32)
215
215
  @table.unshift(emit)
216
216
  @current_table_size += name.bytesize + value.bytesize + 32
217
217
  @_table_updated = true
@@ -302,7 +302,7 @@ module HTTP2
302
302
  # When the size is reduced, some headers might be evicted.
303
303
  def table_size=(size)
304
304
  @limit = size
305
- size_check(0)
305
+ resize_table(0)
306
306
  end
307
307
 
308
308
  def listen_on_table
@@ -313,22 +313,25 @@ module HTTP2
313
313
 
314
314
  private
315
315
 
316
+ def resize_table(cmdsize)
317
+ return if @table.empty?
318
+
319
+ while @current_table_size + cmdsize > @limit
320
+
321
+ name, value = @table.pop
322
+ @current_table_size -= name.bytesize + value.bytesize + 32
323
+ break if @table.empty?
324
+
325
+ end
326
+ end
327
+
316
328
  # To keep the dynamic table size lower than or equal to @limit,
317
329
  # remove one or more entries at the end of the dynamic table.
318
330
  #
319
331
  # @param cmdsize [Integer]
320
332
  # @return [Boolean] whether +cmd+ fits in the dynamic table.
321
- def size_check(cmdsize)
322
- unless @table.empty?
323
- while @current_table_size + cmdsize > @limit
324
-
325
- name, value = @table.pop
326
- @current_table_size -= name.bytesize + value.bytesize + 32
327
- break if @table.empty?
328
-
329
- end
330
- end
331
-
333
+ def size_check?(cmdsize)
334
+ resize_table(cmdsize)
332
335
  cmdsize <= @limit
333
336
  end
334
337
  end
@@ -29,7 +29,7 @@ module HTTP2
29
29
  def encode(str, buffer = "".b)
30
30
  bitstring = String.new("", encoding: Encoding::BINARY, capacity: (str.bytesize * 30) + ((8 - str.size) % 8))
31
31
  str.each_byte { |chr| append_str(bitstring, ENCODE_TABLE[chr]) }
32
- append_str(bitstring, ("1" * ((8 - bitstring.size) % 8)))
32
+ append_str(bitstring, "1" * ((8 - bitstring.size) % 8))
33
33
  pack([bitstring], "B*", buffer: buffer)
34
34
  end
35
35
 
data/lib/http/2/stream.rb CHANGED
@@ -197,21 +197,18 @@ module HTTP2
197
197
  #
198
198
  # @param frame [Hash]
199
199
  def send(frame)
200
- process_priority(frame) if frame[:type] == :priority
201
-
202
200
  case frame[:type]
203
201
  when :data
204
- # @remote_window is maintained in send_data
205
- send_data(frame)
202
+ # stream state management is maintained in send_data
203
+ return send_data(frame)
206
204
  when :window_update
207
- manage_state(frame) do
208
- @local_window += frame[:increment]
209
- emit(:frame, frame)
210
- end
211
- else
212
- manage_state(frame) do
213
- emit(:frame, frame)
214
- end
205
+ @local_window += frame[:increment]
206
+ when :priority
207
+ process_priority(frame)
208
+ end
209
+
210
+ manage_state(frame) do
211
+ emit(:frame, frame)
215
212
  end
216
213
  end
217
214
 
@@ -384,7 +381,7 @@ module HTTP2
384
381
  else
385
382
  event(:open)
386
383
  end
387
- when :priority then process_priority(frame)
384
+ when :priority
388
385
  else stream_error(:protocol_error)
389
386
  end
390
387
  end
@@ -405,19 +402,20 @@ module HTTP2
405
402
  # WINDOW_UPDATE on a stream in this state MUST be treated as a
406
403
  # connection error (Section 5.4.1) of type PROTOCOL_ERROR.
407
404
  when :reserved_local
408
- @state = if sending
409
- case frame[:type]
410
- when :headers then event(:half_closed_remote)
411
- when :rst_stream then event(:local_rst)
412
- else stream_error
413
- end
414
- else
415
- case frame[:type]
416
- when :rst_stream then event(:remote_rst)
417
- when :priority, :window_update then @state
418
- else stream_error
419
- end
420
- end
405
+ if sending
406
+ case frame[:type]
407
+ when :headers then event(:half_closed_remote)
408
+ when :rst_stream then event(:local_rst)
409
+ when :priority
410
+ else stream_error
411
+ end
412
+ else
413
+ case frame[:type]
414
+ when :rst_stream then event(:remote_rst)
415
+ when :priority, :window_update
416
+ else stream_error
417
+ end
418
+ end
421
419
 
422
420
  # A stream in the "reserved (remote)" state has been reserved by a
423
421
  # remote peer.
@@ -434,19 +432,20 @@ module HTTP2
434
432
  # PRIORITY on a stream in this state MUST be treated as a connection
435
433
  # error (Section 5.4.1) of type PROTOCOL_ERROR.
436
434
  when :reserved_remote
437
- @state = if sending
438
- case frame[:type]
439
- when :rst_stream then event(:local_rst)
440
- when :priority, :window_update then @state
441
- else stream_error
442
- end
443
- else
444
- case frame[:type]
445
- when :headers then event(:half_closed_local)
446
- when :rst_stream then event(:remote_rst)
447
- else stream_error
448
- end
449
- end
435
+ if sending
436
+ case frame[:type]
437
+ when :rst_stream then event(:local_rst)
438
+ when :priority, :window_update
439
+ else stream_error
440
+ end
441
+ else
442
+ case frame[:type]
443
+ when :headers then event(:half_closed_local)
444
+ when :rst_stream then event(:remote_rst)
445
+ when :priority
446
+ else stream_error
447
+ end
448
+ end
450
449
 
451
450
  # A stream in the "open" state may be used by both peers to send
452
451
  # frames of any type. In this state, sending peers observe
@@ -465,12 +464,14 @@ module HTTP2
465
464
  when :data, :headers, :continuation
466
465
  event(:half_closed_local) if end_stream?(frame)
467
466
  when :rst_stream then event(:local_rst)
467
+ when :priority
468
468
  end
469
469
  else
470
470
  case frame[:type]
471
471
  when :data, :headers, :continuation
472
472
  event(:half_closed_remote) if end_stream?(frame)
473
473
  when :rst_stream then event(:remote_rst)
474
+ when :priority
474
475
  end
475
476
  end
476
477
 
@@ -490,10 +491,7 @@ module HTTP2
490
491
  case frame[:type]
491
492
  when :rst_stream
492
493
  event(:local_rst)
493
- when :priority
494
- process_priority(frame)
495
- when :window_update
496
- # nop here
494
+ when :priority, :window_update
497
495
  else
498
496
  stream_error
499
497
  end
@@ -502,10 +500,7 @@ module HTTP2
502
500
  when :data, :headers, :continuation
503
501
  event(:remote_closed) if end_stream?(frame)
504
502
  when :rst_stream then event(:remote_rst)
505
- when :priority
506
- process_priority(frame)
507
- when :window_update
508
- # nop here
503
+ when :priority, :window_update
509
504
  end
510
505
  end
511
506
 
@@ -534,9 +529,7 @@ module HTTP2
534
529
  else
535
530
  case frame[:type]
536
531
  when :rst_stream then event(:remote_rst)
537
- when :priority
538
- process_priority(frame)
539
- when :window_update
532
+ when :priority, :window_update
540
533
  # nop
541
534
  else
542
535
  stream_error(:stream_closed)
@@ -584,19 +577,15 @@ module HTTP2
584
577
  when :closed
585
578
  if sending
586
579
  case frame[:type]
587
- when :rst_stream # ignore
588
- when :priority
589
- process_priority(frame)
580
+ when :rst_stream, :priority
590
581
  else
591
582
  stream_error(:stream_closed) unless frame[:type] == :rst_stream
592
583
  end
593
- elsif frame[:type] == :priority
594
- process_priority(frame)
595
584
  else
596
585
  case @closed
597
586
  when :remote_rst, :remote_closed
598
587
  case frame[:type]
599
- when :rst_stream, :window_update # nop here
588
+ when :priority, :rst_stream, :window_update # nop here
600
589
  else
601
590
  stream_error(:stream_closed)
602
591
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP2
4
- VERSION = "1.1.0"
4
+ VERSION = "1.1.2"
5
5
  end
@@ -46,7 +46,9 @@ module HTTP2
46
46
 
47
47
  def add_to_table: (string name, string value) -> void
48
48
 
49
- def size_check: (Integer cmdsize) -> bool
49
+ def resize_table: (Integer cmdsize) -> void
50
+
51
+ def size_check?: (Integer cmdsize) -> bool
50
52
  end
51
53
  end
52
54
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
@@ -9,7 +9,7 @@ authors:
9
9
  - Kaoru Maeda
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-04-10 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Pure-ruby HTTP 2.0 protocol implementation
15
15
  email:
@@ -77,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
77
  - !ruby/object:Gem::Version
78
78
  version: '0'
79
79
  requirements: []
80
- rubygems_version: 3.6.2
80
+ rubygems_version: 3.6.9
81
81
  specification_version: 4
82
82
  summary: Pure-ruby HTTP 2.0 protocol implementation
83
83
  test_files: []