@@ -14,7 +14,11 @@ import {promiseWithResolvers} from "../utils/promiseWithResolvers.js";
1414const IGNORE_HEAD_STATUS_CODES = [ 405 , 501 , 404 ] ;
1515export type InputURLOptions = { partURLs : string [ ] } | { url : string } ;
1616
17- export type BaseDownloadEngineOptions = InputURLOptions & BaseDownloadEngineFetchStreamOptions & {
17+ export type CreateDownloadFileOptions = {
18+ reuseRedirectURL ?: boolean
19+ } ;
20+
21+ export type BaseDownloadEngineOptions = CreateDownloadFileOptions & InputURLOptions & BaseDownloadEngineFetchStreamOptions & {
1822 chunkSize ?: number ;
1923 parallelStreams ?: number ;
2024 retry ?: retry . Options
@@ -139,7 +143,7 @@ export default class BaseDownloadEngine extends EventEmitter<BaseDownloadEngineE
139143 return this . _engine . close ( ) ;
140144 }
141145
142- protected static async _createDownloadFile ( parts : string [ ] , fetchStream : BaseDownloadEngineFetchStream ) {
146+ protected static async _createDownloadFile ( parts : string [ ] , fetchStream : BaseDownloadEngineFetchStream , { reuseRedirectURL } : CreateDownloadFileOptions = { } ) {
143147 const localFileName = decodeURIComponent ( new URL ( parts [ 0 ] , "https://example" ) . pathname . split ( "/" )
144148 . pop ( ) || "" ) ;
145149 const downloadFile : DownloadFile = {
@@ -148,36 +152,34 @@ export default class BaseDownloadEngine extends EventEmitter<BaseDownloadEngineE
148152 localFileName
149153 } ;
150154
151- let counter = 0 ;
152- for ( const part of parts ) {
155+ downloadFile . parts = await Promise . all ( parts . map ( async ( part , index ) => {
153156 try {
154157 const { length, acceptRange, newURL, fileName} = await fetchStream . fetchDownloadInfo ( part ) ;
155- const downloadURL = newURL ?? part ;
158+ const downloadURL = reuseRedirectURL ? ( newURL ?? part ) : part ;
156159 const size = length || 0 ;
157160
158161 downloadFile . totalSize += size ;
159- downloadFile . parts . push ( {
162+ if ( index === 0 && fileName ) {
163+ downloadFile . localFileName = fileName ;
164+ }
165+
166+ return {
160167 downloadURL,
161168 size,
162169 acceptRange : size > 0 && acceptRange
163- } ) ;
164-
165- if ( counter ++ === 0 && fileName ) {
166- downloadFile . localFileName = fileName ;
167- }
170+ } ;
168171 } catch ( error : any ) {
169172 if ( error instanceof StatusCodeError && IGNORE_HEAD_STATUS_CODES . includes ( error . statusCode ) ) {
170173 // if the server does not support HEAD request, we will skip that step
171- downloadFile . parts . push ( {
174+ return {
172175 downloadURL : part ,
173176 size : 0 ,
174177 acceptRange : false
175- } ) ;
176- continue ;
178+ } ;
177179 }
178180 throw error ;
179181 }
180- }
182+ } ) ) ;
181183
182184 return downloadFile ;
183185 }
0 commit comments