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