protocol-http2 0.19.0 → 0.19.2

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: 6fa9a1478ba8829d9e4416cd5507ca611d5e502eb242b1d873d44d1d60a40850
4
- data.tar.gz: 4c560c928f9027108f5cf6b4fd135ce2a7043815cf8c4e2077fd5d20865e26be
3
+ metadata.gz: fe5de9c523fbd986f47d3961f13d58e225f165f36ed322026d72ddbe95357c46
4
+ data.tar.gz: 04d1c6d47af4784c07b61d403efb040153b57b37d88c005f50cd0a6850d6e0f9
5
5
  SHA512:
6
- metadata.gz: 95f413d65bbde12d848f7cbe342274d7e914aca16c1a60d2f3193b91e670ae0553233fe3ae1ef4699d87984c711311c7247daac0990bb44ab0f8d3aa44d4f604
7
- data.tar.gz: 5abe10dc681f35b42a123e69b4fca512d8f0e43b5741d9ab4987c336efa508e6981f2370357fa384c22bbaed8ab5d7725257dc2816823b29926de2c2e7d68d6a
6
+ metadata.gz: 0d869c91b0736f7eaaa4a57708c9ee8e060813df94d536f94de08844e68b78f7f72a1f5ecd860f1d392c7a1a49ed6a7c573084cb462f795c63c5b58357a38bc8
7
+ data.tar.gz: 1b9f8c945a2a8befaf2c07040dcd269637d304461e37732f22f1f5cafcea2bc3637f3ee32141a8d53d1be74bcaefb50a33d471a2f136e42aec2673e55518bbbf
checksums.yaml.gz.sig CHANGED
Binary file
@@ -41,7 +41,7 @@ module Protocol
41
41
  @decoder = HPACK::Context.new
42
42
  @encoder = HPACK::Context.new
43
43
 
44
- @local_window = LocalWindow.new()
44
+ @local_window = LocalWindow.new
45
45
  @remote_window = Window.new
46
46
  end
47
47
 
@@ -215,20 +215,20 @@ module Protocol
215
215
  def write_frame(frame)
216
216
  synchronize do
217
217
  @framer.write_frame(frame)
218
+
219
+ # I tried moving this outside the synchronize block but it caused a deadlock.
220
+ @framer.flush
218
221
  end
219
-
220
- # The IO is already synchronized, and we don't want additional contention.
221
- @framer.flush
222
222
  end
223
223
 
224
224
  def write_frames
225
225
  if @framer
226
226
  synchronize do
227
227
  yield @framer
228
+
229
+ # See note above.
230
+ @framer.flush
228
231
  end
229
-
230
- # See above note.
231
- @framer.flush
232
232
  else
233
233
  raise EOFError, "Connection closed!"
234
234
  end
@@ -70,15 +70,11 @@ module Protocol
70
70
  def receive_window_update(frame)
71
71
  amount = frame.unpack
72
72
 
73
- # Async.logger.info(self) {"expanding remote_window=#{@remote_window} by #{amount}"}
74
-
75
73
  if amount != 0
76
74
  @remote_window.expand(amount)
77
75
  else
78
76
  raise ProtocolError, "Invalid window size increment: #{amount}!"
79
77
  end
80
-
81
- # puts "expanded remote_window=#{@remote_window} by #{amount}"
82
78
  end
83
79
 
84
80
  # The window has been expanded by the given amount.
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Protocol
7
7
  module HTTP2
8
- VERSION = "0.19.0"
8
+ VERSION = "0.19.2"
9
9
  end
10
10
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
+
6
+ module Protocol
7
+ module HTTP2
8
+ class Window
9
+ # When an HTTP/2 connection is first established, new streams are created with an initial flow-control window size of 65,535 octets. The connection flow-control window is also 65,535 octets.
10
+ DEFAULT_CAPACITY = 0xFFFF
11
+
12
+ # @param capacity [Integer] The initial window size, typically from the settings.
13
+ def initialize(capacity = DEFAULT_CAPACITY)
14
+ # This is the main field required:
15
+ @available = capacity
16
+
17
+ # These two fields are primarily used for efficiently sending window updates:
18
+ @used = 0
19
+ @capacity = capacity
20
+ end
21
+
22
+ # The window is completely full?
23
+ def full?
24
+ @available <= 0
25
+ end
26
+
27
+ attr :used
28
+ attr :capacity
29
+
30
+ # When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of all stream flow-control windows that it maintains by the difference between the new value and the old value.
31
+ def capacity= value
32
+ difference = value - @capacity
33
+
34
+ # An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that causes any flow-control window to exceed the maximum size as a connection error of type FLOW_CONTROL_ERROR.
35
+ if (@available + difference) > MAXIMUM_ALLOWED_WINDOW_SIZE
36
+ raise FlowControlError, "Changing window size by #{difference} caused overflow: #{@available + difference} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
37
+ end
38
+
39
+ @available += difference
40
+ @capacity = value
41
+ end
42
+
43
+ def consume(amount)
44
+ @available -= amount
45
+ @used += amount
46
+ end
47
+
48
+ attr :available
49
+
50
+ def available?
51
+ @available > 0
52
+ end
53
+
54
+ def expand(amount)
55
+ available = @available + amount
56
+
57
+ if available > MAXIMUM_ALLOWED_WINDOW_SIZE
58
+ raise FlowControlError, "Expanding window by #{amount} caused overflow: #{available} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
59
+ end
60
+
61
+ # puts "expand(#{amount}) @available=#{@available}"
62
+ @available += amount
63
+ @used -= amount
64
+ end
65
+
66
+ def wanted
67
+ @used
68
+ end
69
+
70
+ def limited?
71
+ @available < (@capacity / 2)
72
+ end
73
+
74
+ def inspect
75
+ "\#<#{self.class} used=#{@used} available=#{@available} capacity=#{@capacity}>"
76
+ end
77
+ end
78
+
79
+ # This is a window which efficiently maintains a desired capacity.
80
+ class LocalWindow < Window
81
+ def initialize(capacity = DEFAULT_CAPACITY, desired: nil)
82
+ super(capacity)
83
+
84
+ # The desired capacity of the window, may be bigger than the initial capacity.
85
+ # If that is the case, we will likely send a window update to the remote end to increase the capacity.
86
+ @desired = desired
87
+ end
88
+
89
+ # The desired capacity of the window.
90
+ attr_accessor :desired
91
+
92
+ def wanted
93
+ if @desired
94
+ # We must send an update which allows at least @desired bytes to be sent.
95
+ (@desired - @capacity) + @used
96
+ else
97
+ super
98
+ end
99
+ end
100
+
101
+ def limited?
102
+ if @desired
103
+ # Do not send window updates until we are less than half the desired capacity:
104
+ @available < (@desired / 2)
105
+ else
106
+ super
107
+ end
108
+ end
109
+
110
+ def inspect
111
+ "\#<#{self.class} used=#{@used} available=#{@available} capacity=#{@capacity} desired=#{@desired}>"
112
+ end
113
+ end
114
+ end
115
+ end
@@ -4,105 +4,10 @@
4
4
  # Copyright, 2019-2024, by Samuel Williams.
