Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit f31b693

Browse files
authored
Merge branch 'master' into bump/selfsigned
2 parents 07ee120 + 92d98c9 commit f31b693

File tree

20 files changed

+266
-110
lines changed

20 files changed

+266
-110
lines changed

docs/docs-config.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ module.exports = {
2323
},
2424
],
2525
search: {
26-
// apiKey: "f0ffcd9dba78827de321d7fce21a8181",
27-
// indexName: "miniflare",
28-
apiKey: "",
29-
indexName: "",
26+
// TODO: migrate to https://docsearch.algolia.com/docs/migrating-from-legacy/
27+
// appId: AYF9TLWKTY
28+
// apiKey: fd375d87d44c5b94352fa1ddd580ebdc
29+
// indexName: miniflare
30+
apiKey: "f0ffcd9dba78827de321d7fce21a8181",
31+
indexName: "miniflare",
3032
algoliaOptions: {},
3133
},
3234
siteMetadata: {

package-lock.json

Lines changed: 4 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"dependencies": {
4141
"@iarna/toml": "^2.2.5",
4242
"@miniflare/shared": "2.0.0",
43+
"@miniflare/watcher": "2.0.0",
4344
"busboy": "^0.3.1",
4445
"dotenv": "^10.0.0",
4546
"kleur": "^4.1.4",
@@ -54,13 +55,5 @@
5455
"@types/busboy": "^0.3.1",
5556
"@types/set-cookie-parser": "^2.4.1",
5657
"dequal": "^2.0.2"
57-
},
58-
"peerDependencies": {
59-
"@miniflare/watcher": "2.0.0"
60-
},
61-
"peerDependenciesMeta": {
62-
"@miniflare/watcher": {
63-
"optional": true
64-
}
6558
}
6659
}

packages/core/src/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ export class MiniflareCore<
862862
}
863863
if (watchedPaths.size > 0) {
864864
this.#ctx.log.debug(`Watching ${pathsToString(newWatchPaths)}...`);
865-
await watcher.watch(watchedPaths);
865+
watcher.watch(watchedPaths);
866866
}
867867
this.#previousWatchPaths = newWatchPaths;
868868
}
@@ -1012,15 +1012,16 @@ export class MiniflareCore<
10121012
}
10131013

10141014
// If upstream set, and the request URL doesn't begin with it, rewrite it
1015+
// so fetching the incoming request gets a response from the upstream
10151016
const { upstreamURL } = this.#instances!.CorePlugin;
10161017
if (upstreamURL && !url.toString().startsWith(upstreamURL.toString())) {
10171018
let path = url.pathname + url.search;
10181019
// Remove leading slash so we resolve relative to upstream's path
10191020
if (path.startsWith("/")) path = path.substring(1);
10201021
const newURL = new URL(path, upstreamURL);
10211022
request = new Request(newURL, request);
1022-
// Make sure Host header is correct
1023-
request.headers.set("host", upstreamURL.host);
1023+
// We don't set the Host header here, fetch will automatically set it
1024+
// based on the request url
10241025
}
10251026

10261027
// Each fetch gets its own context (e.g. 50 subrequests).

packages/core/src/plugins/build.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ export class BuildPlugin extends Plugin<BuildOptions> implements BuildOptions {
3939
@Option({
4040
type: OptionType.ARRAY,
4141
description: "Directory to watch for rebuilding on changes",
42-
fromWrangler: ({ build }) => {
43-
if (build?.watch_dir) return [build.watch_dir];
42+
fromWrangler: ({ build, miniflare }) => {
43+
const watchPaths = miniflare?.build_watch_dirs ?? [];
44+
if (build?.watch_dir) watchPaths.push(build.watch_dir);
45+
if (watchPaths.length) return watchPaths;
46+
47+
// If build command set and no paths set, fallback to watching "src"
4448
if (build?.command) return ["src"];
4549
},
4650
})

packages/core/src/standards/http.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,31 @@ Headers.prototype.getAll = function (key: string): string[] {
120120
return value ? splitCookiesString(value) : [];
121121
};
122122

123+
/** @internal */
124+
export function _headersFromIncomingRequest(
125+
req: http.IncomingMessage
126+
): Headers {
127+
const headers = new Headers();
128+
for (const [name, values] of Object.entries(req.headers)) {
129+
// These headers are unsupported in undici fetch requests, they're added
130+
// automatically
131+
if (
132+
name === "transfer-encoding" ||
133+
name === "connection" ||
134+
name === "keep-alive" ||
135+
name === "expect"
136+
) {
137+
continue;
138+
}
139+
if (Array.isArray(values)) {
140+
for (const value of values) headers.append(name, value);
141+
} else if (values !== undefined) {
142+
headers.append(name, values);
143+
}
144+
}
145+
return headers;
146+
}
147+
123148
// Instead of subclassing our customised Request and Response classes from
124149
// BaseRequest and BaseResponse, we instead compose them and implement the same
125150
// interface.
@@ -630,6 +655,19 @@ export function _getURLList(res: BaseResponse): URL[] | undefined {
630655
return res[fetchSymbols.kState]?.urlList;
631656
}
632657

658+
/** @internal */
659+
export function _getBodyLength(
660+
res: Response | BaseResponse
661+
): number | undefined {
662+
// Extract the actual body length of the Response body. Cloudflare will return
663+
// this for the Content-Length header instead of the user specified value
664+
// if its set. When the body is a stream, it's the user's responsibility to
665+
// set the Content-Length header if they want to.
666+
if (res instanceof Response) res = res[_kInner];
667+
// @ts-expect-error symbol properties are not included in type definitions
668+
return res[fetchSymbols.kState]?.body?.length ?? undefined; // (normalise nullish to undefined)
669+
}
670+
633671
/** @internal */
634672
export const _kLoopHeader = "MF-Loop";
635673

packages/core/src/standards/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from "./domexception";
44
export * from "./encoding";
55
export * from "./event";
66
export {
7+
_headersFromIncomingRequest,
78
_kInner,
89
_isByteStream,
910
Body,
@@ -14,6 +15,7 @@ export {
1415
Response,
1516
withWaitUntil,
1617
_getURLList,
18+
_getBodyLength,
1719
_kLoopHeader,
1820
fetch,
1921
_urlFromRequestInput,

packages/core/test/index.mounts.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ test("MiniflareCore: uses original protocol and host when matching mount routes"
467467
async (res) => resolve(await text(res))
468468
);
469469
});
470-
t.is(body, "https://example.com/a:example.com");
470+
t.is(body, "https://example.com/a:custom.mf");
471471
});
472472

