protocol-http2 0.19.1 → 0.19.3
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 +6 -8
- data/lib/protocol/http2/flow_controlled.rb +0 -4
- data/lib/protocol/http2/stream.rb +2 -2
- data/lib/protocol/http2/version.rb +1 -1
- data/lib/protocol/http2/window.rb +117 -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: 1fc681846886564561e01287c0c8ac5db0944222c6f94262894fe50ac1d0d2a5
|
4
|
+
data.tar.gz: 94106491f20c0b6f08fc637ecd46ccab6a38362207f90ddfefb12b02ba901aad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bb39e01cf605b16625a81ba6706b37ec9022c220e3200cea4e8136091842532f9a00b47c76980a36e726401f35eaf22522211e2c567322099512f6a1c472278
|
7
|
+
data.tar.gz: e2ca6677a9b488a0ec7d4e74ecf1bfb349e496d2e248c60928c27286cfa99c3a5e07a6edf2b957d797c6f374e2e23b2f2ac362b0458594064acf5d9de856c872
|
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,18 @@ 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
|
221
218
|
end
|
219
|
+
|
220
|
+
@framer.flush
|
222
221
|
end
|
223
222
|
|
224
223
|
def write_frames
|
225
224
|
if @framer
|
226
225
|
synchronize do
|
227
226
|
yield @framer
|
228
|
-
|
229
|
-
# See note above.
|
230
|
-
@framer.flush
|
231
227
|
end
|
228
|
+
|
229
|
+
@framer.flush
|
232
230
|
else
|
233
231
|
raise EOFError, "Connection closed!"
|
234
232
|
end
|
@@ -476,7 +474,7 @@ module Protocol
|
|
476
474
|
# Return if there is no window to consume:
|
477
475
|
return unless size > 0
|
478
476
|
|
479
|
-
# Console.
|
477
|
+
# Console.info(self) do |buffer|
|
480
478
|
# @dependencies.each do |id, dependency|
|
481
479
|
# buffer.puts "- #{dependency}"
|
482
480
|
# 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.
|
@@ -275,7 +275,7 @@ module Protocol
|
|
275
275
|
end
|
276
276
|
|
277
277
|
protected def ignore_headers(frame)
|
278
|
-
#
|
278
|
+
# Console.warn(self) {"Received headers in state: #{@state}!"}
|
279
279
|
end
|
280
280
|
|
281
281
|
def receive_headers(frame)
|
@@ -316,7 +316,7 @@ module Protocol
|
|
316
316
|
end
|
317
317
|
|
318
318
|
def ignore_data(frame)
|
319
|
-
#
|
319
|
+
# Console.warn(self) {"Received headers in state: #{@state}!"}
|
320
320
|
end
|
321
321
|
|
322
322
|
# DATA frames are subject to flow control and can only be sent when a stream is in the "open" or "half-closed (remote)" state. The entire DATA frame payload is included in flow control, including the Pad Length and Padding fields if present. If a DATA frame is received whose stream is not in "open" or "half-closed (local)" state, the recipient MUST respond with a stream error of type STREAM_CLOSED.
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 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} available=#{@available} used=#{@used} capacity=#{@capacity}#{limited? ? " limited" : nil}>"
|
76
|
+
end
|
77
|
+
|
78
|
+
alias to_s inspect
|
79
|
+
end
|
80
|
+
|
81
|
+
# This is a window which efficiently maintains a desired capacity.
|
82
|
+
class LocalWindow < Window
|
83
|
+
def initialize(capacity = DEFAULT_CAPACITY, desired: nil)
|
84
|
+
super(capacity)
|
85
|
+
|
86
|
+
# The desired capacity of the window, may be bigger than the initial capacity.
|
87
|
+
# If that is the case, we will likely send a window update to the remote end to increase the capacity.
|
88
|
+
@desired = desired
|
89
|
+
end
|
90
|
+
|
91
|
+
# The desired capacity of the window.
|
92
|
+
attr_accessor :desired
|
93
|
+
|
94
|
+
def wanted
|
95
|
+
if @desired
|
96
|
+
# We must send an update which allows at least @desired bytes to be sent.
|
97
|
+
(@desired - @capacity) + @used
|
98
|
+
else
|
99
|
+
super
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def limited?
|
104
|
+
if @desired
|
105
|
+
# Do not send window updates until we are less than half the desired capacity:
|
106
|
+
@available < (@desired / 2)
|
107
|
+
else
|
108
|
+
super
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def inspect
|
113
|
+
"\#<#{self.class} available=#{@available} used=#{@used} capacity=#{@capacity} desired=#{@desired} #{limited? ? "limited" : nil}>"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
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.3
|
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-
|
43
|
+
date: 2024-10-02 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
|