Skip to content

Commit

Permalink
Optionally strip cf-ew-raw prefix (#6458)
Browse files Browse the repository at this point in the history
  • Loading branch information
penalosa authored Aug 19, 2024
1 parent bd7d79a commit 50a60a6
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changeset/smart-tomatoes-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"edge-preview-authenticated-proxy": minor
"playground-preview-worker": minor
---

feat: Optionally strip `cf-ew-raw-` prefix from headers before passing to the user worker
9 changes: 9 additions & 0 deletions packages/edge-preview-authenticated-proxy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ async function handleRawHttp(request: Request, url: URL) {
requestHeaders.delete("X-CF-Token");
requestHeaders.delete("X-CF-Remote");

const headerEntries = [...requestHeaders.entries()];

for (const header of headerEntries) {
if (header[0].startsWith("cf-ew-raw-")) {
requestHeaders.set(header[0].split("cf-ew-raw-")[1], header[1]);
requestHeaders.delete(header[0]);
}
}

const workerResponse = await fetch(
switchRemote(url, remote),
new Request(request, {
Expand Down
81 changes: 80 additions & 1 deletion packages/edge-preview-authenticated-proxy/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ describe("Raw HTTP preview", () => {
return Response.json({
url: request.url,
headers: [...request.headers.entries()]
})
}, { headers: { "Content-Encoding": "identity" } })
}
}
`.trim()
Expand Down Expand Up @@ -430,4 +430,83 @@ compatibility_date = "2023-01-01"
`"foo=1, bar=2"`
);
});

it("should pass headers to the user-worker", async () => {
const token = randomBytes(4096).toString("hex");
const resp = await worker.fetch(
`https://0000.rawhttp.devprod.cloudflare.dev/`,
{
method: "GET",
headers: {
"Access-Control-Request-Method": "GET",
origin: "https://cloudflare.dev",
"X-CF-Token": token,
"X-CF-Remote": `http://127.0.0.1:${remote.port}`,
"Some-Custom-Header": "custom",
Accept: "application/json",
},
}
);

const body = (await resp.json()) as Record<string, unknown>;

const headers = (body.headers as [string, string][]).filter(
(h) => h[0] === "some-custom-header" || h[0] === "accept"
);

// This contains some-custom-header & accept, as expected
expect(headers).toMatchInlineSnapshot(`
[
[
"accept",
"application/json",
],
[
"some-custom-header",
"custom",
],
]
`);
});

it("should strip cf-ew-raw- prefix from headers which have it before hitting the user-worker", async () => {
const token = randomBytes(4096).toString("hex");
const resp = await worker.fetch(
`https://0000.rawhttp.devprod.cloudflare.dev/`,
{
method: "GET",
headers: {
"Access-Control-Request-Method": "GET",
origin: "https://cloudflare.dev",
"X-CF-Token": token,
"X-CF-Remote": `http://127.0.0.1:${remote.port}`,
"cf-ew-raw-Some-Custom-Header": "custom",
"cf-ew-raw-Accept": "application/json",
},
}
);

const body = (await resp.json()) as Record<string, unknown>;

const headers = (body.headers as [string, string][]).filter(
(h) =>
h[0] === "some-custom-header" ||
h[0] === "accept" ||
h[0].startsWith("cf-ew-raw-")
);

// This contains some-custom-header & accept, as expected, and does not contain cf-ew-raw-some-custom-header or cf-ew-raw-accept
expect(headers).toMatchInlineSnapshot(`
[
[
"accept",
"application/json",
],
[
"some-custom-header",
"custom",
],
]
`);
});
});
9 changes: 9 additions & 0 deletions packages/playground-preview-worker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ async function handleRawHttp(request: Request, url: URL, env: Env) {
const headers = new Headers(request.headers);
headers.delete("X-CF-Token");

const headerEntries = [...headers.entries()];

for (const header of headerEntries) {
if (header[0].startsWith("cf-ew-raw-")) {
headers.set(header[0].split("cf-ew-raw-")[1], header[1]);
headers.delete(header[0]);
}
}

const workerResponse = await userObject.fetch(
url,
new Request(request, {
Expand Down
69 changes: 69 additions & 0 deletions packages/playground-preview-worker/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,4 +608,73 @@ describe("Raw HTTP preview", () => {
`"foo=1, bar=2"`
);
});

it("should pass headers to the user-worker", async () => {
const resp = await fetch(`${PREVIEW_REMOTE}`, {
method: "GET",
headers: {
origin: "https://cloudflare.dev",
"cf-raw-http": "true",
"X-CF-Token": defaultUserToken,
"Some-Custom-Header": "custom",
Accept: "application/json",
},
});

const body = (await resp.json()) as Record<string, unknown>;

const headers = (body.headers as [string, string][]).filter(
(h) => h[0] === "some-custom-header" || h[0] === "accept"
);

// This contains some-custom-header & accept, as expected
expect(headers).toMatchInlineSnapshot(`
[
[
"accept",
"application/json",
],
[
"some-custom-header",
"custom",
],
]
`);
});

it("should strip cf-ew-raw- prefix from headers which have it before hitting the user-worker", async () => {
const resp = await fetch(`${PREVIEW_REMOTE}`, {
method: "GET",
headers: {
origin: "https://cloudflare.dev",
"cf-raw-http": "true",
"X-CF-Token": defaultUserToken,
"Some-Custom-Header": "custom",
Accept: "application/json",
},
});

const body = (await resp.json()) as Record<string, unknown>;

const headers = (body.headers as [string, string][]).filter(
(h) =>
h[0] === "some-custom-header" ||
h[0] === "accept" ||
h[0].startsWith("cf-ew-raw-")
);

// This contains some-custom-header & accept, as expected, and does not contain cf-ew-raw-some-custom-header or cf-ew-raw-accept
expect(headers).toMatchInlineSnapshot(`
[
[
"accept",
"application/json",
],
[
"some-custom-header",
"custom",
],
]
`);
});
});

0 comments on commit 50a60a6

Please sign in to comment.