@@ -29,6 +29,7 @@ const assert = require('node:assert')
2929const { getMaxListeners, setMaxListeners, defaultMaxListeners } = require ( 'node:events' )
3030
3131const kAbortController = Symbol ( 'abortController' )
32+ const kDependantAbortController = Symbol ( 'dependantAbortController' )
3233
3334const requestFinalizer = new FinalizationRegistry ( ( { signal, abort } ) => {
3435 signal . removeEventListener ( 'abort' , abort )
@@ -428,6 +429,12 @@ class Request {
428429 // See, https://github.com/nodejs/undici/issues/1926.
429430 this [ kAbortController ] = ac
430431
432+ // Keep ref to original ac while cloned request is alive.
433+ // See, https://github.com/nodejs/undici/issues/4068.
434+ if ( webidl . is . Request ( input ) && input [ kAbortController ] ) {
435+ this [ kDependantAbortController ] = input [ kAbortController ]
436+ }
437+
431438 const acRef = new WeakRef ( ac )
432439 const abort = buildAbort ( acRef )
433440
@@ -790,8 +797,19 @@ class Request {
790797 )
791798 }
792799
793- // 4. Return clonedRequestObject.
794- return fromInnerRequest ( clonedRequest , this . #dispatcher, ac . signal , getHeadersGuard ( this . #headers) )
800+ // 4. Construct clonedRequestObject.
801+ const req = fromInnerRequest ( clonedRequest , this . #dispatcher, ac . signal , getHeadersGuard ( this . #headers) )
802+ req [ kAbortController ] = ac
803+
804+ // 5. Keep reference of original controller to avoid GC
805+ // Keep ref to original ac while cloned request is alive.
806+ // See, https://github.com/nodejs/undici/issues/4068.
807+ if ( this [ kAbortController ] ) {
808+ req [ kDependantAbortController ] = this [ kAbortController ]
809+ }
810+
811+ // 6. Return cloned request
812+ return req
795813 }
796814
797815 [ nodeUtil . inspect . custom ] ( depth , options ) {
0 commit comments