http-2-next 0.2.2 → 0.2.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
- data/lib/http/2/next.rb +1 -0
- data/lib/http/2/next/buffer.rb +4 -2
- data/lib/http/2/next/compressor.rb +6 -2
- data/lib/http/2/next/connection.rb +5 -6
- data/lib/http/2/next/extensions.rb +13 -0
- data/lib/http/2/next/flow_buffer.rb +70 -33
- data/lib/http/2/next/stream.rb +0 -1
- data/lib/http/2/next/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 57b5112f768b60bc8cba8e6f82925eafc0de71a947fc5282bcc0f4b10dd42b49
|
|
4
|
+
data.tar.gz: 9e8470275022f7d9742232cb1cc2ffab1644a77268a21a656a702db219a3fb93
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a466e82b5a77065453b531602daf30fc5c44bb4918e46f3bc0b48e80268b5496ae23b2bc3ee6f40c8fcf6920dc5ea1a0490c861ace6776f2f522aba090c0309f
|
|
7
|
+
data.tar.gz: b469ea645f4a74fbf5e045a6205ecccf3104d93f190c93cdcfc2faf1f0046623596af728278d3839cddcba235fb1382a830899b5d1f0d7f1ba89734e1cdafc29
|
data/lib/http/2/next.rb
CHANGED
data/lib/http/2/next/buffer.rb
CHANGED
|
@@ -67,12 +67,14 @@ module HTTP2Next
|
|
|
67
67
|
# Ensures that data that is added is binary encoded as well,
|
|
68
68
|
# otherwise this could lead to the Buffer instance changing its encoding.
|
|
69
69
|
%i[<< prepend].each do |mutating_method|
|
|
70
|
-
|
|
70
|
+
class_eval(<<-METH, __FILE__, __LINE__ + 1)
|
|
71
|
+
def #{mutating_method}(string)
|
|
71
72
|
string = string.dup if string.frozen?
|
|
72
|
-
@buffer.send
|
|
73
|
+
@buffer.send __method__, string.force_encoding(Encoding::BINARY)
|
|
73
74
|
|
|
74
75
|
self
|
|
75
76
|
end
|
|
77
|
+
METH
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
end
|
|
@@ -12,6 +12,10 @@ module HTTP2Next
|
|
|
12
12
|
class EncodingContext
|
|
13
13
|
include Error
|
|
14
14
|
|
|
15
|
+
using Extensions
|
|
16
|
+
|
|
17
|
+
UPPER = /[[:upper:]]/.freeze
|
|
18
|
+
|
|
15
19
|
# @private
|
|
16
20
|
# Static table
|
|
17
21
|
# - http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-10#appendix-A
|
|
@@ -188,7 +192,7 @@ module HTTP2Next
|
|
|
188
192
|
cmd[:index] ||= cmd[:name]
|
|
189
193
|
cmd[:value] ||= v
|
|
190
194
|
cmd[:name] = k
|
|
191
|
-
elsif cmd[:name]
|
|
195
|
+
elsif UPPER.match?(cmd[:name])
|
|
192
196
|
raise ProtocolError, "Invalid uppercase key: #{cmd[:name]}"
|
|
193
197
|
end
|
|
194
198
|
|
|
@@ -217,7 +221,7 @@ module HTTP2Next
|
|
|
217
221
|
headers.each do |field, value|
|
|
218
222
|
# Literal header names MUST be translated to lowercase before
|
|
219
223
|
# encoding and transmission.
|
|
220
|
-
field = field.downcase
|
|
224
|
+
field = field.downcase if UPPER.match?(field)
|
|
221
225
|
value = "/" if field == ":path" && value.empty?
|
|
222
226
|
cmd = addcmd(field, value)
|
|
223
227
|
cmd[:type] = :noindex if noindex && cmd[:type] == :incremental
|
|
@@ -96,7 +96,6 @@ module HTTP2Next
|
|
|
96
96
|
@remote_window = @remote_window_limit
|
|
97
97
|
|
|
98
98
|
@recv_buffer = Buffer.new
|
|
99
|
-
@send_buffer = []
|
|
100
99
|
@continuation = []
|
|
101
100
|
@error = nil
|
|
102
101
|
|
|
@@ -720,12 +719,12 @@ module HTTP2Next
|
|
|
720
719
|
# to any in-flight frames while close is registered on both sides.
|
|
721
720
|
# References to such streams will be purged whenever another stream
|
|
722
721
|
# is closed, with a minimum of 15s RTT time window.
|
|
723
|
-
@streams_recently_closed
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
@streams_recently_closed.delete stream_id
|
|
722
|
+
@streams_recently_closed.reject do |_, v|
|
|
723
|
+
to_delete = (Time.now - v) > 15
|
|
724
|
+
@streams.delete stream_id if to_delete
|
|
725
|
+
to_delete
|
|
728
726
|
end
|
|
727
|
+
@streams_recently_closed[id] = Time.now
|
|
729
728
|
end
|
|
730
729
|
|
|
731
730
|
stream.on(:promise, &method(:promise)) if is_a? Server
|
|
@@ -14,7 +14,7 @@ module HTTP2Next
|
|
|
14
14
|
#
|
|
15
15
|
# @return [Integer]
|
|
16
16
|
def buffered_amount
|
|
17
|
-
|
|
17
|
+
send_buffer.bytesize
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def flush
|
|
@@ -23,6 +23,10 @@ module HTTP2Next
|
|
|
23
23
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
|
+
def send_buffer
|
|
27
|
+
@send_buffer ||= FrameBuffer.new
|
|
28
|
+
end
|
|
29
|
+
|
|
26
30
|
def update_local_window(frame)
|
|
27
31
|
frame_size = frame[:payload].bytesize
|
|
28
32
|
frame_size += frame[:padding] || 0
|
|
@@ -63,42 +67,20 @@ module HTTP2Next
|
|
|
63
67
|
# Buffered DATA frames are emitted in FIFO order.
|
|
64
68
|
#
|
|
65
69
|
# @param frame [Hash]
|
|
66
|
-
# @param encode [Boolean] set to true by
|
|
70
|
+
# @param encode [Boolean] set to true by connection
|
|
67
71
|
def send_data(frame = nil, encode = false)
|
|
68
|
-
|
|
72
|
+
send_buffer << frame unless frame.nil?
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
while @remote_window > 0 && !@send_buffer.empty?
|
|
74
|
-
frame = @send_buffer.shift
|
|
75
|
-
|
|
76
|
-
sent = 0
|
|
77
|
-
frame_size = frame[:payload].bytesize
|
|
78
|
-
|
|
79
|
-
if frame_size > @remote_window
|
|
80
|
-
payload = frame.delete(:payload)
|
|
81
|
-
chunk = frame.dup
|
|
82
|
-
|
|
83
|
-
# Split frame so that it fits in the window
|
|
84
|
-
# TODO: consider padding!
|
|
85
|
-
frame[:payload] = payload.slice!(0, @remote_window)
|
|
86
|
-
frame[:length] = frame[:payload].bytesize
|
|
87
|
-
chunk[:length] = payload.bytesize
|
|
88
|
-
chunk[:payload] = payload
|
|
89
|
-
|
|
90
|
-
# if no longer last frame in sequence...
|
|
91
|
-
frame[:flags] -= [:end_stream] if frame[:flags].include? :end_stream
|
|
92
|
-
|
|
93
|
-
@send_buffer.unshift chunk
|
|
94
|
-
sent = @remote_window
|
|
95
|
-
else
|
|
96
|
-
sent = frame_size
|
|
97
|
-
end
|
|
74
|
+
while (frame = send_buffer.retrieve(@remote_window))
|
|
75
|
+
|
|
76
|
+
sent = frame[:payload].bytesize
|
|
98
77
|
|
|
99
78
|
manage_state(frame) do
|
|
100
|
-
|
|
101
|
-
|
|
79
|
+
if encode
|
|
80
|
+
encode(frame).each { |f| emit(:frame, f) }
|
|
81
|
+
else
|
|
82
|
+
emit(:frame, frame)
|
|
83
|
+
end
|
|
102
84
|
@remote_window -= sent
|
|
103
85
|
end
|
|
104
86
|
end
|
|
@@ -116,4 +98,59 @@ module HTTP2Next
|
|
|
116
98
|
send_data(nil, encode)
|
|
117
99
|
end
|
|
118
100
|
end
|
|
101
|
+
|
|
102
|
+
class FrameBuffer
|
|
103
|
+
attr_reader :bytesize
|
|
104
|
+
|
|
105
|
+
def initialize
|
|
106
|
+
@buffer = []
|
|
107
|
+
@bytesize = 0
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def <<(frame)
|
|
111
|
+
@buffer << frame
|
|
112
|
+
@bytesize += frame[:payload].bytesize
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def empty?
|
|
116
|
+
@bytesize == 0
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def retrieve(window_size)
|
|
120
|
+
return if @buffer.empty?
|
|
121
|
+
|
|
122
|
+
frame = @buffer.first
|
|
123
|
+
|
|
124
|
+
frame_size = frame[:payload].bytesize
|
|
125
|
+
end_stream = frame[:flags].include? :end_stream
|
|
126
|
+
|
|
127
|
+
# Frames with zero length with the END_STREAM flag set (that
|
|
128
|
+
# is, an empty DATA frame) MAY be sent if there is no available space
|
|
129
|
+
# in either flow control window.
|
|
130
|
+
return if window_size == 0 && !(frame_size == 0 && end_stream)
|
|
131
|
+
|
|
132
|
+
@buffer.shift
|
|
133
|
+
|
|
134
|
+
if frame_size > window_size
|
|
135
|
+
payload = frame.delete(:payload)
|
|
136
|
+
chunk = frame.dup
|
|
137
|
+
|
|
138
|
+
# Split frame so that it fits in the window
|
|
139
|
+
# TODO: consider padding!
|
|
140
|
+
frame[:payload] = payload.slice!(0, window_size)
|
|
141
|
+
frame[:length] = frame[:payload].bytesize
|
|
142
|
+
chunk[:length] = payload.bytesize
|
|
143
|
+
chunk[:payload] = payload
|
|
144
|
+
|
|
145
|
+
# if no longer last frame in sequence...
|
|
146
|
+
frame[:flags] -= [:end_stream] if end_stream
|
|
147
|
+
|
|
148
|
+
@buffer.unshift(chunk)
|
|
149
|
+
@bytesize -= window_size
|
|
150
|
+
else
|
|
151
|
+
@bytesize -= frame_size
|
|
152
|
+
end
|
|
153
|
+
frame
|
|
154
|
+
end
|
|
155
|
+
end
|
|
119
156
|
end
|
data/lib/http/2/next/stream.rb
CHANGED
data/lib/http/2/next/version.rb
CHANGED
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.2.
|
|
4
|
+
version: 0.2.3
|
|
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: 2020-02-
|
|
13
|
+
date: 2020-02-29 00:00:00.000000000 Z
|
|
14
14
|
dependencies: []
|
|
15
15
|
description: Pure-ruby HTTP 2.0 protocol implementation
|
|
16
16
|
email:
|
|
@@ -27,6 +27,7 @@ files:
|
|
|
27
27
|
- lib/http/2/next/connection.rb
|
|
28
28
|
- lib/http/2/next/emitter.rb
|
|
29
29
|
- lib/http/2/next/error.rb
|
|
30
|
+
- lib/http/2/next/extensions.rb
|
|
30
31
|
- lib/http/2/next/flow_buffer.rb
|
|
31
32
|
- lib/http/2/next/framer.rb
|
|
32
33
|
- lib/http/2/next/huffman.rb
|