Skip to content

Commit

Permalink
fixup! fix: ensure we do not rewrite external Origin headers in wrang…
Browse files Browse the repository at this point in the history
…ler dev
  • Loading branch information
petebacondarwin committed Feb 9, 2024
1 parent ee8af06 commit 0e5e856
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
3 changes: 2 additions & 1 deletion fixtures/worker-app/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export default {
async fetch(request) {
console.log("request log");

const { pathname } = new URL(request.url);
const { pathname, origin } = new URL(request.url);
if (pathname === "/random") return new Response(hexEncode(randomBytes(8)));
if (pathname === "/error") throw new Error("Oops!");
if (pathname === "/redirect") return Response.redirect(`${origin}/foo`);
if (request.headers.get("X-Test-URL") !== null) {
return new Response(request.url);
}
Expand Down
15 changes: 15 additions & 0 deletions fixtures/worker-app/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,19 @@ describe("'wrangler dev' correctly renders pages", () => {
expect(text).toContain(`HOST:prod.example.org`);
expect(text).toContain(`ORIGIN:http://foo.com`);
});

it("rewrites response headers containing the emulated host", async ({
expect,
}) => {
// This /redirect request will add a Location header that points to prod.example.com/foo
// But we should rewrite this back to that of the proxy.
const response = await fetch(`http://${ip}:${port}/redirect`, {
redirect: "manual",
});
expect(response.status).toBe(302);
expect(await response.text()).toEqual("");
expect(response.headers.get("Location")).toEqual(
`http://${ip}:${port}/foo`
);
});
});
5 changes: 4 additions & 1 deletion packages/wrangler/templates/startDevWorker/ProxyWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ export class ProxyWorker implements DurableObject {
// explicitly NOT await-ing this promise, we are in a loop and want to process the whole queue quickly + synchronously
void fetch(userWorkerUrl, new Request(request, { headers }))
.then((res) => {
rewriteUrlRelatedHeaders(headers, innerUrl, outerUrl);
res = new Response(res.body, res);
rewriteUrlRelatedHeaders(res.headers, innerUrl, outerUrl);

if (isHtmlResponse(res)) {
res = insertLiveReloadScript(request, res, this.env, proxyData);
Expand Down Expand Up @@ -305,10 +306,12 @@ function insertLiveReloadScript(
function rewriteUrlRelatedHeaders(headers: Headers, from: URL, to: URL) {
headers.forEach((value, key) => {
if (typeof value === "string" && value.includes(from.host)) {
console.log("updating", key, value);
headers.set(
key,
value.replaceAll(from.origin, to.origin).replaceAll(from.host, to.host)
);
console.log("updated", key, headers.get(key));
}
});
}

0 comments on commit 0e5e856

Please sign in to comment.