http-2-next 0.3.0 → 0.4.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: c4ce4e3302e32d2c860cf38d25f82186a233ae9bb446bde932d185ca398d4eec
4
- data.tar.gz: c2428f11638405fa7c92390745f4c21022627500fe54d564a46f06e83967d126
3
+ metadata.gz: 7db81040e42ff1170fbbcc93611c502b3b7fb1f3e4dcad7dd0ede42eaf08d0a4
4
+ data.tar.gz: 3f6027a4d12dc034726040554a5ba4aab96c145ff7acc7fc6c8287afdc4b49d3
5
5
  SHA512:
6
- metadata.gz: 5a10531d34c3d37989a6de029b4bfdca1b9742b7614a7785179bea4d8794568b58bd88641c259721520f803b1f6577c2e41ddb49bff75564edfbdf9d422124fc
7
- data.tar.gz: 8d9d7e74f52d079a7f9021bcd7679bd7544b1e30d17cdd5f42de24326812c46f4c3f8208f3132ba0e9d0df46b6c947238781a48abbf6d1cacc95da69b3227293
6
+ metadata.gz: edb1d8dcf5509b2d51c64a66bf5396f7603817988b57894ba9529e877714c4c3ea847fd403ce75bb285a545a17758a8405277c9c36323425a2cd83d52ce842d7
7
+ data.tar.gz: fff64e2206e276c3b174d309d8a32181058dfde60f507953a215d6d5850abb754e6db5c5a54247d946b61bf6a74b57a748d8f4138e9c8c533e18000bb69d40e3
data/lib/http/2/next.rb CHANGED
@@ -4,7 +4,6 @@ require "http/2/next/version"
4
4
  require "http/2/next/extensions"
5
5
  require "http/2/next/error"
6
6
  require "http/2/next/emitter"
7
- require "http/2/next/buffer"
8
7
  require "http/2/next/flow_buffer"
9
8
  require "http/2/next/header"
10
9
  require "http/2/next/framer"
@@ -51,6 +51,8 @@ module HTTP2Next
51
51
  include Emitter
52
52
  include Error
53
53
 
54
+ using StringExtensions
55
+
54
56
  # Connection state (:new, :closed).
55
57
  attr_reader :state
56
58
 
@@ -98,7 +100,7 @@ module HTTP2Next
98
100
  @remote_window_limit = @remote_settings[:settings_initial_window_size]
99
101
  @remote_window = @remote_window_limit
100
102
 
101
- @recv_buffer = Buffer.new
103
+ @recv_buffer = "".b
102
104
  @continuation = []
103
105
  @error = nil
104
106
 
@@ -159,7 +161,7 @@ module HTTP2Next
159
161
  send(type: :goaway, last_stream: last_stream,
160
162
  error: error, payload: payload)
161
163
  @state = :closed
162
- @closed_since = Time.now
164
+ @closed_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
163
165
  end
164
166
 
165
167
  # Sends a WINDOW_UPDATE frame to the peer.
@@ -245,7 +247,7 @@ module HTTP2Next
245
247
  @continuation.clear
246
248
 
247
249
  frame.delete(:length)
248
- frame[:payload] = Buffer.new(payload)
250
+ frame[:payload] = payload
249
251
  frame[:flags] << :end_headers
250
252
  end
251
253
 
@@ -478,7 +480,7 @@ module HTTP2Next
478
480
  # the connection, although a new connection can be established
479
481
  # for new streams.
480
482
  @state = :closed
481
- @closed_since = Time.now
483
+ @closed_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
482
484
  emit(:goaway, frame[:last_stream], frame[:error], frame[:payload])
483
485
  when :altsvc
484
486
  # 4. The ALTSVC HTTP/2 Frame
@@ -503,7 +505,7 @@ module HTTP2Next
503
505
  when :ping
504
506
  ping_management(frame)
505
507
  else
506
- connection_error if (Time.now - @closed_since) > 15
508
+ connection_error if (Process.clock_gettime(Process::CLOCK_MONOTONIC) - @closed_since) > 15
507
509
  end
508
510
  else
509
511
  connection_error
@@ -671,7 +673,7 @@ module HTTP2Next
671
673
  #
672
674
  # @param frame [Hash]
673
675
  def decode_headers(frame)
