1- // Flags: --expose-internals
1+ // Flags: --expose-internals --experimental-abortcontroller
22
33'use strict' ;
44
@@ -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{
@@ -165,3 +166,76 @@ const Countdown = require('../common/countdown');
165166 req . on ( 'close' , common . mustCall ( ( ) => server . close ( ) ) ) ;
166167 } ) ) ;
167168}
169+
170+ // Destroy with AbortSignal
171+ {
172+ const server = h2 . createServer ( ) ;
173+ const controller = new AbortController ( ) ;
174+
175+ server . on ( 'stream' , common . mustNotCall ( ) ) ;
176+ server . listen ( 0 , common . mustCall ( ( ) => {
177+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
178+ client . on ( 'close' , common . mustCall ( ) ) ;
179+
180+ const { signal } = controller ;
181+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
182+
183+ client . on ( 'error' , common . mustCall ( ( ) => {
184+ // After underlying stream dies, signal listener detached
185+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
186+ } ) ) ;
187+
188+ const req = client . request ( { } , { signal } ) ;
189+
190+ req . on ( 'error' , common . mustCall ( ( err ) => {
191+ assert . strictEqual ( err . code , 'ABORT_ERR' ) ;
192+ assert . strictEqual ( err . name , 'AbortError' ) ;
193+ } ) ) ;
194+ req . on ( 'close' , common . mustCall ( ( ) => server . close ( ) ) ) ;
195+
196+ assert . strictEqual ( req . aborted , false ) ;
197+ assert . strictEqual ( req . destroyed , false ) ;
198+ // Signal listener attached
199+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) . size , 1 ) ;
200+
201+ controller . abort ( ) ;
202+
203+ assert . strictEqual ( req . aborted , false ) ;
204+ assert . strictEqual ( req . destroyed , true ) ;
205+ } ) ) ;
206+ }
207+ // Pass an already destroyed signal to abort immediately.
208+ {
209+ const server = h2 . createServer ( ) ;
210+ const controller = new AbortController ( ) ;
211+
212+ server . on ( 'stream' , common . mustNotCall ( ) ) ;
213+ server . listen ( 0 , common . mustCall ( ( ) => {
214+ const client = h2 . connect ( `http://localhost:${ server . address ( ) . port } ` ) ;
215+ client . on ( 'close' , common . mustCall ( ) ) ;
216+
217+ const { signal } = controller ;
218+ controller . abort ( ) ;
219+
220+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
221+
222+ client . on ( 'error' , common . mustCall ( ( ) => {
223+ // After underlying stream dies, signal listener detached
224+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
225+ } ) ) ;
226+
227+ const req = client . request ( { } , { signal } ) ;
228+ // Signal already aborted, so no event listener attached.
229+ assert . strictEqual ( signal [ kEvents ] . get ( 'abort' ) , undefined ) ;
230+
231+ assert . strictEqual ( req . aborted , false ) ;
232+ // Destroyed on same tick as request made
233+ assert . strictEqual ( req . destroyed , true ) ;
234+
235+ req . on ( 'error' , common . mustCall ( ( err ) => {
236+ assert . strictEqual ( err . code , 'ABORT_ERR' ) ;
237+ assert . strictEqual ( err . name , 'AbortError' ) ;
238+ } ) ) ;
239+ req . on ( 'close' , common . mustCall ( ( ) => server . close ( ) ) ) ;
240+ } ) ) ;
241+ }
0 commit comments