Skip to content

Commit 5db870f

Browse files
committed
fixup!
- fix code - add tests - minor cleanups in code + tests
1 parent 8a8f9cd commit 5db870f

File tree

3 files changed

+83
-25
lines changed

3 files changed

+83
-25
lines changed

packages/open-next/src/core/routing/middleware.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,18 @@ export async function handleMiddleware(
5454
// We bypass the middleware if the request is internal
5555
if (internalEvent.headers["x-isr"]) return internalEvent;
5656

57-
const protocol = new URL(internalEvent.url).protocol;
57+
// Retrieve the url protocol:
58+
// - In lambda, the url only contains the rawPath and the query - default to https.
59+
// - In cloudflare, the protocol is usually http in dev and https in production.
60+
const protocol = internalEvent.url.startsWith("http://") ? "http:" : "https:";
61+
5862
const host = internalEvent.headers.host
5963
? `${protocol}//${internalEvent.headers.host}`
6064
: "http://localhost:3000";
6165

6266
const initialUrl = new URL(normalizedPath, host);
6367
initialUrl.search = convertToQueryString(query);
6468
const url = initialUrl.toString();
65-
// console.log("url", url, normalizedPath);
6669

6770
const middleware = await middlewareLoader();
6871

@@ -192,7 +195,7 @@ export async function handleMiddleware(
192195
responseHeaders: resHeaders,
193196
url: newUrl,
194197
rawPath: rewritten
195-
? (newUrl ?? internalEvent.rawPath)
198+
? newUrl ?? internalEvent.rawPath
196199
: internalEvent.rawPath,
197200
type: internalEvent.type,
198201
headers: { ...internalEvent.headers, ...reqHeaders },

packages/tests-unit/tests/core/routing/middleware.test.ts

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,25 @@ type PartialEvent = Partial<
4848
> & { body?: string };
4949

5050
function createEvent(event: PartialEvent): InternalEvent {
51-
const [rawPath, qs] = (event.url ?? "/").split("?", 2);
51+
let rawPath: string;
52+
let qs: string;
53+
if (event.url?.startsWith("http")) {
54+
const url = new URL(event.url);
55+
rawPath = url.pathname;
56+
qs = url.search;
57+
} else {
58+
const parts = (event.url ?? "/").split("?", 2);
59+
rawPath = parts[0];
60+
qs = parts[1] ?? "";
61+
}
5262
return {
5363
type: "core",
5464
method: event.method ?? "GET",
5565
rawPath,
5666
url: event.url ?? "/",
5767
body: Buffer.from(event.body ?? ""),
5868
headers: event.headers ?? {},
59-
query: convertFromQueryString(qs ?? ""),
69+
query: convertFromQueryString(qs),
6070
cookies: event.cookies ?? {},
6171
remoteAddress: event.remoteAddress ?? "::1",
6272
};
@@ -70,19 +80,19 @@ beforeEach(() => {
7080
* Ideally these tests would be broken up and tests smaller parts of the middleware rather than the entire function.
7181
*/
7282
describe("handleMiddleware", () => {
73-
it("should bypass middlware for internal requests", async () => {
83+
it("should bypass middleware for internal requests", async () => {
7484
const event = createEvent({
7585
headers: {
7686
"x-isr": "1",
7787
},
7888
});
7989
const result = await handleMiddleware(event, middlewareLoader);
8090

81-
expect(middlewareLoader).not.toBeCalled();
91+
expect(middlewareLoader).not.toHaveBeenCalled();
8292
expect(result).toEqual(event);
8393
});
8494

85-
it("should invoke middlware with redirect", async () => {
95+
it("should invoke middleware with redirect", async () => {
8696
const event = createEvent({});
8797
middleware.mockResolvedValue({
8898
status: 302,
@@ -92,12 +102,12 @@ describe("handleMiddleware", () => {
92102
});
93103
const result = await handleMiddleware(event, middlewareLoader);
94104

95-
expect(middlewareLoader).toBeCalled();
105+
expect(middlewareLoader).toHaveBeenCalled();
96106
expect(result.statusCode).toEqual(302);
97107
expect(result.headers.location).toEqual("/redirect");
98108
});
99109

100-
it("should invoke middlware with external redirect", async () => {
110+
it("should invoke middleware with external redirect", async () => {
101111
const event = createEvent({});
102112
middleware.mockResolvedValue({
103113
status: 302,
@@ -107,12 +117,12 @@ describe("handleMiddleware", () => {
107117
});
108118
const result = await handleMiddleware(event, middlewareLoader);
109119

110-
expect(middlewareLoader).toBeCalled();
120+
expect(middlewareLoader).toHaveBeenCalled();
111121
expect(result.statusCode).toEqual(302);
112122
expect(result.headers.location).toEqual("http://external/redirect");
113123
});
114124

115-
it("should invoke middlware with rewrite", async () => {
125+
it("should invoke middleware with rewrite", async () => {
116126
const event = createEvent({
117127
headers: {
118128
host: "localhost",
@@ -125,7 +135,7 @@ describe("handleMiddleware", () => {
125135
});
126136
const result = await handleMiddleware(event, middlewareLoader);
127137

128-
expect(middlewareLoader).toBeCalled();
138+
expect(middlewareLoader).toHaveBeenCalled();
129139
expect(result).toEqual({
130140
...event,
131141
rawPath: "/rewrite",
@@ -137,7 +147,7 @@ describe("handleMiddleware", () => {
137147
});
138148
});
139149

140-
it("should invoke middlware with rewrite with __nextDataReq", async () => {
150+
it("should invoke middleware with rewrite with __nextDataReq", async () => {
141151
const event = createEvent({
142152
url: "/rewrite?__nextDataReq=1&key=value",
143153
headers: {
@@ -151,7 +161,7 @@ describe("handleMiddleware", () => {
151161
});
152162
const result = await handleMiddleware(event, middlewareLoader);
153163

154-
expect(middlewareLoader).toBeCalled();
164+
expect(middlewareLoader).toHaveBeenCalled();
155165
expect(result).toEqual({
156166
...event,
157167
rawPath: "/rewrite",
@@ -167,7 +177,7 @@ describe("handleMiddleware", () => {
167177
});
168178
});
169179

170-
it("should invoke middlware with external rewrite", async () => {
180+
it("should invoke middleware with external rewrite", async () => {
171181
const event = createEvent({
172182
headers: {
173183
host: "localhost",
@@ -180,7 +190,7 @@ describe("handleMiddleware", () => {
180190
});
181191
const result = await handleMiddleware(event, middlewareLoader);
182192

183-
expect(middlewareLoader).toBeCalled();
193+
expect(middlewareLoader).toHaveBeenCalled();
184194
expect(result).toEqual({
185195
...event,
186196
rawPath: "http://external/rewrite",
@@ -201,7 +211,7 @@ describe("handleMiddleware", () => {
201211
});
202212
const result = await handleMiddleware(event, middlewareLoader);
203213

204-
expect(middlewareLoader).toBeCalled();
214+
expect(middlewareLoader).toHaveBeenCalled();
205215
expect(result).toEqual({
206216
...event,
207217
headers: {
@@ -223,7 +233,7 @@ describe("handleMiddleware", () => {
223233
});
224234
const result = await handleMiddleware(event, middlewareLoader);
225235

226-
expect(middlewareLoader).toBeCalled();
236+
expect(middlewareLoader).toHaveBeenCalled();
227237
expect(result).toEqual({
228238
type: "core",
229239
statusCode: 200,
@@ -246,7 +256,7 @@ describe("handleMiddleware", () => {
246256
});
247257
const result = await handleMiddleware(event, middlewareLoader);
248258

249-
expect(middlewareLoader).toBeCalled();
259+
expect(middlewareLoader).toHaveBeenCalled();
250260
expect(result).toEqual({
251261
type: "core",
252262
statusCode: 200,
@@ -257,4 +267,49 @@ describe("handleMiddleware", () => {
257267
isBase64Encoded: false,
258268
});
259269
});
270+
271+
it("should use the http event protocol when specified", async () => {
272+
const event = createEvent({
273+
url: "http://test.me/path",
274+
headers: {
275+
host: "test.me",
276+
},
277+
});
278+
await handleMiddleware(event, middlewareLoader);
279+
expect(middleware).toHaveBeenCalledWith(
280+
expect.objectContaining({
281+
url: "http://test.me/path",
282+
}),
283+
);
284+
});
285+
286+
it("should use the https event protocol when specified", async () => {
287+
const event = createEvent({
288+
url: "https://test.me/path",
289+
headers: {
290+
host: "test.me/path",
291+
},
292+
});
293+
await handleMiddleware(event, middlewareLoader);
294+
expect(middleware).toHaveBeenCalledWith(
295+
expect.objectContaining({
296+
url: "https://test.me/path",
297+
}),
298+
);
299+
});
300+
301+
it("should default to https protocol", async () => {
302+
const event = createEvent({
303+
url: "/path",
304+
headers: {
305+
host: "test.me",
306+
},
307+
});
308+
await handleMiddleware(event, middlewareLoader);
309+
expect(middleware).toHaveBeenCalledWith(
310+
expect.objectContaining({
311+
url: "https://test.me/path",
312+
}),
313+
);
314+
});
260315
});

packages/tests-unit/tests/core/routing/util.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ describe("getUrlParts", () => {
146146

147147
describe("external", () => {
148148
it("throws for empty url", () => {
149-
expect(() => getUrlParts("", true)).toThrowError();
149+
expect(() => getUrlParts("", true)).toThrow();
150150
});
151151

152152
it("throws for invalid url", () => {
153-
expect(() => getUrlParts("/relative", true)).toThrowError();
153+
expect(() => getUrlParts("/relative", true)).toThrow();
154154
});
155155

156156
it("returns url parts for /", () => {
@@ -581,7 +581,7 @@ describe("revalidateIfRequired", () => {
581581
const headers: Record<string, string> = {};
582582
await revalidateIfRequired("localhost", "/path", headers);
583583

584-
expect(sendMock).not.toBeCalled();
584+
expect(sendMock).not.toHaveBeenCalled();
585585
});
586586

587587
it("should send to queue when x-nextjs-cache is STALE", async () => {
@@ -590,7 +590,7 @@ describe("revalidateIfRequired", () => {
590590
};
591591
await revalidateIfRequired("localhost", "/path", headers);
592592

593-
expect(sendMock).toBeCalledWith({
593+
expect(sendMock).toHaveBeenCalledWith({
594594
MessageBody: { host: "localhost", url: "/path" },
595595
MessageDeduplicationId: expect.any(String),
596596
MessageGroupId: expect.any(String),
@@ -604,7 +604,7 @@ describe("revalidateIfRequired", () => {
604604
sendMock.mockRejectedValueOnce(new Error("Failed to send"));
605605
await revalidateIfRequired("localhost", "/path", headers);
606606

607-
expect(sendMock).toBeCalledWith({
607+
expect(sendMock).toHaveBeenCalledWith({
608608
MessageBody: { host: "localhost", url: "/path" },
609609
MessageDeduplicationId: expect.any(String),
610610
MessageGroupId: expect.any(String),

0 commit comments

Comments
 (0)