674
- frame[:payload] = @decompressor.decode(frame[:payload], frame) if frame[:payload].is_a? Buffer
676
+ frame[:payload] = @decompressor.decode(frame[:payload], frame) if frame[:payload].is_a?(String)
675
677
  rescue CompressionError => e
676
678
  connection_error(:compression_error, e: e)
677
679
  rescue ProtocolError => e
@@ -686,15 +688,16 @@ module HTTP2Next
686
688
  # @return [Array of Frame]
687
689
  def encode_headers(frame)
688
690
  payload = frame[:payload]
689
- payload = @compressor.encode(payload) unless payload.is_a? Buffer
691
+ payload = @compressor.encode(payload) unless payload.is_a?(String)
690
692
 
691
693
  frames = []
692
694
 
693
- while payload.bytesize > 0
695
+ while payload && payload.bytesize > 0
694
696
  cont = frame.dup
695
697
  cont[:type] = :continuation
696
698
  cont[:flags] = []
697
- cont[:payload] = payload.slice!(0, @remote_settings[:settings_max_frame_size])
699
+ cont[:payload] = payload.byteslice(0, @remote_settings[:settings_max_frame_size])
700
+ payload = payload.byteslice(@remote_settings[:settings_max_frame_size]..-1)
698
701
  frames << cont
699
702
  end
700
703
  if frames.empty?
@@ -735,11 +738,11 @@ module HTTP2Next
735
738
  # References to such streams will be purged whenever another stream
736
739
  # is closed, with a minimum of 15s RTT time window.
737
740
  @streams_recently_closed.reject! do |stream_id, v|
738
- to_delete = (Time.now - v) > 15
741
+ to_delete = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - v) > 15
739
742
  @streams.delete stream_id if to_delete
740
743
  to_delete
741
744
  end
742
- @streams_recently_closed[id] = Time.now
745
+ @streams_recently_closed[id] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
743
746
  end
744
747
 
745
748
  stream.on(:promise, &method(:promise)) if is_a? Server
@@ -757,7 +760,7 @@ module HTTP2Next
757
760
 
758
761
  def verify_pseudo_headers(frame, mandatory_headers)
759
762
  headers = frame[:payload]
760
- return if headers.is_a?(Buffer)
763
+ return if headers.is_a?(String)
761
764
 
762
765
  pseudo_headers = headers.take_while do |field, value|
763
766
  # use this loop to validate pseudo-headers
@@ -12,8 +12,23 @@ module HTTP2Next
12
12
  end
13
13
 
14
14
  module StringExtensions
15
- unless String.method_defined?(:unpack1)
16
- refine String do
15
+ refine String do
16
+ def read(n)
17
+ chunk = byteslice(0..n - 1)
18
+ remaining = byteslice(n..-1)
19
+ remaining ? replace(remaining) : clear
20
+ chunk
21
+ end
22
+
23
+ def read_uint32
24
+ read(4).unpack1("N")
25
+ end
26
+
27
+ def shift_byte
28
+ read(1).ord
29
+ end
30
+
31
+ unless String.method_defined?(:unpack1)
17
32
  def unpack1(format)
18
33
  unpack(format).first
19
34
  end
@@ -138,10 +138,13 @@ module HTTP2Next
138
138
 
139
139
  # Split frame so that it fits in the window
140
140
  # TODO: consider padding!
141
- frame[:payload] = payload.slice!(0, window_size)
142
- frame[:length] = frame[:payload].bytesize
143
- chunk[:length] = payload.bytesize
141
+ frame_bytes = payload.byteslice(0, window_size)
142
+ payload = payload.byteslice(window_size..-1)
143
+
144
+ frame[:payload] = frame_bytes
145
+ frame[:length] = frame_bytes.bytesize
144
146
  chunk[:payload] = payload
147
+ chunk[:length] = payload.bytesize
145
148
 
146
149
  # if no longer last frame in sequence...
147
150
  frame[:flags] -= [:end_stream] if end_stream
@@ -159,7 +159,7 @@ module HTTP2Next
159
159
  # @return [Hash] the corresponding frame
160
160
  def read_common_header(buf)
161
161
  frame = {}
