Skip to content

Commit 2fd9883

Browse files
committed
fix middleware not using the initial query
1 parent e5484ac commit 2fd9883

File tree

3 files changed

+49
-30
lines changed

3 files changed

+49
-30
lines changed

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

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,8 @@ import type { InternalEvent, InternalResult } from "types/open-next.js";
1010
import { emptyReadableStream } from "utils/stream.js";
1111

1212
import { localizePath } from "./i18n/index.js";
13-
//NOTE: we should try to avoid importing stuff from next as much as possible
14-
// every release of next could break this
15-
// const { run } = require("next/dist/server/web/sandbox");
16-
// const { getCloneableBody } = require("next/dist/server/body-streams");
17-
// const {
18-
// signalFromNodeResponse,
19-
// } = require("next/dist/server/web/spec-extension/adapters/next-request");
2013
import {
2114
convertBodyToReadableStream,
22-
convertToQueryString,
2315
getMiddlewareMatch,
2416
isExternal,
2517
} from "./util.js";
@@ -45,14 +37,16 @@ function defaultMiddlewareLoader() {
4537
return import("./middleware.mjs");
4638
}
4739

48-
// NOTE: As of Nextjs 13.4.13+, the middleware is handled outside the next-server.
49-
// OpenNext will run the middleware in a sandbox and set the appropriate req headers
50-
// and res.body prior to processing the next-server.
51-
// @returns undefined | res.end()
52-
53-
// if res.end() is return, the parent needs to return and not process next server
40+
/**
41+
*
42+
* @param internalEvent the internal event
43+
* @param initialSearch the initial query string as it was received in the handler
44+
* @param middlewareLoader Only used for unit test
45+
* @returns `Promise<MiddlewareEvent | InternalResult>`
46+
*/
5447
export async function handleMiddleware(
5548
internalEvent: InternalEvent,
49+
initialSearch: string,
5650
middlewareLoader: MiddlewareLoader = defaultMiddlewareLoader,
5751
): Promise<MiddlewareEvent | InternalResult> {
5852
const headers = internalEvent.headers;
@@ -73,7 +67,7 @@ export async function handleMiddleware(
7367
if (!hasMatch) return internalEvent;
7468

7569
const initialUrl = new URL(normalizedPath, internalEvent.url);
76-
initialUrl.search = convertToQueryString(internalEvent.query);
70+
initialUrl.search = initialSearch;
7771
const url = initialUrl.href;
7872

7973
const middleware = await middlewareLoader();

packages/open-next/src/core/routingHandler.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,13 @@ export default async function routingHandler(
100100
return redirect;
101101
}
102102

103-
const eventOrResult = await handleMiddleware(internalEvent);
103+
const eventOrResult = await handleMiddleware(
104+
internalEvent,
105+
// We need to pass the initial search without any decoding
106+
// TODO: we'd need to refactor InternalEvent to include the initial querystring directly
107+
// Should be done in another PR because it is a breaking change
108+
new URL(event.url).search,
109+
);
104110
const isResult = "statusCode" in eventOrResult;
105111
if (isResult) {
106112
return eventOrResult;

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

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe("handleMiddleware", () => {
8484
"x-prerender-revalidate": "preview",
8585
},
8686
});
87-
const result = await handleMiddleware(event, middlewareLoader);
87+
const result = await handleMiddleware(event, "", middlewareLoader);
8888

8989
expect(middlewareLoader).not.toHaveBeenCalled();
9090
expect(result).toEqual(event);
@@ -103,7 +103,7 @@ describe("handleMiddleware", () => {
103103
location: "/redirect",
104104
}),
105105
});
106-
const result = await handleMiddleware(event, middlewareLoader);
106+
const result = await handleMiddleware(event, "", middlewareLoader);
107107

108108
expect(middlewareLoader).toHaveBeenCalled();
109109
expect(result.statusCode).toEqual(302);
@@ -122,7 +122,7 @@ describe("handleMiddleware", () => {
122122
location: "/redirect",
123123
}),
124124
});
125-
const result = await handleMiddleware(event, middlewareLoader);
125+
const result = await handleMiddleware(event, "", middlewareLoader);
126126

127127
expect(middlewareLoader).toHaveBeenCalled();
128128
expect(result.statusCode).toEqual(302);
@@ -137,7 +137,7 @@ describe("handleMiddleware", () => {
137137
location: "/redirect",
138138
}),
139139
});
140-
const result = await handleMiddleware(event, middlewareLoader);
140+
const result = await handleMiddleware(event, "", middlewareLoader);
141141

