oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.28k stars 2.77k forks source link

fetch don't follow 302/308 correctly #15150

Open Leechael opened 2 days ago

Leechael commented 2 days ago

What version of Bun is running?

1.1.34

Hint: the issue occurs after 1.1.24.

What platform is your computer?

No response

What steps can reproduce the bug?

The fetch implementation in Bun does not fully handle 302 and 308 status codes correctly.

When we runs a script that more then 256 redirect rquests, which the default value of BUN_CONFIG_MAX_HTTP_REQUESTS, the script will hung up. It looks like ran out of MAX HTTP REQUESTS.

Here is the snapshot of reproduce scripts & output:

❯ cat test.ts 
const resp = await fetch('http://www.diamondcabinets.com/')
console.log(resp.status)

❯ BUN_CONFIG_VERBOSE_FETCH=curl timeout 60s bun run test.ts || echo "Error: Command timed out after 60 seconds"
[fetch] $ curl --http1.1 "http://www.diamondcabinets.com/" -H "Connection: keep-alive" -H "User-Agent: Bun/1.1.34" -H "Accept: */*" -H "Host: www.diamondcabinets.com" -H "Accept-Encoding: gzip, deflate, br" --compressed
[fetch] > HTTP/1.1 GET http://www.diamondcabinets.com/
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.1.34
[fetch] > Accept: */*
[fetch] > Host: www.diamondcabinets.com
[fetch] > Accept-Encoding: gzip, deflate, br

[fetch] < 302 Redirect
[fetch] < Connection: Close
[fetch] < Location: https://www.diamondcabinets.com:443/

Error: Command timed out after 60 seconds

❯ cat test.ts
const resp = await fetch('http://aquaticbath.com/')
console.log(resp.status)

❯ BUN_CONFIG_VERBOSE_FETCH=curl timeout 60s bun run test.ts || echo "Error: Command timed out after 60 seconds"
[fetch] $ curl --http1.1 "http://aquaticbath.com/" -H "Connection: keep-alive" -H "User-Agent: Bun/1.1.34" -H "Accept: */*" -H "Host: aquaticbath.com" -H "Accept-Encoding: gzip, deflate, br" --compressed
[fetch] > HTTP/1.1 GET http://aquaticbath.com/
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.1.34
[fetch] > Accept: */*
[fetch] > Host: aquaticbath.com
[fetch] > Accept-Encoding: gzip, deflate, br

[fetch] < 308 Permanent Redirect
[fetch] < Content-Type: text/plain
[fetch] < Location: https://aquaticbath.com/
[fetch] < Refresh: 0;url=https://aquaticbath.com/
[fetch] < server: Vercel

Error: Command timed out after 60 seconds

What is the expected behavior?

To avoid this error, use fetch(url, { redirect: "manual" }). The default behavior is redirect: follow, which can lead to unexpected issues widely.

What do you see instead?

No response

Additional information

No response

Leechael commented 2 days ago

Is there an API that provides the current HTTP request count, allowing us to set BUN_CONFIG_MAX_HTTP_REQUESTS more accurately?