diff --git a/changelog.txt b/changelog.txt index c1c80d5cebe..b2b25ffd3fd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,4 +8,5 @@ * Fixed bug where environment variables are unset for script in `emulators:exec`. * `emulators:exec` script now inherits stdout and stderr. * Improved reliability and performance of project listing for `firebase use` command. -* Fixed bug where `firestore:delete` skips legacy documents with numeric IDs. \ No newline at end of file +* Fixed bug where `firestore:delete` skips legacy documents with numeric IDs. +* Fixed bug in Firestore emulator where it ignored `x-forwarded-host` header. diff --git a/src/emulator/functionsEmulatorRuntime.ts b/src/emulator/functionsEmulatorRuntime.ts index 927d963455b..4510210d3dd 100644 --- a/src/emulator/functionsEmulatorRuntime.ts +++ b/src/emulator/functionsEmulatorRuntime.ts @@ -544,6 +544,7 @@ async function ProcessHTTPS(frb: FunctionsRuntimeBundle, trigger: EmulatedTrigge } }; + ephemeralServer.enable("trust proxy"); ephemeralServer.use(bodyParser.json({})); ephemeralServer.use(bodyParser.text({})); ephemeralServer.use(bodyParser.urlencoded({ extended: true })); diff --git a/src/test/emulators/functionsEmulatorRuntime.spec.ts b/src/test/emulators/functionsEmulatorRuntime.spec.ts index 79f46093a49..c62da255bed 100644 --- a/src/test/emulators/functionsEmulatorRuntime.spec.ts +++ b/src/test/emulators/functionsEmulatorRuntime.spec.ts @@ -571,6 +571,42 @@ describe("FunctionsEmulator-Runtime", () => { await runtime.exit; }).timeout(TIMEOUT_MED); + + it("should handle `x-forwarded-host`", async () => { + const runtime = InvokeRuntimeWithFunctions(FunctionRuntimeBundles.onRequest, () => { + require("firebase-admin").initializeApp(); + return { + function_id: require("firebase-functions").https.onRequest( + async (req: any, res: any) => { + res.json({ hostname: req.hostname }); + } + ), + }; + }); + + await runtime.ready; + await new Promise((resolve) => { + request( + { + socketPath: runtime.metadata.socketPath, + path: "/", + headers: { + "x-forwarded-host": "real-hostname", + }, + }, + (res) => { + let data = ""; + res.on("data", (chunk) => (data += chunk)); + res.on("end", () => { + expect(JSON.parse(data)).to.deep.equal({ hostname: "real-hostname" }); + resolve(); + }); + } + ).end(); + }); + + await runtime.exit; + }).timeout(TIMEOUT_MED); }); describe("Cloud Firestore", () => {