cloudflare / miniflare

🔥 Fully-local simulator for Cloudflare Workers. For the latest version, see https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare.
https://miniflare.dev
MIT License
3.78k stars 205 forks source link

Host header customization for upstream #692

Closed oxcafedead closed 1 year ago

oxcafedead commented 1 year ago

Hi. I have Miniflare with HTTPS enabled, acting like a 'local Cloudflare' before my local 'origin', to emulate my production worker. The worker itself acts like a proxy with some non-important logic, like adding new cookies/headers. The local setup is:

browser -> miniflare (localhost, 443) -> web_server (localhost, 8443)

Production:

browser -> cloudflare (site.com, 443) -> tunnel -> web_server (internal.host, 80)

In production, web_server receives HTTP requests with Host header set to site.com. Locally, the behavior is different: web_server receives requests with Host header localhost:8443. My expectation was it should receive requests with Host header localhost It does not allow my origin to build correct redirect links. Can you advise if this is something which can be fixed at miniflare level (e.g. new config option)?

My current config:

const mf = new Miniflare({
    name,
    bindings,
    httpsKeyPath,
    httpsCertPath,
    host: "localhost",
    port: 443,
    scriptPath: "dist/bundle.js",
    modules: true,
    kvNamespaces,
    durableObjects,
    verbose: true,
    routes: [ "localhost/*" ],
    upstream: "https://localhost:8443",
    log: new Log(LogLevel.VERBOSE),
});

Miniflare is v3

Or I am completely wrong and there is some obvious way to do it right which I missed?

oxcafedead commented 1 year ago

I guess, the workaround can be to explicitly (manually, in the worker code) set x-forwarded-host header. And a web-server must respect this header.... So, I am not sure my issue is valid. Despite most common reverse proxies' behavior is different: nginx, HAproxy, Traefik - but - Miniflare does not position itself as a reverse proxy, so I'm not sure if is a valuable idea at all

Please close it if you think it's useless. Thanks!

mrbbot commented 1 year ago

Hey! 👋 I think this behaviour is correct. MDN states the Host header "specifies the host and port of the server to which the request is being sent". If you didn't want to set X-Forwarded-Host in your worker, you could consider using the outboundService option...

import { fetch } from "miniflare";

new Miniflare({
  outboundService(request) {
    const url = new URL(request.url);
    if (url.host === "localhost:8443") request.headers.set("X-Forwarded-Host", ...);
    return fetch(request);
  }
})