162
- len_hi, len_lo, type, flags, stream = buf.slice(0, 9).unpack(HEADERPACK)
162
+ len_hi, len_lo, type, flags, stream = buf.byteslice(0, 9).unpack(HEADERPACK)
163
163
 
164
164
  frame[:length] = (len_hi << FRAME_LENGTH_HISHIFT) | len_lo
165
165
  frame[:type], = FRAME_TYPES.find { |_t, pos| type == pos }
@@ -178,7 +178,7 @@ module HTTP2Next
178
178
  #
179
179
  # @param frame [Hash]
180
180
  def generate(frame)
181
- bytes = Buffer.new
181
+ bytes = "".b
182
182
  length = 0
183
183
 
184
184
  frame[:flags] ||= []
@@ -360,7 +360,7 @@ module HTTP2Next
360
360
  frame[:padding] = padlen + 1
361
361
  raise ProtocolError, "padding too long" if padlen > payload.bytesize
362
362
 
363
- payload.slice!(-padlen, padlen) if padlen > 0
363
+ payload = payload.byteslice(0, payload.bytesize - padlen) if padlen > 0
364
364
  frame[:length] -= frame[:padding]
365
365
  frame[:flags].delete(:padded)
366
366
  end
@@ -374,7 +374,9 @@ module HTTP2Next
374
374
  e_sd = payload.read_uint32
375
375
  frame[:dependency] = e_sd & RBIT
376
376
  frame[:exclusive] = (e_sd & EBIT) != 0
377
- frame[:weight] = payload.getbyte + 1
377
+ weight = payload.byteslice(0, 1).ord + 1
378
+ frame[:weight] = weight
379
+ payload = payload.byteslice(1..-1)
378
380
  end
379
381
  frame[:payload] = payload.read(frame[:length])
380
382
  when :priority
@@ -383,7 +385,9 @@ module HTTP2Next
383
385
  e_sd = payload.read_uint32
384
386
  frame[:dependency] = e_sd & RBIT
385
387
  frame[:exclusive] = (e_sd & EBIT) != 0
386
- frame[:weight] = payload.getbyte + 1
388
+ weight = payload.byteslice(0, 1).ord + 1
389
+ frame[:weight] = weight
390
+ payload = payload.byteslice(1..-1)
387
391
  when :rst_stream
388
392
  raise FrameSizeError, "Invalid length for RST_STREAM (#{frame[:length]} != 4)" if frame[:length] != 4
389
393
 
@@ -428,10 +432,12 @@ module HTTP2Next
428
432
  when :altsvc
429
433
  frame[:max_age], frame[:port] = payload.read(6).unpack(UINT32 + UINT16)
430
434
 
431
- len = payload.getbyte
435
+ len = payload.byteslice(0, 1).ord
436
+ payload = payload.byteslice(1..-1)
432
437
  frame[:proto] = payload.read(len) if len > 0
433
438
 
434
- len = payload.getbyte
439
+ len = payload.byteslice(0, 1).ord
440
+ payload = payload.byteslice(1..-1)
435
441
  frame[:host] = payload.read(len) if len > 0
436
442
 
437
443
  frame[:origin] = payload.read(payload.size) unless payload.empty?
@@ -91,7 +91,7 @@ module HTTP2Next
91
91
  # @param h [Hash] header command
92
92
  # @param buffer [String]
93
93
  # @return [Buffer]
94
- def header(h, buffer = Buffer.new)
94
+ def header(h, buffer = "".b)
95
95
  rep = HEADREP[h[:type]]
96
96
 
97
97
  case h[:type]
@@ -122,7 +122,7 @@ module HTTP2Next
122
122
  # @param headers [Array] +[[name, value], ...]+
123
123
  # @return [Buffer]
124
124
  def encode(headers)
125
- buffer = Buffer.new
125
+ buffer = "".b
126
126
  pseudo_headers, regular_headers = headers.partition { |f, _| f.start_with? ":" }
127
127
  headers = [*pseudo_headers, *regular_headers]
128
128
  commands = @cc.encode(headers)
@@ -2,6 +2,7 @@
2
2
 
3
3
  module HTTP2Next
4
4
  module Header
5
+ using StringExtensions
5
6
  # Responsible for decoding received headers and maintaining compression
6
7
  # context of the opposing peer. Decompressor must be initialized with
7
8
  # appropriate starting context based on local role: client or server.