142142
expect(middlewareLoader).toHaveBeenCalled();
143143
expect(result.statusCode).toEqual(302);
@@ -152,7 +152,7 @@ describe("handleMiddleware", () => {
152152
location: "http://external/redirect",
153153
}),
154154
});
155-
const result = await handleMiddleware(event, middlewareLoader);
155+
const result = await handleMiddleware(event, "", middlewareLoader);
156156

157157
expect(middlewareLoader).toHaveBeenCalled();
158158
expect(result.statusCode).toEqual(302);
@@ -170,7 +170,7 @@ describe("handleMiddleware", () => {
170170
"x-middleware-rewrite": "http://localhost/rewrite",
171171
}),
172172
});
173-
const result = await handleMiddleware(event, middlewareLoader);
173+
const result = await handleMiddleware(event, "", middlewareLoader);
174174

175175
expect(middlewareLoader).toHaveBeenCalled();
176176
expect(result).toEqual({
@@ -196,7 +196,7 @@ describe("handleMiddleware", () => {
196196
"x-middleware-rewrite": "http://localhost/rewrite?newKey=value",
197197
}),
198198
});
199-
const result = await handleMiddleware(event, middlewareLoader);
199+
const result = await handleMiddleware(event, "", middlewareLoader);
200200

201201
expect(middlewareLoader).toHaveBeenCalled();
202202
expect(result).toEqual({
@@ -225,7 +225,7 @@ describe("handleMiddleware", () => {
225225
"x-middleware-rewrite": "http://external/rewrite",
226226
}),
227227
});
228-
const result = await handleMiddleware(event, middlewareLoader);
228+
const result = await handleMiddleware(event, "", middlewareLoader);
229229

230230
expect(middlewareLoader).toHaveBeenCalled();
231231
expect(result).toEqual({
@@ -246,7 +246,7 @@ describe("handleMiddleware", () => {
246246
"x-middleware-request-custom-header": "value",
247247
}),
248248
});
249-
const result = await handleMiddleware(event, middlewareLoader);
249+
const result = await handleMiddleware(event, "", middlewareLoader);
250250

251251
expect(middlewareLoader).toHaveBeenCalled();
252252
expect(result).toEqual({
@@ -268,7 +268,7 @@ describe("handleMiddleware", () => {
268268
headers: new Headers(),
269269
body,
270270
});
271-
const result = await handleMiddleware(event, middlewareLoader);
271+
const result = await handleMiddleware(event, "", middlewareLoader);
272272

273273
expect(middlewareLoader).toHaveBeenCalled();
274274
expect(result).toEqual({
@@ -291,7 +291,7 @@ describe("handleMiddleware", () => {
291291
}),
292292
body,
293293
});
294-
const result = await handleMiddleware(event, middlewareLoader);
294+
const result = await handleMiddleware(event, "", middlewareLoader);
295295

296296
expect(middlewareLoader).toHaveBeenCalled();
297297
expect(result).toEqual({
@@ -312,7 +312,7 @@ describe("handleMiddleware", () => {
312312
host: "test.me",
313313
},
314314
});
315-
await handleMiddleware(event, middlewareLoader);
315+
await handleMiddleware(event, "", middlewareLoader);
316316
expect(middleware).toHaveBeenCalledWith(
317317
expect.objectContaining({
318318
url: "http://test.me/path",
@@ -327,7 +327,7 @@ describe("handleMiddleware", () => {
327327
host: "test.me/path",
328328
},
329329
});
330-
await handleMiddleware(event, middlewareLoader);
330+
await handleMiddleware(event, "", middlewareLoader);
331331
expect(middleware).toHaveBeenCalledWith(
332332
expect.objectContaining({
333333
url: "https://test.me/path",
@@ -342,11 +342,30 @@ describe("handleMiddleware", () => {
342342
host: "test.me",
343343
},
344344
});
345-
await handleMiddleware(event, middlewareLoader);
345+
await handleMiddleware(event, "", middlewareLoader);
346346
expect(middleware).toHaveBeenCalledWith(
347347
expect.objectContaining({
348348
url: "https://test.me/path",
349349
}),
350350
);
351351
});
352+
353+
it("should use the initial search query", async () => {
354+
const event = createEvent({
355+
url: "https://test.me/path?something=General%2520Banner",
356+
headers: {
357+
host: "test.me",
358+
},
359+
});
360+
await handleMiddleware(
361+
event,
362+
"?something=General%2520Banner",
363+
middlewareLoader,
364+
);
365+
expect(middleware).toHaveBeenCalledWith(
366+
expect.objectContaining({
367+
url: "https://test.me/path?something=General%2520Banner",
368+
}),
369+
);
370+
});
352371
});

0 commit comments

Comments
 (0)