473473
// Shared storage persistence tests

packages/core/test/index.spec.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
triggerPromise,
4242
useMiniflare,
4343
useMiniflareWithHandler,
44+
useServer,
4445
useTmp,
4546
utf8Decode,
4647
utf8Encode,
@@ -1087,17 +1088,29 @@ test("MiniflareCore: dispatchFetch: rewrites url to match upstream if different"
10871088
new globals.Response(`${req.url}:${req.headers.get("host")}`)
10881089
);
10891090
// Check url and host header are correct
1090-
let res = await mf.dispatchFetch("http://localhost/a");
1091-
t.is(await res.text(), "https://miniflare.dev/a:miniflare.dev");
1091+
const init: RequestInit = { headers: { host: "localhost" } };
1092+
let res = await mf.dispatchFetch("http://localhost/a", init);
1093+
t.is(await res.text(), "https://miniflare.dev/a:localhost");
10921094

10931095
// Check includes query string
1094-
res = await mf.dispatchFetch("http://localhost/a?b=c");
1095-
t.is(await res.text(), "https://miniflare.dev/a?b=c:miniflare.dev");
1096+
res = await mf.dispatchFetch("http://localhost/a?b=c", init);
1097+
t.is(await res.text(), "https://miniflare.dev/a?b=c:localhost");
10961098

10971099
// Check includes subpath
10981100
await mf.setOptions({ upstream: "https://miniflare.dev/subpath/" });
1099-
res = await mf.dispatchFetch("http://localhost/a");
1100-
t.is(await res.text(), "https://miniflare.dev/subpath/a:miniflare.dev");
1101+
res = await mf.dispatchFetch("http://localhost/a", init);
1102+
t.is(await res.text(), "https://miniflare.dev/subpath/a:localhost");
1103+
});
1104+
test("MiniflareCore: dispatchFetch: fetching incoming request responds with upstream", async (t) => {
1105+
const upstream = (await useServer(t, (req, res) => res.end("upstream"))).http;
1106+
const mf = useMiniflareWithHandler(
1107+
{},
1108+
{ upstream: upstream.toString() },
1109+
(globals, req) => globals.fetch(req)
1110+
);
1111+
// Host should be rewritten to match upstream
1112+
const res = await mf.dispatchFetch("https://random.mf/");
1113+
t.is(await res.text(), "upstream");
11011114
});
11021115
test("MiniflareCore: dispatchFetch: request gets immutable headers", async (t) => {
11031116
const mf = useMiniflareWithHandler({}, {}, (globals, req) => {

packages/core/test/plugins/build.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,14 @@ test("BuildPlugin: parses options from wrangler config", (t) => {
6262
cwd: "cwd",
6363
watch_dir: "source",
6464
},
65+
miniflare: {
66+
build_watch_dirs: ["source1", "source2"],
67+
},
6568
});
6669
t.deepEqual(options, {
6770
buildCommand: "npm run build",
6871
buildBasePath: "cwd",
69-
buildWatchPaths: ["source"],
72+
buildWatchPaths: ["source1", "source2", "source"],
7073
});
7174
// Check buildWatchPaths defaults to "src" if any command specified
7275
options = parsePluginWranglerConfig(BuildPlugin, {

0 commit comments

Comments
 (0)