http-2 0.6.1 → 0.6.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/.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 }
|