http-2 0.6.1 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.autotest +2 -1
- data/Gemfile +8 -1
- data/README.md +27 -21
- data/example/README.md +53 -0
- data/example/client.rb +88 -30
- data/example/helper.rb +5 -0
- data/example/keys/mycert.pem +24 -0
- data/example/keys/mykey.pem +27 -0
- data/example/server.rb +47 -8
- data/http-2.gemspec +0 -2
- data/lib/http/2.rb +2 -0
- data/lib/http/2/buffer.rb +21 -4
- data/lib/http/2/client.rb +50 -0
- data/lib/http/2/compressor.rb +197 -181
- data/lib/http/2/connection.rb +57 -83
- data/lib/http/2/emitter.rb +2 -2
- data/lib/http/2/error.rb +5 -0
- data/lib/http/2/framer.rb +32 -31
- data/lib/http/2/server.rb +55 -0
- data/lib/http/2/stream.rb +1 -1
- data/lib/http/2/version.rb +1 -1
- data/spec/buffer_spec.rb +23 -0
- data/spec/client_spec.rb +93 -0
- data/spec/compressor_spec.rb +89 -80
- data/spec/connection_spec.rb +24 -75
- data/spec/emitter_spec.rb +8 -0
- data/spec/framer_spec.rb +36 -40
- data/spec/helper.rb +6 -2
- data/spec/server_spec.rb +50 -0
- data/spec/stream_spec.rb +23 -30
- metadata +13 -30
data/spec/connection_spec.rb
CHANGED
@@ -2,20 +2,12 @@ require "helper"
|
|
2
2
|
|
3
3
|
describe HTTP2::Connection do
|
4
4
|
before(:each) do
|
5
|
-
@conn =
|
5
|
+
@conn = Client.new
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:f) { Framer.new }
|
9
9
|
|
10
10
|
context "initialization and settings" do
|
11
|
-
it "should return odd ids for client requests" do
|
12
|
-
@conn = Connection.new(:client)
|
13
|
-
@conn.new_stream.id.should_not be_even
|
14
|
-
|
15
|
-
@conn = Connection.new(:server)
|
16
|
-
@conn.new_stream.id.should be_even
|
17
|
-
end
|
18
|
-
|
19
11
|
it "should raise error if first frame is not SETTINGS" do
|
20
12
|
(FRAME_TYPES - [SETTINGS]).each do |frame|
|
21
13
|
frame = set_stream_id(f.generate(frame), 0x0)
|
@@ -33,8 +25,8 @@ describe HTTP2::Connection do
|
|
33
25
|
end
|
34
26
|
|
35
27
|
context "stream management" do
|
36
|
-
it "should initialize to default stream limit (
|
37
|
-
@conn.stream_limit.should eq
|
28
|
+
it "should initialize to default stream limit (100)" do
|
29
|
+
@conn.stream_limit.should eq 100
|
38
30
|
end
|
39
31
|
|
40
32
|
it "should change stream limit to received SETTINGS value" do
|
@@ -93,56 +85,6 @@ describe HTTP2::Connection do
|
|
93
85
|
|
94
86
|
stream.priority.should eq 20
|
95
87
|
end
|
96
|
-
|
97
|
-
context "push" do
|
98
|
-
it "should raise error on PUSH_PROMISE against stream 0" do
|
99
|
-
expect {
|
100
|
-
@conn << set_stream_id(f.generate(PUSH_PROMISE), 0)
|
101
|
-
}.to raise_error(ProtocolError)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should raise error on PUSH_PROMISE against bogus stream" do
|
105
|
-
expect {
|
106
|
-
@conn << set_stream_id(f.generate(PUSH_PROMISE), 31415)
|
107
|
-
}.to raise_error(ProtocolError)
|
108
|
-
end
|
109
|
-
|
110
|
-
it "should raise error on PUSH_PROMISE against non-idle stream" do
|
111
|
-
expect {
|
112
|
-
s = @conn.new_stream
|
113
|
-
s.send HEADERS
|
114
|
-
|
115
|
-
@conn << set_stream_id(f.generate(PUSH_PROMISE), s.id)
|
116
|
-
@conn << set_stream_id(f.generate(PUSH_PROMISE), s.id)
|
117
|
-
}.to raise_error(ProtocolError)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should emit stream object for received PUSH_PROMISE" do
|
121
|
-
s = @conn.new_stream
|
122
|
-
s.send HEADERS
|
123
|
-
|
124
|
-
promise = nil
|
125
|
-
@conn.on(:promise) {|s| promise = s }
|
126
|
-
@conn << set_stream_id(f.generate(PUSH_PROMISE), s.id)
|
127
|
-
|
128
|
-
promise.id.should eq 2
|
129
|
-
promise.state.should eq :reserved_remote
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should auto RST_STREAM promises against locally-RST stream" do
|
133
|
-
s = @conn.new_stream
|
134
|
-
s.send HEADERS
|
135
|
-
s.close
|
136
|
-
|
137
|
-
@conn.stub(:send)
|
138
|
-
@conn.should_receive(:send) do |frame|
|
139
|
-
frame[:type].should eq :rst_stream
|
140
|
-
frame[:stream].should eq 2
|
141
|
-
end
|
142
|
-
|
143
|
-
@conn << set_stream_id(f.generate(PUSH_PROMISE), s.id)
|
144
|
-
end
|
145
|
-
end
|
146
88
|
end
|
147
89
|
|
148
90
|
context "flow control" do
|
@@ -295,24 +237,22 @@ describe HTTP2::Connection do
|
|
295
237
|
|
296
238
|
it "should raise connection error on decode exception" do
|
297
239
|
@conn << f.generate(SETTINGS)
|
240
|
+
frame = f.generate(HEADERS.dup)
|
241
|
+
frame[1] = 0.chr
|
298
242
|
|
299
|
-
|
300
|
-
headers[:payload] = [0x44, 0x16].pack("C*")
|
301
|
-
expect { @conn << f.generate(headers) }.to raise_error(CompressionError)
|
243
|
+
expect { @conn << frame }.to raise_error(ProtocolError)
|
302
244
|
end
|
303
245
|
|
304
246
|
it "should emit encoded frames via on(:frame)" do
|
305
247
|
bytes = nil
|
306
248
|
@conn.on(:frame) {|d| bytes = d }
|
307
|
-
@conn.settings(
|
308
|
-
settings_max_concurrent_streams: 10,
|
309
|
-
settings_flow_control_options: 1
|
310
|
-
})
|
249
|
+
@conn.settings(stream_limit: 10, window_limit: Float::INFINITY)
|
311
250
|
|
312
251
|
bytes.should eq f.generate(SETTINGS)
|
313
252
|
end
|
314
253
|
|
315
254
|
it "should compress stream headers" do
|
255
|
+
@conn.ping("12345678")
|
316
256
|
@conn.on(:frame) do |bytes|
|
317
257
|
bytes.force_encoding('binary')
|
318
258
|
bytes.should_not match('get')
|
@@ -331,6 +271,16 @@ describe HTTP2::Connection do
|
|
331
271
|
end
|
332
272
|
|
333
273
|
context "connection management" do
|
274
|
+
it "should raise error on invalid connection header" do
|
275
|
+
srv = Server.new
|
276
|
+
expect { srv.dup << f.generate(SETTINGS) }.to raise_error(HandshakeError)
|
277
|
+
|
278
|
+
expect {
|
279
|
+
srv << CONNECTION_HEADER
|
280
|
+
srv << f.generate(SETTINGS)
|
281
|
+
}.to_not raise_error
|
282
|
+
end
|
283
|
+
|
334
284
|
it "should respond to PING frames" do
|
335
285
|
@conn << f.generate(SETTINGS)
|
336
286
|
@conn.should_receive(:send) do |frame|
|
@@ -408,18 +358,16 @@ describe HTTP2::Connection do
|
|
408
358
|
|
409
359
|
context "API" do
|
410
360
|
it ".settings should emit SETTINGS frames" do
|
411
|
-
settings = {
|
412
|
-
settings_max_concurrent_streams: 10,
|
413
|
-
settings_flow_control_options: 1
|
414
|
-
}
|
415
|
-
|
416
361
|
@conn.should_receive(:send) do |frame|
|
417
362
|
frame[:type].should eq :settings
|
418
|
-
frame[:payload].should eq
|
363
|
+
frame[:payload].should eq({
|
364
|
+
settings_max_concurrent_streams: 10,
|
365
|
+
settings_flow_control_options: 1
|
366
|
+
})
|
419
367
|
frame[:stream].should eq 0
|
420
368
|
end
|
421
369
|
|
422
|
-
@conn.settings
|
370
|
+
@conn.settings(stream_limit: 10, window_limit: Float::INFINITY)
|
423
371
|
end
|
424
372
|
|
425
373
|
it ".ping should generate PING frames" do
|
@@ -444,5 +392,6 @@ describe HTTP2::Connection do
|
|
444
392
|
|
445
393
|
@conn.goaway(:internal_error, "payload")
|
446
394
|
end
|
395
|
+
|
447
396
|
end
|
448
397
|
end
|
data/spec/emitter_spec.rb
CHANGED
@@ -31,6 +31,14 @@ describe HTTP2::Emitter do
|
|
31
31
|
args.should eq 123
|
32
32
|
end
|
33
33
|
|
34
|
+
it "should pass emitted callbacks to listeners" do
|
35
|
+
@w.on(:a) { |&block| block.call }
|
36
|
+
@w.once(:a) { |&block| block.call }
|
37
|
+
@w.emit(:a) { @cnt += 1 }
|
38
|
+
|
39
|
+
@cnt.should eq 2
|
40
|
+
end
|
41
|
+
|
34
42
|
it "should allow events with no callbacks" do
|
35
43
|
expect { @w.emit(:missing) }.to_not raise_error
|
36
44
|
end
|
data/spec/framer_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe HTTP2::Framer do
|
|
14
14
|
}
|
15
15
|
}
|
16
16
|
|
17
|
-
let(:bytes) { [0x04, 0x01, 0x7, 0x0000000F].pack("
|
17
|
+
let(:bytes) { [0x04, 0x01, 0x7, 0x0000000F].pack("nCCN") }
|
18
18
|
|
19
19
|
it "should generate common 8 byte header" do
|
20
20
|
f.commonHeader(frame).should eq bytes
|
@@ -64,9 +64,9 @@ describe HTTP2::Framer do
|
|
64
64
|
}
|
65
65
|
|
66
66
|
bytes = f.generate(frame)
|
67
|
-
bytes.should eq [0x4,0x0,0x3,0x1,*'text'.bytes].pack("
|
67
|
+
bytes.should eq [0x4,0x0,0x3,0x1,*'text'.bytes].pack("nCCNC*")
|
68
68
|
|
69
|
-
f.parse(
|
69
|
+
f.parse(bytes).should eq frame
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -81,8 +81,8 @@ describe HTTP2::Framer do
|
|
81
81
|
}
|
82
82
|
|
83
83
|
bytes = f.generate(frame)
|
84
|
-
bytes.should eq [0xc,0x1,0x7,0x1,*'header-block'.bytes].pack("
|
85
|
-
f.parse(
|
84
|
+
bytes.should eq [0xc,0x1,0x7,0x1,*'header-block'.bytes].pack("nCCNC*")
|
85
|
+
f.parse(bytes).should eq frame
|
86
86
|
end
|
87
87
|
|
88
88
|
it "should carry an optional stream priority" do
|
@@ -96,8 +96,8 @@ describe HTTP2::Framer do
|
|
96
96
|
}
|
97
97
|
|
98
98
|
bytes = f.generate(frame)
|
99
|
-
bytes.should eq [0x10,0x1,0xc,0x1,0xf,*'header-block'.bytes].pack("
|
100
|
-
f.parse(
|
99
|
+
bytes.should eq [0x10,0x1,0xc,0x1,0xf,*'header-block'.bytes].pack("nCCNNC*")
|
100
|
+
f.parse(bytes).should eq frame
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
@@ -111,8 +111,8 @@ describe HTTP2::Framer do
|
|
111
111
|
}
|
112
112
|
|
113
113
|
bytes = f.generate(frame)
|
114
|
-
bytes.should eq [0x4,0x2,0x0,0x1,0xf].pack("
|
115
|
-
f.parse(
|
114
|
+
bytes.should eq [0x4,0x2,0x0,0x1,0xf].pack("nCCNN")
|
115
|
+
f.parse(bytes).should eq frame
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
@@ -126,8 +126,8 @@ describe HTTP2::Framer do
|
|
126
126
|
}
|
127
127
|
|
128
128
|
bytes = f.generate(frame)
|
129
|
-
bytes.should eq [0x4,0x3,0x0,0x1,0x5].pack("
|
130
|
-
f.parse(
|
129
|
+
bytes.should eq [0x4,0x3,0x0,0x1,0x5].pack("nCCNN")
|
130
|
+
f.parse(bytes).should eq frame
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
@@ -136,6 +136,7 @@ describe HTTP2::Framer do
|
|
136
136
|
{
|
137
137
|
length: 8,
|
138
138
|
type: :settings,
|
139
|
+
flags: [],
|
139
140
|
stream: 0,
|
140
141
|
payload: {
|
141
142
|
settings_max_concurrent_streams: 10
|
@@ -146,20 +147,19 @@ describe HTTP2::Framer do
|
|
146
147
|
it "should generate and parse bytes" do
|
147
148
|
|
148
149
|
bytes = f.generate(frame)
|
149
|
-
bytes.should eq [0x8,0x4,0x0,0x0,0x4,0xa].pack("
|
150
|
-
f.parse(
|
150
|
+
bytes.should eq [0x8,0x4,0x0,0x0,0x4,0xa].pack("nCCNNN")
|
151
|
+
f.parse(bytes).should eq frame
|
151
152
|
end
|
152
153
|
|
153
|
-
it "should
|
154
|
-
frame[:length] = 8*
|
154
|
+
it "should ignore custom settings" do
|
155
|
+
frame[:length] = 8*2
|
155
156
|
frame[:payload] = {
|
156
157
|
settings_max_concurrent_streams: 10,
|
157
|
-
settings_initial_window_size: 20
|
158
|
-
55 => 30
|
158
|
+
settings_initial_window_size: 20
|
159
159
|
}
|
160
160
|
|
161
|
-
f.
|
162
|
-
|
161
|
+
buf = f.generate(frame.merge({55 => 30}))
|
162
|
+
f.parse(buf).should eq frame
|
163
163
|
end
|
164
164
|
|
165
165
|
it "should raise exception on invalid stream ID" do
|
@@ -189,8 +189,8 @@ describe HTTP2::Framer do
|
|
189
189
|
}
|
190
190
|
|
191
191
|
bytes = f.generate(frame)
|
192
|
-
bytes.should eq [0xb,0x5,0x1,0x1,0x2,*'headers'.bytes].pack("
|
193
|
-
f.parse(
|
192
|
+
bytes.should eq [0xb,0x5,0x1,0x1,0x2,*'headers'.bytes].pack("nCCNNC*")
|
193
|
+
f.parse(bytes).should eq frame
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
@@ -207,8 +207,8 @@ describe HTTP2::Framer do
|
|
207
207
|
|
208
208
|
it "should generate and parse bytes" do
|
209
209
|
bytes = f.generate(frame)
|
210
|
-
bytes.should eq [0x8,0x6,0x1,0x1,*'12345678'.bytes].pack("
|
211
|
-
f.parse(
|
210
|
+
bytes.should eq [0x8,0x6,0x1,0x1,*'12345678'.bytes].pack("nCCNC*")
|
211
|
+
f.parse(bytes).should eq frame
|
212
212
|
end
|
213
213
|
|
214
214
|
it "should raise exception on invalid payload" do
|
@@ -233,8 +233,8 @@ describe HTTP2::Framer do
|
|
233
233
|
|
234
234
|
it "should generate and parse bytes" do
|
235
235
|
bytes = f.generate(frame)
|
236
|
-
bytes.should eq [0xd,0x7,0x0,0x1,0x2,0x0,*'debug'.bytes].pack("
|
237
|
-
f.parse(
|
236
|
+
bytes.should eq [0xd,0x7,0x0,0x1,0x2,0x0,*'debug'.bytes].pack("nCCNNNC*")
|
237
|
+
f.parse(bytes).should eq frame
|
238
238
|
end
|
239
239
|
|
240
240
|
it "should treat debug payload as optional" do
|
@@ -242,8 +242,8 @@ describe HTTP2::Framer do
|
|
242
242
|
frame[:length] = 0x8
|
243
243
|
|
244
244
|
bytes = f.generate(frame)
|
245
|
-
bytes.should eq [0x8,0x7,0x0,0x1,0x2,0x0].pack("
|
246
|
-
f.parse(
|
245
|
+
bytes.should eq [0x8,0x7,0x0,0x1,0x2,0x0].pack("nCCNNN")
|
246
|
+
f.parse(bytes).should eq frame
|
247
247
|
end
|
248
248
|
end
|
249
249
|
|
@@ -256,8 +256,8 @@ describe HTTP2::Framer do
|
|
256
256
|
}
|
257
257
|
|
258
258
|
bytes = f.generate(frame)
|
259
|
-
bytes.should eq [0x4,0x9,0x0,0x0,0xa].pack("
|
260
|
-
f.parse(
|
259
|
+
bytes.should eq [0x4,0x9,0x0,0x0,0xa].pack("nCCNN")
|
260
|
+
f.parse(bytes).should eq frame
|
261
261
|
end
|
262
262
|
end
|
263
263
|
|
@@ -272,8 +272,8 @@ describe HTTP2::Framer do
|
|
272
272
|
}
|
273
273
|
|
274
274
|
bytes = f.generate(frame)
|
275
|
-
bytes.should eq [0xc,0xa,0x3,0x1,*'header-block'.bytes].pack("
|
276
|
-
f.parse(
|
275
|
+
bytes.should eq [0xc,0xa,0x3,0x1,*'header-block'.bytes].pack("nCCNC*")
|
276
|
+
f.parse(bytes).should eq frame
|
277
277
|
end
|
278
278
|
end
|
279
279
|
|
@@ -293,7 +293,7 @@ describe HTTP2::Framer do
|
|
293
293
|
|
294
294
|
frames.each do |(frame, size)|
|
295
295
|
bytes = f.generate(frame)
|
296
|
-
|
296
|
+
bytes.slice(0,2).unpack("n").first.should eq size
|
297
297
|
end
|
298
298
|
end
|
299
299
|
|
@@ -303,7 +303,7 @@ describe HTTP2::Framer do
|
|
303
303
|
{type: :data, stream: 1, flags: [:end_stream], payload: "abc"}
|
304
304
|
]
|
305
305
|
|
306
|
-
buf =
|
306
|
+
buf = f.generate(frames[0]) << f.generate(frames[1])
|
307
307
|
|
308
308
|
f.parse(buf).should eq frames[0]
|
309
309
|
f.parse(buf).should eq frames[1]
|
@@ -313,13 +313,9 @@ describe HTTP2::Framer do
|
|
313
313
|
frame = {type: :headers, stream: 1, payload: "headers"}
|
314
314
|
bytes = f.generate(frame)
|
315
315
|
|
316
|
-
|
317
|
-
f.parse(
|
318
|
-
|
319
|
-
|
320
|
-
buf = Buffer.new(bytes)
|
321
|
-
f.parse(buf).should eq frame
|
322
|
-
buf.should be_empty
|
316
|
+
f.parse(bytes[0...-1]).should be_nil
|
317
|
+
f.parse(bytes).should eq frame
|
318
|
+
bytes.should be_empty
|
323
319
|
end
|
324
320
|
|
325
321
|
end
|
data/spec/helper.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'http/2'
|
2
|
+
require 'json'
|
3
|
+
require 'coveralls'
|
4
|
+
|
5
|
+
Coveralls.wear! if ENV["CI"]
|
2
6
|
|
3
7
|
include HTTP2
|
4
8
|
include HTTP2::Header
|
@@ -91,8 +95,8 @@ FRAME_TYPES = [
|
|
91
95
|
]
|
92
96
|
|
93
97
|
def set_stream_id(bytes, id)
|
94
|
-
head = bytes.slice!(0,8).unpack(
|
98
|
+
head = bytes.slice!(0,8).unpack('nCCN')
|
95
99
|
head[3] = id
|
96
100
|
|
97
|
-
head.pack(
|
101
|
+
head.pack('nCCN') + bytes
|
98
102
|
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
describe HTTP2::Server do
|
4
|
+
before(:each) do
|
5
|
+
@srv = Server.new
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:f) { Framer.new }
|
9
|
+
|
10
|
+
context "initialization and settings" do
|
11
|
+
it "should return even stream IDs" do
|
12
|
+
@srv.new_stream.id.should be_even
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should emit SETTINGS on new connection" do
|
16
|
+
frames = []
|
17
|
+
@srv.on(:frame) { |recv| frames << recv }
|
18
|
+
@srv << CONNECTION_HEADER
|
19
|
+
|
20
|
+
f.parse(frames[0])[:type].should eq :settings
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should initialize client with custom connection settings" do
|
24
|
+
frames = []
|
25
|
+
|
26
|
+
@srv = Server.new(streams: 200, window: 2**10)
|
27
|
+
@srv.on(:frame) { |recv| frames << recv }
|
28
|
+
@srv << CONNECTION_HEADER
|
29
|
+
|
30
|
+
frame = f.parse(frames[0])
|
31
|
+
frame[:type].should eq :settings
|
32
|
+
frame[:payload][:settings_max_concurrent_streams].should eq 200
|
33
|
+
frame[:payload][:settings_initial_window_size].should eq 2**10
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should allow server push" do
|
38
|
+
client = Client.new
|
39
|
+
client.on(:frame) { |bytes| @srv << bytes }
|
40
|
+
|
41
|
+
@srv.on(:stream) do |stream|
|
42
|
+
expect {
|
43
|
+
stream.promise({}) {}
|
44
|
+
}.to_not raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
client.new_stream
|
48
|
+
client.send HEADERS
|
49
|
+
end
|
50
|
+
end
|
data/spec/stream_spec.rb
CHANGED
@@ -2,8 +2,8 @@ require "helper"
|
|
2
2
|
|
3
3
|
describe HTTP2::Stream do
|
4
4
|
before(:each) do
|
5
|
-
@
|
6
|
-
@stream = @
|
5
|
+
@client = Client.new
|
6
|
+
@stream = @client.new_stream
|
7
7
|
end
|
8
8
|
|
9
9
|
context "stream states" do
|
@@ -11,10 +11,9 @@ describe HTTP2::Stream do
|
|
11
11
|
@stream.state.should eq :idle
|
12
12
|
end
|
13
13
|
|
14
|
-
it "should set stream priority
|
15
|
-
stream = @
|
14
|
+
it "should set custom stream priority" do
|
15
|
+
stream = @client.new_stream(priority: 3)
|
16
16
|
stream.priority.should eq 3
|
17
|
-
stream.window.should eq 1024
|
18
17
|
end
|
19
18
|
|
20
19
|
context "reserved (local)" do
|
@@ -137,7 +136,7 @@ describe HTTP2::Stream do
|
|
137
136
|
end
|
138
137
|
|
139
138
|
it "should transition to half closed if remote opened with END_STREAM" do
|
140
|
-
s = @
|
139
|
+
s = @client.new_stream
|
141
140
|
hclose = HEADERS.dup
|
142
141
|
hclose[:flags] = [:end_stream]
|
143
142
|
|
@@ -146,7 +145,7 @@ describe HTTP2::Stream do
|
|
146
145
|
end
|
147
146
|
|
148
147
|
it "should transition to half closed if local opened with END_STREAM" do
|
149
|
-
s = @
|
148
|
+
s = @client.new_stream
|
150
149
|
hclose = HEADERS.dup
|
151
150
|
hclose[:flags] = [:end_stream]
|
152
151
|
|
@@ -166,8 +165,8 @@ describe HTTP2::Stream do
|
|
166
165
|
|
167
166
|
it "should emit :active on open transition" do
|
168
167
|
openp, openr = false, false
|
169
|
-
sp = @
|
170
|
-
sr = @
|
168
|
+
sp = @client.new_stream
|
169
|
+
sr = @client.new_stream
|
171
170
|
sp.on(:active) { openp = true }
|
172
171
|
sr.on(:active) { openr = true }
|
173
172
|
|
@@ -179,7 +178,7 @@ describe HTTP2::Stream do
|
|
179
178
|
end
|
180
179
|
|
181
180
|
it "should not emit :active on transition from open" do
|
182
|
-
order, stream = [], @
|
181
|
+
order, stream = [], @client.new_stream
|
183
182
|
|
184
183
|
stream.on(:active) { order << :active }
|
185
184
|
stream.on(:half_close) { order << :half_close }
|
@@ -208,7 +207,7 @@ describe HTTP2::Stream do
|
|
208
207
|
end
|
209
208
|
|
210
209
|
it "should emit :close after frame is processed" do
|
211
|
-
order, stream = [], @
|
210
|
+
order, stream = [], @client.new_stream
|
212
211
|
|
213
212
|
stream.on(:active) { order << :active }
|
214
213
|
stream.on(:data) { order << :data }
|
@@ -270,7 +269,7 @@ describe HTTP2::Stream do
|
|
270
269
|
|
271
270
|
it "should emit :half_close event on transition" do
|
272
271
|
order = []
|
273
|
-
stream = @
|
272
|
+
stream = @client.new_stream
|
274
273
|
stream.on(:active) { order << :active }
|
275
274
|
stream.on(:half_close) { order << :half_close }
|
276
275
|
|
@@ -330,7 +329,7 @@ describe HTTP2::Stream do
|
|
330
329
|
|
331
330
|
it "should emit :half_close event on transition" do
|
332
331
|
order = []
|
333
|
-
stream = @
|
332
|
+
stream = @client.new_stream
|
334
333
|
stream.on(:active) { order << :active }
|
335
334
|
stream.on(:half_close) { order << :half_close }
|
336
335
|
|
@@ -460,9 +459,9 @@ describe HTTP2::Stream do
|
|
460
459
|
settings[:stream] = 0
|
461
460
|
|
462
461
|
framer = Framer.new
|
463
|
-
@
|
462
|
+
@client << framer.generate(settings)
|
464
463
|
|
465
|
-
s1 = @
|
464
|
+
s1 = @client.new_stream
|
466
465
|
s1.send HEADERS
|
467
466
|
s1.send data.merge({payload: "x" * 900, flags: []})
|
468
467
|
s1.window.should eq 100
|
@@ -471,7 +470,7 @@ describe HTTP2::Stream do
|
|
471
470
|
s1.window.should eq 0
|
472
471
|
s1.buffered_amount.should eq 100
|
473
472
|
|
474
|
-
@
|
473
|
+
@client << framer.generate(WINDOW_UPDATE.merge({
|
475
474
|
stream: s1.id, increment: 1000
|
476
475
|
}))
|
477
476
|
s1.buffered_amount.should eq 0
|
@@ -490,8 +489,8 @@ describe HTTP2::Stream do
|
|
490
489
|
end
|
491
490
|
|
492
491
|
it ".reprioritize should raise error if invoked by server" do
|
493
|
-
|
494
|
-
stream =
|
492
|
+
srv = Server.new
|
493
|
+
stream = srv.new_stream
|
495
494
|
|
496
495
|
expect { stream.reprioritize(10) }.to raise_error(StreamError)
|
497
496
|
end
|
@@ -557,11 +556,11 @@ describe HTTP2::Stream do
|
|
557
556
|
|
558
557
|
context "server API" do
|
559
558
|
before(:each) do
|
560
|
-
@srv =
|
559
|
+
@srv = Server.new
|
561
560
|
@frm = Framer.new
|
562
561
|
|
563
|
-
@
|
564
|
-
@client_stream = @
|
562
|
+
@client.on(:frame) {|bytes| @srv << bytes }
|
563
|
+
@client_stream = @client.new_stream
|
565
564
|
end
|
566
565
|
|
567
566
|
it "should emit received headers via on(:headers)" do
|
@@ -600,21 +599,15 @@ describe HTTP2::Stream do
|
|
600
599
|
|
601
600
|
context "push" do
|
602
601
|
before(:each) do
|
603
|
-
@srv.on(:frame) {|bytes| @
|
602
|
+
@srv.on(:frame) {|bytes| @client << bytes }
|
604
603
|
@srv.on(:stream) do |stream|
|
605
604
|
@server_stream = stream
|
606
605
|
end
|
607
606
|
|
608
|
-
@srv << @frm.generate(SETTINGS)
|
607
|
+
# @srv << @frm.generate(SETTINGS)
|
609
608
|
@client_stream.headers({"key" => "value"})
|
610
609
|
end
|
611
610
|
|
612
|
-
it ".promise should raise error on client push" do
|
613
|
-
expect do
|
614
|
-
@client_stream.promise({}) {}
|
615
|
-
end.to raise_error(ProtocolError)
|
616
|
-
end
|
617
|
-
|
618
611
|
it ".promise should emit server initiated stream" do
|
619
612
|
push = nil
|
620
613
|
@server_stream.promise({"key" => "val"}) { |pstream| push = pstream }
|
@@ -651,7 +644,7 @@ describe HTTP2::Stream do
|
|
651
644
|
|
652
645
|
it "client: headers > active > headers > .. > data > close" do
|
653
646
|
order, headers = [], {}
|
654
|
-
@
|
647
|
+
@client.on(:promise) do |push|
|
655
648
|
order << :reserved
|
656
649
|
|
657
650
|
push.on(:active) { order << :active }
|