http-2 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a5b4286258966b81acdfc845ae3dda4380c4f64
4
- data.tar.gz: 7f61a80280bc7b85f220a6e6661d594d588f0969
3
+ metadata.gz: f52820ad290d538c293b8d008baa622bc788c07c
4
+ data.tar.gz: 93aa6df1ade7720059e84c8ffd69d1fb2385028d
5
5
  SHA512:
6
- metadata.gz: 90e4326062ff7d6ee5161ffe0509a99ac46f36c5aebe906b8ec6e044018d36fab1a8e17cf549a30272a5c6a1d7603362eb2fac42edbcc5a666f9b336cdf4bdc4
7
- data.tar.gz: fc4ed18e276fbd8d27dbf090999f989d91450bd8a2dd59d9a1e77bdaa482e74217a4f7ecb0bf9033af99c40df29858d88c849a7cba36e19363c43718cc026aa4
6
+ metadata.gz: d8fb28dd5124a1dc9995f250ca82a0a257d5a1c2a4b802fadcf0d7fe30a054c1e1e312fa81f6bb69888103783d23916c3bdb464c5eb5819e2ef68609ddeae303
7
+ data.tar.gz: 82f8859ce4752d46be361deb76e1b37b076472b0b07262ca5aa9d7b2daa2c50d6d28b44aa8811031b58a294424c1e8fc056f22ffd9c92301a48b2369503784ae
@@ -38,6 +38,11 @@ module HTTP2
38
38
  super(frame)
39
39
  end
40
40
 
41
+ def receive(frame)
42
+ send_connection_preface
43
+ super(frame)
44
+ end
45
+
41
46
  # sends the preface and initializes the first stream in half-closed state
42
47
  def upgrade
43
48
  fail ProtocolError unless @stream_id == 1
@@ -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.compact
565
+ list
564
566
  end
565
567
  end
566
568
  end
@@ -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
- alias << receive
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, :blocked
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
@@ -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, :blocked
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
 
@@ -1,3 +1,3 @@
1
1
  module HTTP2
2
- VERSION = '0.10.0'.freeze
2
+ VERSION = '0.10.1'.freeze
3
3
  end
@@ -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
@@ -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
@@ -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.0
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-07-25 00:00:00.000000000 Z
12
+ date: 2018-11-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler