http-2-next 0.3.0 → 0.4.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: 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