fix: avoid endless loop with http redirections
Massimo Melina committed
Nov 6, 2024 at 22:56 UTC
e625fc0f10bd10980d1f8060971e7b46b92b4dc6
1 file changed
+11
-2
src/util-http.ts
+11
-2
@@ -5,6 +5,7 @@ import http, { IncomingMessage } from 'node:http'
5
import { Readable } from 'node:stream'
6
import _ from 'lodash'
7
import { text as stream2string, buffer } from 'node:stream/consumers'
8
+import { stringAfter } from './cross'
9
export { stream2string }
10
11
export async function httpString(url: string, options?: XRequestOptions): Promise<string> {
@@ -54,8 +55,16 @@ export function httpStream(url: string, { body, jar, noRedirect, httpThrow, ...o
55
}
56
if (!res.statusCode || (httpThrow ?? true) && res.statusCode >= 400)
57
return reject(new Error(String(res.statusCode), { cause: res }))
57
- if (res.headers.location && !noRedirect)
58
- return resolve(httpStream(res.headers.location, options))
58
+ let r = res.headers.location
59
+ if (r && !noRedirect) {
60
+ if (r.startsWith('/')) // relative
61
+ r = /(.+)\b\/(\b|$)/.exec(url)?.[1] + r
62
+ const stack = ((options as any)._stack ||= [])
63
+ if (stack.length > 20 || stack.includes(r))
64
+ return reject(new Error('endless http redirection'))
65
+ stack.push(r)
66
+ return resolve(httpStream(r, options))
67
+ }
68
resolve(res)
69
}).on('error', e => {
70
reject((req as any).res || e)