protocol-http2 0.19.0 → 0.19.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/protocol/http2/connection.rb +7 -7
- data/lib/protocol/http2/flow_controlled.rb +0 -4
- data/lib/protocol/http2/version.rb +1 -1
- data/lib/protocol/http2/window.rb +115 -0
- data/lib/protocol/http2/window_update_frame.rb +1 -96
- data.tar.gz.sig +0 -0
- metadata +3 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe5de9c523fbd986f47d3961f13d58e225f165f36ed322026d72ddbe95357c46
|
4
|
+
data.tar.gz: 04d1c6d47af4784c07b61d403efb040153b57b37d88c005f50cd0a6850d6e0f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
@@ -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.
|
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-
|
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
|