@@ -6,50 +6,142 @@ if (!common.hasCrypto)
6
6
const assert = require ( 'assert' ) ;
7
7
const h2 = require ( 'http2' ) ;
8
8
9
- const server = h2 . createServer ( ) ;
10
- server . listen ( 0 ) ;
9
+ {
10
+ const server = h2 . createServer ( ) ;
11
+ server . listen (
12
+ 0 ,
13
+ common . mustCall ( ( ) => {
14
+ const destroyCallbacks = [
15
+ ( client ) => client . destroy ( ) ,
16
+ ( client ) => client . socket . destroy ( )
17
+ ] ;
11
18
12
- server . on ( 'listening' , common . mustCall ( function ( ) {
13
- const port = this . address ( ) . port ;
19
+ let remaining = destroyCallbacks . length ;
14
20
15
- const destroyCallbacks = [
16
- ( client ) => client . destroy ( ) ,
17
- ( client ) => client . socket . destroy ( )
18
- ] ;
21
+ destroyCallbacks . forEach ( ( destroyCallback ) => {
22
+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
23
+ client . on (
24
+ 'connect' ,
25
+ common . mustCall ( ( ) => {
26
+ const socket = client . socket ;
19
27
20
- let remaining = destroyCallbacks . length ;
28
+ assert ( client . socket , 'client session has associated socket' ) ;
29
+ assert (
30
+ ! client . destroyed ,
31
+ 'client has not been destroyed before destroy is called'
32
+ ) ;
33
+ assert (
34
+ ! socket . destroyed ,
35
+ 'socket has not been destroyed before destroy is called'
36
+ ) ;
21
37
22
- destroyCallbacks . forEach ( ( destroyCallback ) => {
23
- const client = h2 . connect ( `http://localhost:${ port } ` ) ;
24
- client . on ( 'connect' , common . mustCall ( ( ) => {
25
- const socket = client . socket ;
38
+ // Ensure that 'close' event is emitted
39
+ client . on ( 'close' , common . mustCall ( ) ) ;
26
40
27
- assert ( client . socket , 'client session has associated socket' ) ;
28
- assert ( ! client . destroyed ,
29
- 'client has not been destroyed before destroy is called' ) ;
30
- assert ( ! socket . destroyed ,
31
- 'socket has not been destroyed before destroy is called' ) ;
41
+ destroyCallback ( client ) ;
32
42
33
- // Ensure that 'close' event is emitted
34
- client . on ( 'close' , common . mustCall ( ) ) ;
43
+ assert (
44
+ ! client . socket ,
45
+ 'client.socket undefined after destroy is called'
46
+ ) ;
35
47
36
- destroyCallback ( client ) ;
48
+ // Must must be closed
49
+ client . on (
50
+ 'close' ,
51
+ common . mustCall ( ( ) => {
52
+ assert ( client . destroyed ) ;
53
+ } )
54
+ ) ;
37
55
38
- assert ( ! client . socket , 'client.socket undefined after destroy is called' ) ;
56
+ // socket will close on process.nextTick
57
+ socket . on (
58
+ 'close' ,
59
+ common . mustCall ( ( ) => {
60
+ assert ( socket . destroyed ) ;
61
+ } )
62
+ ) ;
39
63
40
- // Must must be closed
41
- client . on ( 'close' , common . mustCall ( ( ) => {
42
- assert ( client . destroyed ) ;
43
- } ) ) ;
64
+ if ( -- remaining === 0 ) {
65
+ server . close ( ) ;
66
+ }
67
+ } )
68
+ ) ;
69
+ } ) ;
70
+ } )
71
+ ) ;
72
+ }
44
73
45
- // socket will close on process.nextTick
46
- socket . on ( 'close' , common . mustCall ( ( ) => {
47
- assert ( socket . destroyed ) ;
48
- } ) ) ;
74
+ // test destroy before connect
75
+ {
76
+ const server = h2 . createServer ( ) ;
77
+ server . listen (
78
+ 0 ,
79
+ common . mustCall ( ( ) => {
80
+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
49
81
50
- if ( -- remaining === 0 ) {
51
- server . close ( ) ;
52
- }
53
- } ) ) ;
54
- } ) ;
55
- } ) ) ;
82
+ const req = client . request ( { ':path' : '/' } ) ;
83
+ client . destroy ( ) ;
84
+
85
+ req . on ( 'response' , common . mustNotCall ( ) ) ;
86
+ req . resume ( ) ;
87
+ req . on (
88
+ 'end' ,
89
+ common . mustCall ( ( ) => {
90
+ server . close ( ) ;
91
+ } )
92
+ ) ;
93
+ req . end ( ) ;
94
+ } )
95
+ ) ;
96
+ }
97
+
98
+ // test destroy before request
99
+ {
100
+ const server = h2 . createServer ( ) ;
101
+ server . listen (
102
+ 0 ,
103
+ common . mustCall ( ( ) => {
104
+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
105
+ client . destroy ( ) ;
106
+
107
+ assert . throws (
108
+ ( ) => client . request ( { ':path' : '/' } ) ,
109
+ common . expectsError ( {
110
+ code : 'ERR_HTTP2_INVALID_SESSION' ,
111
+ message : 'The session has been destroyed'
112
+ } )
113
+ ) ;
114
+
115
+ server . close ( ) ;
116
+ } )
117
+ ) ;
118
+ }
119
+
120
+ // test destroy before goaway
121
+ {
122
+ const server = h2 . createServer ( ) ;
123
+ server . on (
124
+ 'stream' ,
125
+ common . mustCall ( ( stream ) => {
126
+ stream . on ( 'error' , common . mustCall ( ) ) ;
127
+ stream . session . shutdown ( ) ;
128
+ } )
129
+ ) ;
130
+ server . listen (
131
+ 0 ,
132
+ common . mustCall ( ( ) => {
133
+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
134
+
135
+ client . on (
136
+ 'goaway' ,
137
+ common . mustCall ( ( ) => {
138
+ // We ought to be able to destroy the client in here without an error
139
+ server . close ( ) ;
140
+ client . destroy ( ) ;
141
+ } )
142
+ ) ;
143
+
144
+ client . request ( ) ;
145
+ } )
146
+ ) ;
147
+ }
0 commit comments