@@ -42,7 +42,10 @@ const {
4242 simpleRangeHeaderValue,
4343 buildContentRange,
4444 createInflate,
45- extractMimeType
45+ extractMimeType,
46+ hasAuthenticationEntry,
47+ includesCredentials,
48+ isTraversableNavigable
4649} = require ( './util' )
4750const assert = require ( 'node:assert' )
4851const { safelyExtractBody, extractBody } = require ( './body' )
@@ -1524,13 +1527,39 @@ async function httpNetworkOrCacheFetch (
15241527
15251528 httpRequest . headersList . delete ( 'host' , true )
15261529
1527- // 20 . If includeCredentials is true, then:
1530+ // 21 . If includeCredentials is true, then:
15281531 if ( includeCredentials ) {
15291532 // 1. If the user agent is not configured to block cookies for httpRequest
15301533 // (see section 7 of [COOKIES]), then:
15311534 // TODO: credentials
1535+
15321536 // 2. If httpRequest’s header list does not contain `Authorization`, then:
1533- // TODO: credentials
1537+ if ( ! httpRequest . headersList . contains ( 'authorization' , true ) ) {
1538+ // 1. Let authorizationValue be null.
1539+ let authorizationValue = null
1540+
1541+ // 2. If there’s an authentication entry for httpRequest and either
1542+ // httpRequest’s use-URL-credentials flag is unset or httpRequest’s
1543+ // current URL does not include credentials, then set
1544+ // authorizationValue to authentication entry.
1545+ if ( hasAuthenticationEntry ( httpRequest ) && (
1546+ httpRequest . useURLCredentials === undefined || ! includesCredentials ( requestCurrentURL ( httpRequest ) )
1547+ ) ) {
1548+ // TODO
1549+ } else if ( includesCredentials ( requestCurrentURL ( httpRequest ) ) && isAuthenticationFetch ) {
1550+ // 3. Otherwise, if httpRequest’s current URL does include credentials
1551+ // and isAuthenticationFetch is true, set authorizationValue to
1552+ // httpRequest’s current URL, converted to an `Authorization` value
1553+ const { username, password } = requestCurrentURL ( httpRequest )
1554+ authorizationValue = `Basic ${ Buffer . from ( `${ username } :${ password } ` ) . toString ( 'base64' ) } `
1555+ }
1556+
1557+ // 4. If authorizationValue is non-null, then append (`Authorization`,
1558+ // authorizationValue) to httpRequest’s header list.
1559+ if ( authorizationValue !== null ) {
1560+ httpRequest . headersList . append ( 'Authorization' , authorizationValue , false )
1561+ }
1562+ }
15341563 }
15351564
15361565 // 21. If there’s a proxy-authentication entry, use it as appropriate.
@@ -1612,10 +1641,48 @@ async function httpNetworkOrCacheFetch (
16121641 // 13. Set response’s request-includes-credentials to includeCredentials.
16131642 response . requestIncludesCredentials = includeCredentials
16141643
1615- // 14. If response’s status is 401, httpRequest’s response tainting is not
1616- // "cors", includeCredentials is true, and request’s window is an environment
1617- // settings object, then:
1618- // TODO
1644+ // 14. If response’s status is 401, httpRequest’s response tainting is not "cors",
1645+ // includeCredentials is true, and request’s traversable for user prompts is
1646+ // a traversable navigable:
1647+ if ( response . status === 401 && httpRequest . responseTainting !== 'cors' && includeCredentials && isTraversableNavigable ( request . traversableForUserPrompts ) ) {
1648+ // 2. If request’s body is non-null, then:
1649+ if ( request . body != null ) {
1650+ // 1. If request’s body’s source is null, then return a network error.
1651+ if ( request . body . source == null ) {
1652+ return makeNetworkError ( 'expected non-null body source' )
1653+ }
1654+
1655+ // 2. Set request’s body to the body of the result of safely extracting
1656+ // request’s body’s source.
1657+ request . body = safelyExtractBody ( request . body . source ) [ 0 ]
1658+ }
1659+
1660+ // 3. If request’s use-URL-credentials flag is unset or isAuthenticationFetch is
1661+ // true, then:
1662+ if ( request . useURLCredentials === undefined || isAuthenticationFetch ) {
1663+ // 1. If fetchParams is canceled, then return the appropriate network error
1664+ // for fetchParams.
1665+ if ( isCancelled ( fetchParams ) ) {
1666+ return makeAppropriateNetworkError ( fetchParams )
1667+ }
1668+
1669+ // 2. Let username and password be the result of prompting the end user for a
1670+ // username and password, respectively, in request’s traversable for user prompts.
1671+ // TODO
1672+
1673+ // 3. Set the username given request’s current URL and username.
1674+ // requestCurrentURL(request).username = TODO
1675+
1676+ // 4. Set the password given request’s current URL and password.
1677+ // requestCurrentURL(request).password = TODO
1678+ }
1679+
1680+ // 4. Set response to the result of running HTTP-network-or-cache fetch given
1681+ // fetchParams and true.
1682+ fetchParams . controller . connection . destroy ( )
1683+
1684+ response = await httpNetworkOrCacheFetch ( fetchParams , true )
1685+ }
16191686
16201687 // 15. If response’s status is 407, then:
16211688 if ( response . status === 407 ) {
0 commit comments