@@ -30,11 +31,11 @@ module HTTP2Next
30
31
  # @return [Integer]
31
32
  def integer(buf, n)
32
33
  limit = 2**n - 1
33
- i = !n.zero? ? (buf.getbyte & limit) : 0
34
+ i = !n.zero? ? (buf.shift_byte & limit) : 0
34
35
 
35
36
  m = 0
36
37
  if i == limit
37
- while (byte = buf.getbyte)
38
+ while (byte = buf.shift_byte)
38
39
  i += ((byte & 127) << m)
39
40
  m += 7
40
41
 
@@ -53,12 +54,12 @@ module HTTP2Next
53
54
  def string(buf)
54
55
  raise CompressionError, "invalid header block fragment" if buf.empty?
55
56
 
56
- huffman = (buf.readbyte(0) & 0x80) == 0x80
57
+ huffman = (buf.getbyte(0) & 0x80) == 0x80
57
58
  len = integer(buf, 7)
58
59
  str = buf.read(len)
59
60
  raise CompressionError, "string too short" unless str.bytesize == len
60
61
 
61
- str = Huffman.new.decode(Buffer.new(str)) if huffman
62
+ str = Huffman.new.decode(str) if huffman
62
63
  str.force_encoding(Encoding::UTF_8)
63
64
  end
64
65
 
@@ -67,7 +68,7 @@ module HTTP2Next
67
68
  # @param buf [Buffer]
68
69
  # @return [Hash] command
69
70
  def header(buf)
70
- peek = buf.readbyte(0)
71
+ peek = buf.getbyte(0)
71
72
 
72
73
  header = {}
73
74
  header[:type], type = HEADREP.find do |_t, desc|
@@ -79,7 +79,8 @@ module HTTP2Next
79
79
  receive(CONNECTION_PREFACE_MAGIC)
80
80
 
81
81
  # Process received HTTP2-Settings payload
