2
2
// Flags: --expose-internals
3
3
4
4
const common = require ( '../common' ) ;
5
+ const assert = require ( 'assert' ) ;
5
6
6
7
if ( ! common . hasCrypto )
7
8
common . skip ( 'missing crypto' ) ;
@@ -13,16 +14,36 @@ const h2test = require('../common/http2');
13
14
let client ;
14
15
15
16
const server = h2 . createServer ( ) ;
17
+ let gotFirstStreamId1 ;
16
18
server . on ( 'stream' , common . mustCall ( ( stream ) => {
17
19
stream . respond ( ) ;
18
20
stream . end ( 'ok' ) ;
19
21
20
- // the error will be emitted asynchronously
21
- stream . on ( 'error' , common . expectsError ( {
22
- type : NghttpError ,
23
- code : 'ERR_HTTP2_ERROR' ,
24
- message : 'Stream was already closed or invalid'
25
- } ) ) ;
22
+ // Http2Server should be fast enough to respond to and close
23
+ // the first streams with ID 1 and ID 3 without errors.
24
+
25
+ // Test for errors in 'close' event to ensure no errors on some streams.
26
+ stream . on ( 'error' , ( ) => { } ) ;
27
+ stream . on ( 'close' , ( err ) => {
28
+ if ( stream . id === 1 ) {
29
+ if ( gotFirstStreamId1 ) {
30
+ // We expect our outgoing frames to fail on Stream ID 1 the second time
31
+ // because a stream with ID 1 was already closed before.
32
+ common . expectsError ( {
33
+ constructor : NghttpError ,
34
+ code : 'ERR_HTTP2_ERROR' ,
35
+ message : 'Stream was already closed or invalid'
36
+ } ) ;
37
+ return ;
38
+ }
39
+ gotFirstStreamId1 = true ;
40
+ }
41
+ assert . strictEqual ( err , undefined ) ;
42
+ } ) ;
43
+
44
+ // Stream ID 5 should never reach the server
45
+ assert . notStrictEqual ( stream . id , 5 ) ;
46
+
26
47
} , 2 ) ) ;
27
48
28
49
server . on ( 'session' , common . mustCall ( ( session ) => {
@@ -35,26 +56,27 @@ server.on('session', common.mustCall((session) => {
35
56
36
57
const settings = new h2test . SettingsFrame ( ) ;
37
58
const settingsAck = new h2test . SettingsFrame ( true ) ;
38
- const head1 = new h2test . HeadersFrame ( 1 , h2test . kFakeRequestHeaders , 0 , true ) ;
39
- const head2 = new h2test . HeadersFrame ( 3 , h2test . kFakeRequestHeaders , 0 , true ) ;
40
- const head3 = new h2test . HeadersFrame ( 1 , h2test . kFakeRequestHeaders , 0 , true ) ;
41
- const head4 = new h2test . HeadersFrame ( 5 , h2test . kFakeRequestHeaders , 0 , true ) ;
59
+ // HeadersFrame(id, payload, padding, END_STREAM)
60
+ const id1 = new h2test . HeadersFrame ( 1 , h2test . kFakeRequestHeaders , 0 , true ) ;
61
+ const id3 = new h2test . HeadersFrame ( 3 , h2test . kFakeRequestHeaders , 0 , true ) ;
62
+ const id5 = new h2test . HeadersFrame ( 5 , h2test . kFakeRequestHeaders , 0 , true ) ;
42
63
43
64
server . listen ( 0 , ( ) => {
44
65
client = net . connect ( server . address ( ) . port , ( ) => {
45
66
client . write ( h2test . kClientMagic , ( ) => {
46
67
client . write ( settings . data , ( ) => {
47
68
client . write ( settingsAck . data ) ;
48
- // This will make it ok.
49
- client . write ( head1 . data , ( ) => {
50
- // This will make it ok.
51
- client . write ( head2 . data , ( ) => {
69
+ // Stream ID 1 frame will make it OK.
70
+ client . write ( id1 . data , ( ) => {
71
+ // Stream ID 3 frame will make it OK.
72
+ client . write ( id3 . data , ( ) => {
73
+ // A second Stream ID 1 frame should fail.
52
74
// This will cause an error to occur because the client is
53
75
// attempting to reuse an already closed stream. This must
54
76
// cause the server session to be torn down.
55
- client . write ( head3 . data , ( ) => {
56
- // This won't ever make it to the server
57
- client . write ( head4 . data ) ;
77
+ client . write ( id1 . data , ( ) => {
78
+ // This Stream ID 5 frame will never make it to the server
79
+ client . write ( id5 . data ) ;
58
80
} ) ;
59
81
} ) ;
60
82
} ) ;
0 commit comments