http-2-next 0.5.1 → 1.0.1

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: a7c15b998344b09aee75566b64f5ef94abb9b388fdc3d2f06704e8263a586789
4
- data.tar.gz: 935a6225e964eb46b6f26e57ccf3080fd231570f3710bf6e78e3f05f589a294f
3
+ metadata.gz: 772dfd651b9130358e1de248ead9c68729e482dfdd518973a2d4b61d787d7807
4
+ data.tar.gz: 59dca4e2a1319dc7363b00e3d52ee7889354f0b0bb114fe49bfc7cd47cbcb1e4
5
5
  SHA512:
6
- metadata.gz: 5d768219d315950da7cc798981c6d081e23f2ffab97f354149ebae1398a25cf3db304bdd81429f8e3f257cb0100cc1a28374a1459cef4dc551d317d9bb1cade0
7
- data.tar.gz: 758a733387749553121d3117d9a86ae6109fc28fcbae12cce2852c9d291a30ad133c16060a5374c6c13aadc16af02996fba41a239998d32a194d0516fa75c71f
6
+ metadata.gz: fb2dce4d9d3f663929771b3141b616030de65f1004e28acee1e01a7d4aa306daba51a839fb9c2e68337d056311369bfb6f1b3bb7dae3cf755a9510839185bef8
7
+ data.tar.gz: 5c3e377005030768e6056e9cab0076a5e1165ef0aa4433c4920db2cbd29fed171867da9f4b6da5e2c7b64da340bc24f65e01397c90cc7f160ae520f563dbc132
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ if RUBY_VERSION < "3.3.0"
4
+ require "base64"
5
+ elsif !defined?(Base64)
6
+ module HTTP2Next
7
+ # require "base64" will not be a default gem after ruby 3.4.0
8
+ module Base64
9
+ module_function
10
+
11
+ def encode64(bin)
12
+ [bin].pack("m")
13
+ end
14
+
15
+ def decode64(str)
16
+ str.unpack1("m")
17
+ end
18
+
19
+ def urlsafe_encode64(bin, padding: true)
20
+ str = strict_encode64(bin)
21
+ str.chomp!("==") or str.chomp!("=") unless padding
22
+ str.tr!("+/", "-_")
23
+ str
24
+ end
25
+ end
26
+
27
+ def urlsafe_decode64(str)
28
+ if !str.end_with?("=") && str.length % 4 != 0
29
+ str = str.ljust((str.length + 3) & ~3, "=")
30
+ str.tr!("-_", "+/")
31
+ else
32
+ str = str.tr("-_", "+/")
33
+ end
34
+ strict_decode64(str)
35
+ end
36
+ end
37
+ end
@@ -71,10 +71,7 @@ module HTTP2Next
71
71
 
72
72
  # Number of active streams between client and server (reserved streams
73
73
  # are not counted towards the stream limit).
74
- attr_reader :active_stream_count
75
-
76
- # Max number of streams that can be in-transit in this connection.
77
- attr_writer :max_streams
74
+ attr_accessor :active_stream_count
78
75
 
79
76
  # Initializes new connection object.
80
77
  #
@@ -86,7 +83,6 @@ module HTTP2Next
86
83
  @decompressor = Header::Decompressor.new(settings)
87
84
 
88
85
  @active_stream_count = 0
89
- @max_streams = nil
90
86
  @last_activated_stream = 0
91
87
  @last_stream_id = 0
92
88
  @streams = {}
@@ -120,8 +116,7 @@ module HTTP2Next
120
116
  # @param parent [Stream]
121
117
  def new_stream(**args)
122
118
  raise ConnectionClosed if @state == :closed
123
-
124
- raise StreamLimitExceeded if @active_stream_count >= (@max_streams || @remote_settings[:settings_max_concurrent_streams])
119
+ raise StreamLimitExceeded if @active_stream_count >= @remote_settings[:settings_max_concurrent_streams]
125
120
 
126
121
  connection_error(:protocol_error, msg: "id is smaller than previous") if @stream_id < @last_activated_stream
127
122
 
@@ -727,14 +722,10 @@ module HTTP2Next
727
722
  def activate_stream(id:, **args)
728
723
  connection_error(msg: "Stream ID already exists") if @streams.key?(id)
729
724
 
730
- raise StreamLimitExceeded if @active_stream_count >= (@max_streams || @local_settings[:settings_max_concurrent_streams])
725
+ raise StreamLimitExceeded if @active_stream_count >= @local_settings[:settings_max_concurrent_streams]
731
726
 
732
727
  stream = Stream.new(connection: self, id: id, **args)
733
728
 
