@@ -137,7 +137,7 @@ export class FileFetcher {
137137 options : ResolvedFetchOptions ,
138138 httpCache : HttpCache ,
139139 ) : Promise < LoadResponse > {
140- const cached = this . #fetchCached ( specifier , 0 , options , httpCache ) ;
140+ const cached = this . fetchCachedOnce ( specifier , options , httpCache ) ;
141141 if ( cached ) {
142142 return cached ;
143143 }
@@ -163,26 +163,22 @@ export class FileFetcher {
163163 } ;
164164 }
165165
166- #fetchCached (
166+ fetchCachedOnce (
167167 specifier : URL ,
168- redirectLimit : number ,
169168 options : ResolvedFetchOptions ,
170169 httpCache : HttpCache ,
171170 ) : LoadResponse | undefined {
172- if ( redirectLimit < 0 ) {
173- throw new Deno . errors . Http (
174- `Too many redirects.\n Specifier: "${ specifier . toString ( ) } "` ,
175- ) ;
176- }
177-
178171 const headers = httpCache . getHeaders ( specifier ) ;
179172 if ( ! headers ) {
180173 return undefined ;
181174 }
182175 const location = headers [ "location" ] ;
183176 if ( location != null && location . length > 0 ) {
184177 const redirect = new URL ( location , specifier ) ;
185- return this . #fetchCached( redirect , redirectLimit - 1 , options , httpCache ) ;
178+ return {
179+ kind : "redirect" ,
180+ specifier : redirect . toString ( ) ,
181+ } ;
186182 }
187183 const content = httpCache . get ( specifier , options ) ;
188184 if ( content == null ) {
@@ -196,22 +192,14 @@ export class FileFetcher {
196192 } ;
197193 }
198194
199- async #fetchRemote (
195+ async #fetchRemoteOnce (
200196 specifier : URL ,
201- redirectLimit : number ,
202197 options : ResolvedFetchOptions ,
203198 httpCache : HttpCache ,
204199 ) : Promise < LoadResponse | undefined > {
205- if ( redirectLimit < 0 ) {
206- throw new Deno . errors . Http (
207- `Too many redirects.\n Specifier: "${ specifier . toString ( ) } "` ,
208- ) ;
209- }
210-
211200 if ( shouldUseCache ( options . cacheSetting , specifier ) ) {
212- const response = this . #fetchCached (
201+ const response = this . fetchCachedOnce (
213202 specifier ,
214- redirectLimit ,
215203 options ,
216204 httpCache ,
217205 ) ;
@@ -283,6 +271,25 @@ export class FileFetcher {
283271 }
284272
285273 async fetch (
274+ specifier : URL ,
275+ // Providing a checksum here doesn't make sense because the provided
276+ // checksum will change based on the specifier being requested, which
277+ // could be invalided by a redirect
278+ options ?: Omit < FetchOptions , "checksum" > ,
279+ ) : Promise < LoadResponse | undefined > {
280+ for ( let i = 0 ; i <= 10 ; i ++ ) {
281+ const response = await this . fetchOnce ( specifier , options ) ;
282+ if ( response ?. kind !== "redirect" ) {
283+ return response ;
284+ }
285+ specifier = new URL ( response . specifier ) ;
286+ }
287+ throw new Deno . errors . Http (
288+ `Too many redirects.\n Specifier: "${ specifier . toString ( ) } "` ,
289+ ) ;
290+ }
291+
292+ async fetchOnce (
286293 specifier : URL ,
287294 options ?: FetchOptions ,
288295 ) : Promise < LoadResponse | undefined > {
@@ -306,9 +313,8 @@ export class FileFetcher {
306313 `A remote specifier was requested: "${ specifier . toString ( ) } ", but --no-remote is specified.` ,
307314 ) ;
308315 } else {
309- const response = await this . #fetchRemote (
316+ const response = await this . #fetchRemoteOnce (
310317 specifier ,
311- 10 ,
312318 this . #resolveOptions( options ) ,
313319 await this . #resolveHttpCache( ) ,
314320 ) ;
0 commit comments