fix(proxy-pools): lossless header forwarding for relay pools
Preserve request headers through the Vercel/Cloudflare/Deno relay.
- proxyFetch: normalize options.headers via Object.fromEntries before
spreading into the relay headers. Spreading a Headers instance yields
{} and silently dropped every entry (auth + content-type), which is why
the same pool worked on one path and failed on another.
- vercel relay: build the forwarded header object from req.headers.entries()
instead of new Headers(req.headers), avoiding edge-runtime normalization
of casing/duplicate keys that some providers reject.
This commit is contained in:
@@ -298,8 +298,11 @@ export async function proxyAwareFetch(url, options = {}, proxyOptions = null) {
|
|||||||
const vercelRelayUrl = normalizeString(proxyOptions?.vercelRelayUrl);
|
const vercelRelayUrl = normalizeString(proxyOptions?.vercelRelayUrl);
|
||||||
if (vercelRelayUrl) {
|
if (vercelRelayUrl) {
|
||||||
const parsed = new URL(targetUrl);
|
const parsed = new URL(targetUrl);
|
||||||
|
const baseHeaders = options.headers instanceof Headers
|
||||||
|
? Object.fromEntries(options.headers.entries())
|
||||||
|
: { ...(options.headers || {}) };
|
||||||
const relayHeaders = {
|
const relayHeaders = {
|
||||||
...options.headers,
|
...baseHeaders,
|
||||||
"x-relay-target": `${parsed.protocol}//${parsed.host}`,
|
"x-relay-target": `${parsed.protocol}//${parsed.host}`,
|
||||||
"x-relay-path": `${parsed.pathname}${parsed.search}`,
|
"x-relay-path": `${parsed.pathname}${parsed.search}`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,14 +20,15 @@ export default async function handler(req) {
|
|||||||
|
|
||||||
const targetUrl = target.replace(/\\/$/, "") + relayPath;
|
const targetUrl = target.replace(/\\/$/, "") + relayPath;
|
||||||
|
|
||||||
const headers = new Headers(req.headers);
|
const rawHeaders = {};
|
||||||
headers.delete("x-relay-target");
|
for (const [k, v] of req.headers.entries()) rawHeaders[k] = v;
|
||||||
headers.delete("x-relay-path");
|
delete rawHeaders["x-relay-target"];
|
||||||
headers.delete("host");
|
delete rawHeaders["x-relay-path"];
|
||||||
|
delete rawHeaders["host"];
|
||||||
|
|
||||||
const response = await fetch(targetUrl, {
|
const response = await fetch(targetUrl, {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
headers,
|
headers: rawHeaders,
|
||||||
body: req.method !== "GET" && req.method !== "HEAD" ? req.body : undefined,
|
body: req.method !== "GET" && req.method !== "HEAD" ? req.body : undefined,
|
||||||
duplex: "half",
|
duplex: "half",
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user