@@ -8,6 +8,7 @@ if (!common.hasCrypto)
88const assert = require ( 'assert' ) ;
99const h2 = require ( 'http2' ) ;
1010const { kSocket } = require ( 'internal/http2/util' ) ;
11+ const { kEvents } = require ( 'internal/event_target' ) ;
1112const Countdown = require ( '../common/countdown' ) ;
1213
1314{
@@ -167,3 +168,76 @@ const Countdown = require('../common/countdown');
167168 req . on ( 'close' , common . mustCall ( ( ) => server . close ( ) ) ) ;
168169 } ) ) ;
169170}
171+
172+ // Destroy with AbortSignal
173+ {
174+ const server = h2 . createServer ( ) ;
175+ const controller = new AbortController ( ) ;
176+
177+ server . on ( 'stream' , common . mustNotCall ( ) ) ;
178+ server . listen ( 0 , common . mustCall ( ( ) => {
179+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
180+ client . on ( 'close' , common . mustCall ( ) ) ;
181+
182+ const { signal } = controller ;
183+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
184+
185+ client . on ( 'error' , common . mustCall ( ( ) => {
186+ // After underlying stream dies, signal listener detached
187+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
188+ } ) ) ;
189+
190+ const req = client . request ( { } , { signal } ) ;
191+
192+ req . on ( 'error' , common . mustCall ( ( err ) => {
193+ assert . strictEqual ( err . code , 'ABORT_ERR' ) ;
194+ assert . strictEqual ( err . name , 'AbortError' ) ;
195+ } ) ) ;
196+ req . on ( 'close' , common . mustCall ( ( ) => server . close ( ) ) ) ;
197+
198+ assert . strictEqual ( req . aborted , false ) ;
199+ assert . strictEqual ( req . destroyed , false ) ;
200+ // Signal listener attached
201+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) . size , 1 ) ;
202+
203+ controller . abort ( ) ;
204+
205+ assert . strictEqual ( req . aborted , false ) ;
206+ assert . strictEqual ( req . destroyed , true ) ;
207+ } ) ) ;
208+ }
209+ // Pass an already destroyed signal to abort immediately.
210+ {
211+ const server = h2 . createServer ( ) ;
212+ const controller = new AbortController ( ) ;
213+
214+ server . on ( 'stream' , common . mustNotCall ( ) ) ;
215+ server . listen ( 0 , common . mustCall ( ( ) => {
216+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
217+ client . on ( 'close' , common . mustCall ( ) ) ;
218+
219+ const { signal } = controller ;
220+ controller . abort ( ) ;
221+
222+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
223+
224+ client . on ( 'error' , common . mustCall ( ( ) => {
225+ // After underlying stream dies, signal listener detached
226+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
227+ } ) ) ;
228+
229+ const req = client . request ( { } , { signal } ) ;
230+ // Signal already aborted, so no event listener attached.
231+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
232+
233+ assert . strictEqual ( req . aborted , false ) ;
234+ // Destroyed on same tick as request made
235+ assert . strictEqual ( req . destroyed , true ) ;
236+
237+ req . on ( 'error' , common . mustCall ( ( err ) => {
238+ assert . strictEqual ( err . code , 'ABORT_ERR' ) ;
239+ assert . strictEqual ( err . name , 'AbortError' ) ;
240+ } ) ) ;
241+ req . on ( 'close' , common . mustCall ( ( ) => server . close ( ) ) ) ;
242+ } ) ) ;
243+ }
0 commit comments