5
5
 
6
6
  require_relative "frame"
7
+ require_relative "window"
7
8
 
8
9
  module Protocol
9
10
  module HTTP2
10
- class Window
11
- # @param capacity [Integer] The initial window size, typically from the settings.
12
- def initialize(capacity = 0xFFFF)
13
- # This is the main field required:
14
- @available = capacity
15
-
16
- # These two fields are primarily used for efficiently sending window updates:
17
- @used = 0
18
- @capacity = capacity
19
- end
20
-
21
- # The window is completely full?
22
- def full?
23
- @available <= 0
24
- end
25
-
26
- attr :used
27
- attr :capacity
28
-
29
- # When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of all stream flow-control windows that it maintains by the difference between the new value and the old value.
30
- def capacity= value
31
- difference = value - @capacity
32
-
33
- # An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that causes any flow-control window to exceed the maximum size as a connection error of type FLOW_CONTROL_ERROR.
34
- if (@available + difference) > MAXIMUM_ALLOWED_WINDOW_SIZE
35
- raise FlowControlError, "Changing window size by #{difference} caused overflow: #{@available + difference} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
36
- end
37
-
38
- @available += difference
39
- @capacity = value
40
- end
41
-
42
- def consume(amount)
43
- @available -= amount
44
- @used += amount
45
- end
46
-
47
- attr :available
48
-
49
- def available?
50
- @available > 0
51
- end
52
-
53
- def expand(amount)
54
- available = @available + amount
55
-
56
- if available > MAXIMUM_ALLOWED_WINDOW_SIZE
57
- raise FlowControlError, "Expanding window by #{amount} caused overflow: #{available} > #{MAXIMUM_ALLOWED_WINDOW_SIZE}!"
58
- end
59
-
60
- # puts "expand(#{amount}) @available=#{@available}"
61
- @available += amount
62
- @used -= amount
63
- end
64
-
65
- def wanted
66
- @used
67
- end
68
-
69
- def limited?
70
- @available < (@capacity / 2)
71
- end
72
-
73
- def inspect
74
- "\#<#{self.class} used=#{@used} available=#{@available} capacity=#{@capacity}>"
75
- end
76
- end
77
-
78
- # This is a window which efficiently maintains a desired capacity.
79
- class LocalWindow < Window
80
- def initialize(capacity = 0xFFFF, desired: nil)
81
- super(capacity)
82
-
83
- @desired = desired
84
- end
85
-
86
- attr_accessor :desired
87
-
88
- def wanted
89
- if @desired
90
- # We must send an update which allows at least @desired bytes to be sent.
91
- (@desired - @capacity) + @used
92
- else
93
- @used
94
- end
95
- end
96
-
97
- def limited?
98
- if @desired
99
- @available < @desired
100
- else
101
- super
102
- end
103
- end
104
- end
105
-
106
11
  # The WINDOW_UPDATE frame is used to implement flow control.
107
12
  #
108
13
  # +-+-------------------------------------------------------------+
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-http2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -40,7 +40,7 @@ cert_chain:
40
40
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
41
41
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
42
42
  -----END CERTIFICATE-----
43
- date: 2024-09-24 00:00:00.000000000 Z
43
+ date: 2024-09-28 00:00:00.000000000 Z
44
44
  dependencies:
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: protocol-hpack
@@ -97,6 +97,7 @@ files:
97
97
  - lib/protocol/http2/settings_frame.rb
98
98
  - lib/protocol/http2/stream.rb
99
99
  - lib/protocol/http2/version.rb
100
+ - lib/protocol/http2/window.rb
100
101
  - lib/protocol/http2/window_update_frame.rb
101
102
  - license.md
102
103
  - readme.md
metadata.gz.sig CHANGED
Binary file