Skip to content

Commit 4920fc4

Browse files
authored
fix fetch 401 loop (#4761)
1 parent c2307d0 commit 4920fc4

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/web/fetch/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,11 @@ async function httpNetworkOrCacheFetch (
16751675

16761676
// 4. Set the password given request’s current URL and password.
16771677
// requestCurrentURL(request).password = TODO
1678+
1679+
// In browsers, the user will be prompted to enter a username/password before the request
1680+
// is re-sent. To prevent an infinite 401 loop, return a network error for now.
1681+
// https://github.com/nodejs/undici/pull/4756
1682+
return makeNetworkError()
16781683
}
16791684

16801685
// 4. Set response to the result of running HTTP-network-or-cache fetch given
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict'
2+
3+
const { fetch } = require('../..')
4+
const { createServer } = require('node:http')
5+
const { once } = require('node:events')
6+
const { test } = require('node:test')
7+
const assert = require('node:assert')
8+
9+
const { closeServerAsPromise } = require('../utils/node-http')
10+
11+
test('Receiving a 401 status code should not cause infinite retry loop', async (t) => {
12+
let requestCount = 0
13+
14+
const server = createServer({ joinDuplicateHeaders: true }, (req, res) => {
15+
requestCount++
16+
console.log({ requestCount })
17+
res.statusCode = 401
18+
res.setHeader('WWW-Authenticate', 'Basic realm="test"')
19+
res.end('Unauthorized')
20+
}).listen(0)
21+
22+
t.after(closeServerAsPromise(server))
23+
await once(server, 'listening')
24+
25+
await assert.rejects(() => fetch(`http://localhost:${server.address().port}`))
26+
})

0 commit comments

Comments
 (0)