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 +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
|