734
- # Streams that are in the "open" state, or either of the "half closed"
735
- # states count toward the maximum number of streams that an endpoint is
736
- # permitted to open.
737
- stream.once(:active) { @active_stream_count += 1 }
738
729
  stream.once(:close) do
739
730
  # Store a reference to the closed stream, such that we can respond
740
731
  # to any in-flight frames while close is registered on both sides.
@@ -3,7 +3,7 @@
3
3
  module HTTP2Next
4
4
  # Stream, connection, and compressor exceptions.
5
5
  module Error
6
- @types = {} # rubocop:disable ThreadSafety/MutableClassInstanceVariable
6
+ @types = {}
7
7
 
8
8
  class << self
9
9
  attr_reader :types
@@ -1,16 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP2Next
4
- module RegexpExtensions
5
- unless Regexp.method_defined?(:match?)
6
- refine Regexp do
7
- def match?(*args)
8
- !match(*args).nil?
9
- end
10
- end
11
- end
12
- end
13
-
14
4
  module StringExtensions
15
5
  refine String do
16
6
  def read(n)
@@ -29,12 +19,6 @@ module HTTP2Next
29
19
  def shift_byte
30
20
  read(1).ord
31
21
  end
32
-
33
- unless String.method_defined?(:unpack1)
34
- def unpack1(format)
35
- unpack(format).first
36
- end
37
- end
38
22
  end
39
23
  end
40
24
  end
@@ -8,8 +8,6 @@ module HTTP2Next
8
8
  class EncodingContext
9
9
  include Error
10
10
 
11
- using RegexpExtensions
12
-
13
11
  UPPER = /[[:upper:]]/.freeze
14
12
 
15
13
  # @private
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "base64"
4
3
  module HTTP2Next
5
4
  # HTTP 2.0 server connection class that implements appropriate header
6
5
  # compression / decompression algorithms and stream management logic.
@@ -91,6 +91,7 @@ module HTTP2Next
91
91
  @_method = @_content_length = @_status_code = nil
92
92
  @_waiting_on_trailers = false
93
93
  @received_data = false
94
+ @activated = false
94
95
 
95
96
  on(:window) { |v| @remote_window = v }
96
97
  on(:local_window) { |v| @local_window_max_size = @local_window = v }
@@ -605,7 +606,7 @@ module HTTP2Next
605
606
  case newstate
606
607
  when :open
607
608
  @state = newstate
608
- emit(:active)
609
+ activate_stream_in_conn
609
610
 
610
611
  when :reserved_local, :reserved_remote
611
612
  @state = newstate
@@ -613,7 +614,7 @@ module HTTP2Next
613
614
 
614
615
  when :half_closed_local, :half_closed_remote
615
616
  @closed = newstate
616
- emit(:active) unless @state == :open
617
+ activate_stream_in_conn unless @state == :open
617
618
  @state = :half_closing
618
619
 
619
620
  when :local_closed, :remote_closed, :local_rst, :remote_rst
@@ -624,11 +625,25 @@ module HTTP2Next
624
625
  @state
625
626
  end
626
627
 
628
+ # Streams that are in the "open" state, or either of the "half closed"
629
+ # states count toward the maximum number of streams that an endpoint is
630
+ # permitted to open.
631
+ def activate_stream_in_conn
632
+ @connection.active_stream_count += 1
633
+ @activated = true
634
+ emit(:active)
635
+ end
636
+
637
+ def close_stream_in_conn(*args)
638
+ @connection.active_stream_count -= 1 if @activated
639
+ emit(:close, *args)
640
+ end
641
+
627
642
  def complete_transition(frame)
628
643
  case @state
629
644
  when :closing
630
645
  @state = :closed
631
- emit(:close, frame[:error])
646
+ close_stream_in_conn(frame[:error])
632
647
  when :half_closing
633
648
  @state = @closed
634
649
  emit(:half_close)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTP2Next
4
- VERSION = "0.5.1"
4
+ VERSION = "1.0.1"
5
5
  end
data/lib/http/2/next.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "http/2/next/version"
4
4
  require "http/2/next/extensions"
5
+ require "http/2/next/base64"
5
6
  require "http/2/next/error"
6
7
  require "http/2/next/emitter"
7
8
  require "http/2/next/flow_buffer"
data/sig/connection.rbs CHANGED
@@ -17,9 +17,30 @@ module HTTP2Next
17
17
  attr_reader local_settings: settings_hash
18
18
  attr_reader pending_settings: settings_ary
19
19
 
20
- attr_reader active_stream_count: Integer
20
+ attr_accessor active_stream_count: Integer
21
21
 