82
- buf = HTTP2Next::Buffer.new Base64.urlsafe_decode64(settings.to_s)
82
+ buf = "".b
83
+ buf << Base64.urlsafe_decode64(settings.to_s)
83
84
  header = @framer.common_header(
84
85
  length: buf.bytesize,
85
86
  type: :settings,
@@ -163,7 +163,7 @@ module HTTP2Next
163
163
  return unless @_trailers
164
164
 
165
165
  trailers = frame[:payload]
166
- return if trailers.is_a?(Buffer)
166
+ return unless trailers.respond_to?(:each)
167
167
 
168
168
  trailers.each do |field, _|
169
169
  @_trailers.delete(field)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP2Next
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/sig/connection.rbs CHANGED
@@ -48,7 +48,7 @@ module HTTP2Next
48
48
 
49
49
  def send: (frame) -> void
50
50
 
51
- def encode: (frame) -> Array[Buffer]
51
+ def encode: (frame) -> Array[String]
52
52
 
53
53
  def connection_frame?: (frame) -> bool
54
54
 
data/sig/emitter.rbs CHANGED
@@ -1,10 +1,10 @@
1
1
  module HTTP2Next
2
2
  module Emitter
3
- # def on: (Symbol event) { (*untyped) -> void } -> void
3
+ def on: (Symbol event) { (*untyped) -> void } -> void
4
4
 
5
- # def once: (Symbol event) { (*untyped) -> void } -> void
5
+ def once: (Symbol event) { (*untyped) -> void } -> void
6
6
 
7
- # def emit: (Symbol event, *untyped args) ?{ (*untyped) -> void } -> void
7
+ def emit: (Symbol event, *untyped args) ?{ (*untyped) -> void } -> void
8
8
 
9
9
  private
10
10
 
data/sig/framer.rbs CHANGED
@@ -6,11 +6,11 @@ module HTTP2Next
6
6
 
7
7
  def common_header: (frame) -> String
8
8
 
9
- def read_common_frame: (Buffer) -> frame
9
+ def read_common_frame: (String) -> frame
10
10
 
11
- def generate: (frame) -> Buffer
11
+ def generate: (frame) -> String
12
12
 
13
- def parse: (Buffer) -> frame?
13
+ def parse: (String) -> frame?
14
14
 
15
15
  private
16
16
 
@@ -9,10 +9,10 @@ module HTTP2Next
9
9
 
10
10
  def string: (String) -> String
11
11
 
12
- def header: (header_command, Buffer) -> Buffer
13
- | (header_command) -> Buffer
12
+ def header: (header_command, String) -> String
13
+ | (header_command) -> String
14
14
 
15
- def encode: (Enumerable[header_pair]) -> Buffer
15
+ def encode: (Enumerable[header_pair]) -> String
16
16
 
17
17
  private
18
18
 
@@ -5,14 +5,14 @@ module HTTP2Next
5
5
 
6
6
  def table_size=: (Integer) -> void
7
7
 
8
- def integer: (Buffer, Integer) -> Integer
8
+ def integer: (String, Integer) -> Integer
9
9
 
10
- def string: (Buffer) -> String
10
+ def string: (String) -> String
11
11
 
12
- def header: (Buffer) -> header_command
12
+ def header: (String) -> header_command
13
13
 
14
- def decode: (Buffer, frame?) -> Array[header_pair]
15
- | (Buffer) -> Array[header_pair]
14
+ def decode: (String, frame?) -> Array[header_pair]
15
+ | (String) -> Array[header_pair]
16
16
  private
17
17
 
18
18
  def initialize: (context_hash options) -> untyped
@@ -3,7 +3,7 @@ module HTTP2Next
3
3
  class Huffman
4
4
  def encode: (String str) -> String
5
5
 
6
- def decode: (Buffer str) -> String
6
+ def decode: (String str) -> String
7
7
  end
8
8
  end
9
9
  end
data/sig/next.rbs CHANGED
@@ -23,6 +23,46 @@ module HTTP2Next
23
23
 
24
24
  type header_pair = [String, String]
25
25
 
26
+ # # FRAMES
27
+ # type frame_control_flags = Array[:end_headers | :end_stream]
28
+
29
+ # # HEADERS
30
+ # type headers_frame = {
31
+ # type: :headers, flags: frame_control_flags, stream: Integer, payload: Enumerable[header_pair],
32
+ # ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, ?padding: Integer
33
+ # }
34
+
35
+ # # DATA
36
+ # type data_frame = { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String, ?padding: Integer }
37
+
38
+ # # PUSH_PROMISE
39
+ # type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, stream: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
40
+
41
+ # # SETTINGS
42
+ # type settings_frame = { type: :settings, stream: 0, payload: Array[[Symbol | Integer, Integer]] }
43
+
44
+ # # WINDOW_UPDATE
45
+ # type window_update_frame = { type: :window_update, stream: Integer, increment: Integer }
46
+
47
+ # # PRIORITY
48
+ # type priority_frame = { type: :priority, stream: Integer, dependency: Integer, exclusive: bool, weight: Integer }
49
+
50
+ # # ALTSVC
51
+ # type altsvc_frame = { type: :altsvc, stream: 0, max_age: Integer, port: Integer, proto: "String", host: String }
52
+
53
+ # # ORIGIN
54
+ # type origin_frame = { type: :origin, stream: 0, origin: Array[String] }
55
+
56
+ # # PING
57
+ # type ping_frame = { type: :ping, payload: String, length: Integer }
58
+
59
+ # # GOAWAY
60
+ # type goaway_frame = { type: :goaway, stream: 0, last_stream: Integer, error: Symbol? }
61
+
62
+ # type frame = headers_frame | data_frame | push_promise_frame |
63
+ # settings_frame | window_update_frame | priority_frame | altsvc_frame |
64
+ # origin_frame | ping_frame | goaway_frame
65
+
26
66
  type frame_key = :type | :flags | :stream | :padding | :ignore |
27
67
  # headers
28
68
  :method | :trailer | :content_length |
@@ -44,10 +84,9 @@ module HTTP2Next
44
84
  type frame_value = Integer |
45
85
  Symbol | # type (:data, :headers)
46
86
  Array[Symbol] |
47
- String | Buffer |
87
+ String |
48
88
  bool |
49
89
  Array[String] |
50
- Array[Buffer] |
51
90
  Array[[Symbol | Integer, Integer]] |
52
91
  Enumerable[header_pair] |
53
92
  nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-2-next
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-12-09 00:00:00.000000000 Z
13
+ date: 2021-02-21 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Pure-ruby HTTP 2.0 protocol implementation
16
16
  email:
@@ -21,7 +21,6 @@ extra_rdoc_files: []
21
21
  files:
22
22
  - README.md
23
23
  - lib/http/2/next.rb
24
- - lib/http/2/next/buffer.rb
25
24
  - lib/http/2/next/client.rb
26
25
  - lib/http/2/next/connection.rb
27
26
  - lib/http/2/next/emitter.rb
@@ -39,7 +38,6 @@ files:
39
38
  - lib/http/2/next/stream.rb
40
39
  - lib/http/2/next/version.rb
41
40
  - lib/tasks/generate_huffman_table.rb
42
- - sig/buffer.rbs
43
41
  - sig/client.rbs
44
42
  - sig/connection.rbs
45
43
  - sig/emitter.rbs
@@ -73,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
71
  - !ruby/object:Gem::Version
74
72
  version: '0'
75
73
  requirements: []
76
- rubygems_version: 3.1.4
74
+ rubygems_version: 3.2.3
77
75
  signing_key:
78
76
  specification_version: 4
79
77
  summary: Pure-ruby HTTP 2.0 protocol implementation
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "forwardable"
4
-
5
- module HTTP2Next
6
- # Binary buffer wraps String.
7
- #
8
- class Buffer
9
- extend Forwardable
10
-
11
- using StringExtensions
12
-
13
- def_delegators :@buffer, :ord, :encoding, :setbyte, :unpack,
14
- :size, :each_byte, :to_str, :to_s, :length, :inspect,
15
- :[], :[]=, :empty?, :bytesize, :include?
16
-
17
- UINT32 = "N"
18
- private_constant :UINT32
19
-
20
- # Forces binary encoding on the string
21
- def initialize(str = "".b)
22
- str = str.dup if str.frozen?
23
- @buffer = str.force_encoding(Encoding::BINARY)
24
- end
25
-
26
- # Emulate StringIO#read: slice first n bytes from the buffer.
27
- #
28
- # @param n [Integer] number of bytes to slice from the buffer
29
- def read(n)
30
- Buffer.new(@buffer.slice!(0, n))
31
- end
32
-
33
- def unpack1(*arg)
34
- @buffer.unpack1(*arg)
35
- end
36
-
37
- # Emulate StringIO#getbyte: slice first byte from buffer.
38
- def getbyte
39
- read(1).ord
40
- end
41
-
42
- def slice!(*args)
43
- Buffer.new(@buffer.slice!(*args))
44
- end
45
-
46
- def slice(*args)
47
- Buffer.new(@buffer.slice(*args))
48
- end
49
-
50
- def force_encoding(*args)
51
- @buffer = @buffer.force_encoding(*args)
52
- end
53
-
54
- def ==(other)
55
- @buffer == other
56
- end
57
-
58
- def +(other)
59
- @buffer += other
60
- end
61
-
62
- # Emulate String#getbyte: return nth byte from buffer.
63
- def readbyte(n)
64
- @buffer[n].ord
65
- end
66
-
67
- # Slice unsigned 32-bit integer from buffer.
68
- # @return [Integer]
69
- def read_uint32
70
- read(4).unpack1(UINT32)
71
- end
72
-
73
- # Ensures that data that is added is binary encoded as well,
74
- # otherwise this could lead to the Buffer instance changing its encoding.
75
- %i[<< prepend].each do |mutating_method|
76
- class_eval(<<-METH, __FILE__, __LINE__ + 1)
77
- def #{mutating_method}(string)
78
- string = string.dup if string.frozen?
79
- @buffer.send __method__, string.force_encoding(Encoding::BINARY)
80
-
81
- self
82
- end
83
- METH
84
- end
85
- end
86
- end
data/sig/buffer.rbs DELETED
@@ -1,21 +0,0 @@
1
- module HTTP2Next
2
- class Buffer
3
-
4
- def read: (Integer) -> Buffer
5
-
6
- def getbyte: () -> Integer
7
-
8
- def readbyte: (Integer) -> Integer
9
-
10
- def read_uint32: () -> Integer
11
-
12
- def <<: (string) -> void
13
-
14
- def prepend: (string) -> void
15
-
16
- private
17
-
18
- def initialize: () -> untyped
19
- | (string) -> untyped
20
- end
21
- end