http-2 0.10.0 → 0.10.1
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/client.rb +5 -0
- data/lib/http/2/compressor.rb +4 -2
- data/lib/http/2/connection.rb +17 -2
- data/lib/http/2/stream.rb +9 -1
- data/lib/http/2/version.rb +1 -1
- data/spec/client_spec.rb +62 -0
- data/spec/compressor_spec.rb +16 -0
- data/spec/connection_spec.rb +9 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f52820ad290d538c293b8d008baa622bc788c07c
|
4
|
+
data.tar.gz: 93aa6df1ade7720059e84c8ffd69d1fb2385028d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8fb28dd5124a1dc9995f250ca82a0a257d5a1c2a4b802fadcf0d7fe30a054c1e1e312fa81f6bb69888103783d23916c3bdb464c5eb5819e2ef68609ddeae303
|
7
|
+
data.tar.gz: 82f8859ce4752d46be361deb76e1b37b076472b0b07262ca5aa9d7b2daa2c50d6d28b44aa8811031b58a294424c1e8fc056f22ffd9c92301a48b2369503784ae
|
data/lib/http/2/client.rb
CHANGED
data/lib/http/2/compressor.rb
CHANGED
@@ -139,7 +139,8 @@ module HTTP2
|
|
139
139
|
# - http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-10#section-4.1
|
140
140
|
#
|
141
141
|
# @param cmd [Hash] { type:, name:, value:, index: }
|
142
|
-
# @return [Array] +[name, value]+ header field that is added to the decoded header list
|
142
|
+
# @return [Array, nil] +[name, value]+ header field that is added to the decoded header list,
|
143
|
+
# or nil if +cmd[:type]+ is +:changetablesize+
|
143
144
|
def process(cmd)
|
144
145
|
emit = nil
|
145
146
|
|
@@ -553,6 +554,7 @@ module HTTP2
|
|
553
554
|
decoding_pseudo_headers = true
|
554
555
|
until buf.empty?
|
555
556
|
next_header = @cc.process(header(buf))
|
557
|
+
next if next_header.nil?
|
556
558
|
is_pseudo_header = next_header.first.start_with? ':'
|
557
559
|
if !decoding_pseudo_headers && is_pseudo_header
|
558
560
|
fail ProtocolError, 'one or more pseudo headers encountered after regular headers'
|
@@ -560,7 +562,7 @@ module HTTP2
|
|
560
562
|
decoding_pseudo_headers = is_pseudo_header
|
561
563
|
list << next_header
|
562
564
|
end
|
563
|
-
list
|
565
|
+
list
|
564
566
|
end
|
565
567
|
end
|
566
568
|
end
|
data/lib/http/2/connection.rb
CHANGED
@@ -94,6 +94,7 @@ module HTTP2
|
|
94
94
|
@error = nil
|
95
95
|
|
96
96
|
@h2c_upgrade = nil
|
97
|
+
@closed_since = nil
|
97
98
|
end
|
98
99
|
|
99
100
|
def closed?
|
@@ -144,6 +145,7 @@ module HTTP2
|
|
144
145
|
send(type: :goaway, last_stream: last_stream,
|
145
146
|
error: error, payload: payload)
|
146
147
|
@state = :closed
|
148
|
+
@closed_since = Time.now
|
147
149
|
end
|
148
150
|
|
149
151
|
# Sends a WINDOW_UPDATE frame to the peer.
|
@@ -358,7 +360,10 @@ module HTTP2
|
|
358
360
|
raise if e.is_a?(Error::Error)
|
359
361
|
connection_error(e: e)
|
360
362
|
end
|
361
|
-
|
363
|
+
|
364
|
+
def <<(*args)
|
365
|
+
receive(*args)
|
366
|
+
end
|
362
367
|
|
363
368
|
private
|
364
369
|
|
@@ -446,12 +451,22 @@ module HTTP2
|
|
446
451
|
# the connection, although a new connection can be established
|
447
452
|
# for new streams.
|
448
453
|
@state = :closed
|
454
|
+
@closed_since = Time.now
|
449
455
|
emit(:goaway, frame[:last_stream], frame[:error], frame[:payload])
|
450
|
-
when :altsvc
|
456
|
+
when :altsvc
|
457
|
+
# 4. The ALTSVC HTTP/2 Frame
|
458
|
+
# An ALTSVC frame on stream 0 with empty (length 0) "Origin"
|
459
|
+
# information is invalid and MUST be ignored.
|
460
|
+
if frame[:origin] && !frame[:origin].empty?
|
461
|
+
emit(frame[:type], frame)
|
462
|
+
end
|
463
|
+
when :blocked
|
451
464
|
emit(frame[:type], frame)
|
452
465
|
else
|
453
466
|
connection_error
|
454
467
|
end
|
468
|
+
when :closed
|
469
|
+
connection_error if (Time.now - @closed_since) > 15
|
455
470
|
else
|
456
471
|
connection_error
|
457
472
|
end
|
data/lib/http/2/stream.rb
CHANGED
@@ -115,7 +115,15 @@ module HTTP2
|
|
115
115
|
process_priority(frame)
|
116
116
|
when :window_update
|
117
117
|
process_window_update(frame)
|
118
|
-
when :altsvc
|
118
|
+
when :altsvc
|
119
|
+
# 4. The ALTSVC HTTP/2 Frame
|
120
|
+
# An ALTSVC frame on a
|
121
|
+
# stream other than stream 0 containing non-empty "Origin" information
|
122
|
+
# is invalid and MUST be ignored.
|
123
|
+
if !frame[:origin] || frame[:origin].empty?
|
124
|
+
emit(frame[:type], frame)
|
125
|
+
end
|
126
|
+
when :blocked
|
119
127
|
emit(frame[:type], frame)
|
120
128
|
end
|
121
129
|
|
data/lib/http/2/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -32,6 +32,18 @@ RSpec.describe HTTP2::Client do
|
|
32
32
|
expect(frame[:type]).to eq :settings
|
33
33
|
expect(frame[:payload]).to include([:settings_max_concurrent_streams, 200])
|
34
34
|
end
|
35
|
+
|
36
|
+
it 'should initialize client when receiving server settings before sending ack' do
|
37
|
+
frames = []
|
38
|
+
@client.on(:frame) { |bytes| frames << bytes }
|
39
|
+
@client << f.generate(SETTINGS.dup)
|
40
|
+
|
41
|
+
expect(frames[0]).to eq CONNECTION_PREFACE_MAGIC
|
42
|
+
expect(f.parse(frames[1])[:type]).to eq :settings
|
43
|
+
ack_frame = f.parse(frames[2])
|
44
|
+
expect(ack_frame[:type]).to eq :settings
|
45
|
+
expect(ack_frame[:flags]).to include(:ack)
|
46
|
+
end
|
35
47
|
end
|
36
48
|
|
37
49
|
context 'upgrade' do
|
@@ -122,4 +134,54 @@ RSpec.describe HTTP2::Client do
|
|
122
134
|
@client << set_stream_id(f.generate(PUSH_PROMISE.dup), s.id)
|
123
135
|
end
|
124
136
|
end
|
137
|
+
|
138
|
+
context 'alt-svc' do
|
139
|
+
context 'received in the connection' do
|
140
|
+
it 'should emit :altsvc when receiving one' do
|
141
|
+
@client << f.generate(SETTINGS.dup)
|
142
|
+
frame = nil
|
143
|
+
@client.on(:altsvc) do |f|
|
144
|
+
frame = f
|
145
|
+
end
|
146
|
+
@client << f.generate(ALTSVC.deep_dup)
|
147
|
+
expect(frame).to be_a(Hash)
|
148
|
+
end
|
149
|
+
it 'should not emit :altsvc when the frame when contains no host' do
|
150
|
+
@client << f.generate(SETTINGS.dup)
|
151
|
+
frame = nil
|
152
|
+
@client.on(:altsvc) do |f|
|
153
|
+
frame = f
|
154
|
+
end
|
155
|
+
|
156
|
+
@client << f.generate(ALTSVC.deep_dup.merge(origin: nil))
|
157
|
+
expect(frame).to be_nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
context 'received in a stream' do
|
161
|
+
it 'should emit :altsvc' do
|
162
|
+
s = @client.new_stream
|
163
|
+
s.send HEADERS.deep_dup
|
164
|
+
s.close
|
165
|
+
|
166
|
+
frame = nil
|
167
|
+
s.on(:altsvc) { |f| frame = f }
|
168
|
+
|
169
|
+
@client << set_stream_id(f.generate(ALTSVC.deep_dup.merge(origin: nil)), s.id)
|
170
|
+
|
171
|
+
expect(frame).to be_a(Hash)
|
172
|
+
end
|
173
|
+
it 'should not emit :alt_svc when the frame when contains a origin' do
|
174
|
+
s = @client.new_stream
|
175
|
+
s.send HEADERS.deep_dup
|
176
|
+
s.close
|
177
|
+
|
178
|
+
frame = nil
|
179
|
+
s.on(:altsvc) { |f| frame = f }
|
180
|
+
|
181
|
+
@client << set_stream_id(f.generate(ALTSVC.deep_dup), s.id)
|
182
|
+
|
183
|
+
expect(frame).to be_nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
125
187
|
end
|
data/spec/compressor_spec.rb
CHANGED
@@ -546,6 +546,22 @@ RSpec.describe HTTP2::Header do
|
|
546
546
|
},
|
547
547
|
],
|
548
548
|
},
|
549
|
+
{ title: 'D.6.a. Response Examples with Huffman - dynamic table size updates should not trigger exceptions',
|
550
|
+
type: :response,
|
551
|
+
table_size: 4096,
|
552
|
+
huffman: :always,
|
553
|
+
bypass_encoder: true,
|
554
|
+
streams: [
|
555
|
+
{ wire: '2088 7689 aa63 55e5 80ae 16d7 17',
|
556
|
+
emitted: [
|
557
|
+
[':status', '200'],
|
558
|
+
['server', 'nginx/1.15.2'],
|
559
|
+
],
|
560
|
+
table: [],
|
561
|
+
table_size: 0,
|
562
|
+
},
|
563
|
+
],
|
564
|
+
},
|
549
565
|
]
|
550
566
|
|
551
567
|
context 'decode' do
|
data/spec/connection_spec.rb
CHANGED
@@ -10,7 +10,6 @@ RSpec.describe HTTP2::Connection do
|
|
10
10
|
context 'initialization and settings' do
|
11
11
|
(FRAME_TYPES - [SETTINGS]).each do |frame|
|
12
12
|
it "should raise error if first frame is #{frame[:type]}" do
|
13
|
-
frame = set_stream_id(f.generate(frame.deep_dup), 0x0)
|
14
13
|
expect { @conn << frame }.to raise_error(ProtocolError)
|
15
14
|
expect(@conn).to be_closed
|
16
15
|
end
|
@@ -542,6 +541,15 @@ RSpec.describe HTTP2::Connection do
|
|
542
541
|
expect { @conn.new_stream }.to raise_error(ConnectionClosed)
|
543
542
|
end
|
544
543
|
|
544
|
+
it 'should not raise error when receiving connection management frames immediately after emitting goaway' do
|
545
|
+
@conn.goaway
|
546
|
+
expect(@conn).to be_closed
|
547
|
+
|
548
|
+
expect { @conn << f.generate(SETTINGS.dup) }.not_to raise_error(ProtocolError)
|
549
|
+
expect { @conn << f.generate(PING.dup) }.not_to raise_error(ProtocolError)
|
550
|
+
expect { @conn << f.generate(GOAWAY.dup) }.not_to raise_error(ProtocolError)
|
551
|
+
end
|
552
|
+
|
545
553
|
it 'should process connection management frames after GOAWAY' do
|
546
554
|
@conn << f.generate(SETTINGS.dup)
|
547
555
|
@conn << f.generate(HEADERS.dup)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Grigorik
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|