22
- attr_writer max_streams: Integer?
22
+ @stream_id: Integer
23
+ @active_stream_count: Integer
24
+ @last_activated_stream: Integer
25
+ @last_stream_id: Integer
26
+
27
+ @streams: Hash[Integer, Stream]
28
+ @streams_recently_closed: Hash[Integer, Stream]
29
+
30
+ @framer: Framer
31
+
32
+ @local_window_limit: Integer
33
+ @remote_window_limit: Integer
34
+
35
+ @compressor: Header::Compressor
36
+ @decompressor: Header::Decompressor
37
+ @error: Symbol?
38
+
39
+ @recv_buffer: String
40
+ @continuation: Array[frame]
41
+
42
+ @closed_since: Float?
43
+ @received_frame: bool
23
44
 
24
45
  def closed?: () -> bool
25
46
 
@@ -37,9 +58,9 @@ module HTTP2Next
37
58
  def receive: (string data) -> void
38
59
  alias << receive
39
60
 
40
- private
61
+ def initialize: (?settings_hash) -> void
41
62
 
42
- def initialize: (?settings_hash) -> untyped
63
+ private
43
64
 
44
65
  def send: (frame) -> void
45
66
 
@@ -67,6 +88,6 @@ module HTTP2Next
67
88
 
68
89
  def _verify_pseudo_headers: (frame, Array[String]) -> void
69
90
 
70
- def connection_error: (?Symbol error, ?msg: String, ?e: StandardError) -> void
91
+ def connection_error: (?Symbol error, ?msg: String?, ?e: StandardError?) -> void
71
92
  end
72
93
  end
data/sig/error.rbs CHANGED
@@ -1,2 +1,35 @@
1
1
  module HTTP2Next
2
+ module Error
3
+ def self?.types: () -> Hash[Symbol, singleton(Error)]
4
+
5
+ class Error < StandardError
6
+ end
7
+
8
+ class HandshakeError < Error
9
+ end
10
+
11
+ class ProtocolError < Error
12
+ end
13
+
14
+ class CompressionError < ProtocolError
15
+ end
16
+
17
+ class FlowControlError < ProtocolError
18
+ end
19
+
20
+ class InternalError < ProtocolError
21
+ end
22
+
23
+ class StreamClosed < Error
24
+ end
25
+
26
+ class ConnectionClosed < Error
27
+ end
28
+
29
+ class StreamLimitExceeded < Error
30
+ end
31
+
32
+ class FrameSizeError < Error
33
+ end
34
+ end
2
35
  end
data/sig/stream.rbs CHANGED
@@ -12,6 +12,16 @@ module HTTP2Next
12
12
  attr_reader local_window: Integer
13
13
  attr_reader closed: Symbol?
14
14
 
15
+ @connection: Connection
16
+ @local_window_max_size: Integer
17
+ @error: bool
18
+ @_method: String?
19
+ @_content_length: Integer?
20
+ @_status_code: Integer?
21
+ @_waiting_on_trailers: bool
22
+ @received_data: bool
23
+ @activated: bool
24
+
15
25
  alias window local_window
16
26
 
17
27
  def closed?: () -> bool
@@ -61,6 +71,10 @@ module HTTP2Next
61
71
 
62
72
  def event: (Symbol newstate) -> void
63
73
 
74
+ def activate_stream_in_conn: () -> void
75
+
76
+ def close_stream_in_conn: (*untyped) -> void
77
+
64
78
  def complete_transition: (frame) -> void
65
79
 
66
80
  def process_priority: ({weight: Integer, dependency: Integer, exclusive: bool}) -> void
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.5.1
4
+ version: 1.0.1
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: 2022-11-10 00:00:00.000000000 Z
13
+ date: 2023-10-13 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Pure-ruby HTTP 2.0 protocol implementation
16
16
  email:
@@ -21,6 +21,7 @@ extra_rdoc_files: []
21
21
  files:
22
22
  - README.md
23
23
  - lib/http/2/next.rb
24
+ - lib/http/2/next/base64.rb
24
25
  - lib/http/2/next/client.rb
25
26
  - lib/http/2/next/connection.rb
26
27
  - lib/http/2/next/emitter.rb
@@ -70,14 +71,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
71
  requirements:
71
72
  - - ">="
72
73
  - !ruby/object:Gem::Version
73
- version: 2.1.0
74
+ version: 2.7.0
74
75
  required_rubygems_version: !ruby/object:Gem::Requirement
75
76
  requirements:
76
77
  - - ">="
77
78
  - !ruby/object:Gem::Version
78
79
  version: '0'
79
80
  requirements: []
80
- rubygems_version: 3.3.7
81
+ rubygems_version: 3.4.10
81
82
  signing_key:
82
83
  specification_version: 4
83
84
  summary: Pure-ruby HTTP 2.0 protocol implementation