fix: use callable .get to detect Headers in pickRequestHost
This commit is contained in:
@@ -111,6 +111,16 @@ describe('pickRequestHost', () => {
|
|||||||
it('lower-cases the result', () => {
|
it('lower-cases the result', () => {
|
||||||
expect(pickRequestHost(mockHeaders({ host: 'EXAMPLE.com' }))).toBe('example.com');
|
expect(pickRequestHost(mockHeaders({ host: 'EXAMPLE.com' }))).toBe('example.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles a ReadonlyHeaders-shaped object with an internal `headers` field', () => {
|
||||||
|
// `await headers()` returns Next's ReadonlyHeaders, which exposes `.get`
|
||||||
|
// directly but also carries an internal `headers` property. Ensure we use
|
||||||
|
// its own `.get` rather than descending into `.headers` (#585).
|
||||||
|
const readonlyLike = Object.assign(mockHeaders({ host: 'ro.example.com' }), {
|
||||||
|
headers: { notCallable: true },
|
||||||
|
});
|
||||||
|
expect(pickRequestHost(readonlyLike as unknown as Headers)).toBe('ro.example.com');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('matchDomainBranding', () => {
|
describe('matchDomainBranding', () => {
|
||||||
|
|||||||
@@ -113,7 +113,15 @@ type HeadersLike = Headers | { get(name: string): string | null };
|
|||||||
* host header is set.
|
* host header is set.
|
||||||
*/
|
*/
|
||||||
export function pickRequestHost(headersOrReq: NextRequest | HeadersLike): string | null {
|
export function pickRequestHost(headersOrReq: NextRequest | HeadersLike): string | null {
|
||||||
const headers: HeadersLike = 'headers' in headersOrReq ? (headersOrReq as NextRequest).headers : headersOrReq;
|
// A Headers / ReadonlyHeaders exposes `.get` directly; a NextRequest carries
|
||||||
|
// its headers under `.headers`. Discriminate on the callable `.get` rather
|
||||||
|
// than the presence of a `headers` property, since ReadonlyHeaders (returned
|
||||||
|
// by `await headers()`) also has an internal `headers` field (#585).
|
||||||
|
const candidate = headersOrReq as { get?: unknown };
|
||||||
|
const headers: HeadersLike =
|
||||||
|
typeof candidate.get === 'function'
|
||||||
|
? (headersOrReq as HeadersLike)
|
||||||
|
: (headersOrReq as NextRequest).headers;
|
||||||
const raw = headers.get('x-forwarded-host') || headers.get('host');
|
const raw = headers.get('x-forwarded-host') || headers.get('host');
|
||||||
if (!raw) return null;
|
if (!raw) return null;
|
||||||
const first = raw.split(',')[0]?.trim();
|
const first = raw.split(',')[0]?.trim();
|
||||||
|
|||||||
Reference in New Issue
Block a user