diff --git a/.changeset/fix-tcp-regression-connect-pass-through.md b/.changeset/fix-tcp-regression-connect-pass-through.md new file mode 100644 index 000000000000..c462ba6f23f0 --- /dev/null +++ b/.changeset/fix-tcp-regression-connect-pass-through.md @@ -0,0 +1,6 @@ +--- +"miniflare": patch +"wrangler": patch +--- + +Strip the `CF-Connecting-IP` header from outgoing fetches diff --git a/packages/miniflare/src/plugins/core/index.ts b/packages/miniflare/src/plugins/core/index.ts index 07a1c6b65a03..7894ff2435a8 100644 --- a/packages/miniflare/src/plugins/core/index.ts +++ b/packages/miniflare/src/plugins/core/index.ts @@ -163,9 +163,7 @@ const CoreOptionsSchemaInput = z.intersection( unsafeEnableAssetsRpc: z.boolean().optional(), // Strip the CF-Connecting-IP header from outbound fetches - // There is an issue with the connect() API and the globalOutbound workerd setting that impacts TCP ingress - // We should default it to true once https://github.com/cloudflare/workerd/pull/4145 is resolved - stripCfConnectingIp: z.boolean().default(false), + stripCfConnectingIp: z.boolean().default(true), }) ); export const CoreOptionsSchema = CoreOptionsSchemaInput.transform((value) => { @@ -759,6 +757,7 @@ export const CORE_PLUGIN: Plugin< }, ], compatibilityDate: "2025-01-01", + compatibilityFlags: ["connect_pass_through", "experimental"], globalOutbound: getGlobalOutbound(workerIndex, options), }, }); diff --git a/packages/miniflare/test/index.spec.ts b/packages/miniflare/test/index.spec.ts index 5c364e5cd6d8..674e7425050f 100644 --- a/packages/miniflare/test/index.spec.ts +++ b/packages/miniflare/test/index.spec.ts @@ -2715,7 +2715,6 @@ test("Miniflare: strips CF-Connecting-IP", async (t) => { const client = new Miniflare({ script: `export default { fetch(request) { return fetch('${url.href}', {headers: {"CF-Connecting-IP":"fake-value"}}) } }`, modules: true, - stripCfConnectingIp: true, }); t.teardown(() => client.dispose()); t.teardown(() => server.dispose()); diff --git a/packages/wrangler/src/__tests__/api/startDevWorker/startWorker.test.ts b/packages/wrangler/src/__tests__/api/startDevWorker/startWorker.test.ts deleted file mode 100644 index 88cc48988950..000000000000 --- a/packages/wrangler/src/__tests__/api/startDevWorker/startWorker.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import http from "node:http"; -import path from "node:path"; -import dedent from "ts-dedent"; -import { startWorker } from "../../../api/startDevWorker"; -import { runInTempDir } from "../../helpers/run-in-tmp"; -import { seed } from "../../helpers/seed"; - -describe("startWorker", () => { - runInTempDir(); - - // We do not inject the `CF-Connecting-IP` header on Windows at the moment. - // See https://github.com/cloudflare/workerd/issues/3310 - it.skipIf(process.platform === "win32")( - "strips the CF-Connecting-IP header from all outbound requests", - async (t) => { - const server = http.createServer((req, res) => { - res.writeHead(200); - res.end( - req.headers["cf-connecting-ip"] ?? "CF-Connecting-IP header stripped" - ); - }); - - t.onTestFinished(() => { - server.close(); - }); - - const address = server.listen(0).address(); - - if (address === null || typeof address === "string") { - expect.fail("Failed to get server address"); - } - - await seed({ - "src/index.ts": dedent` - export default { - fetch(request) { - if (request.headers.has('CF-Connecting-IP')) { - return fetch(request); - } - - return new Response("No CF-Connecting-IP header"); - } - } - `, - }); - - const worker = await startWorker({ - name: "test-worker", - entrypoint: path.resolve("src/index.ts"), - }); - - t.onTestFinished(() => worker.dispose()); - - const response = await worker.fetch(`http://127.0.0.1:${address.port}`); - await expect(response.text()).resolves.toEqual( - "CF-Connecting-IP header stripped" - ); - } - ); -}); diff --git a/packages/wrangler/src/deployment-bundle/bundle.ts b/packages/wrangler/src/deployment-bundle/bundle.ts index 8f972f94c9b1..72dd75d24912 100644 --- a/packages/wrangler/src/deployment-bundle/bundle.ts +++ b/packages/wrangler/src/deployment-bundle/bundle.ts @@ -304,32 +304,6 @@ export async function bundleWorker( inject.push(checkedFetchFileToInject); } - // We injected the `CF-Connecting-IP` header in the entry worker on Miniflare. - // It used to be stripped by Miniflare, but that caused TCP ingress failures - // because of the global outbound setup. This is a temporary workaround until - // a proper fix is landed in Workerd. - // See https://github.com/cloudflare/workers-sdk/issues/9238 for more details. - if (targetConsumer === "dev" && local) { - const stripCfConnectingIpHeaderFileToInject = path.join( - tmpDir.path, - "strip-cf-connecting-ip-header.js" - ); - - if (!fs.existsSync(stripCfConnectingIpHeaderFileToInject)) { - fs.writeFileSync( - stripCfConnectingIpHeaderFileToInject, - fs.readFileSync( - path.resolve( - getBasePath(), - "templates/strip-cf-connecting-ip-header.js" - ) - ) - ); - } - - inject.push(stripCfConnectingIpHeaderFileToInject); - } - // When multiple workers are running we need some way to disambiguate logs between them. Inject a patched version of `globalThis.console` that prefixes logs with the worker name if (getFlag("MULTIWORKER")) { middlewareToLoad.push({ diff --git a/packages/wrangler/templates/strip-cf-connecting-ip-header.js b/packages/wrangler/templates/strip-cf-connecting-ip-header.js deleted file mode 100644 index a011710ccf80..000000000000 --- a/packages/wrangler/templates/strip-cf-connecting-ip-header.js +++ /dev/null @@ -1,13 +0,0 @@ -function stripCfConnectingIPHeader(input, init) { - const request = new Request(input, init); - request.headers.delete("CF-Connecting-IP"); - return request; -} - -globalThis.fetch = new Proxy(globalThis.fetch, { - apply(target, thisArg, argArray) { - return Reflect.apply(target, thisArg, [ - stripCfConnectingIPHeader.apply(null, argArray), - ]); - }, -});