@opennextjs/aws 4.1.9 → 4.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,11 +4,15 @@ type MiddlewareLoader = () => Promise<{
4
4
  default: Middleware;
5
5
  }>;
6
6
  /**
7
+ * Runs matching Next.js middleware and applies its routing result.
7
8
  *
8
- * @param internalEvent the internal event
9
- * @param initialSearch the initial query string as it was received in the handler
10
- * @param middlewareLoader Only used for unit test
11
- * @returns `Promise<MiddlewareEvent | InternalResult>`
9
+ * Middleware request-header overrides are normalized and filtered to Next.js's allowlist.
10
+ *
11
+ * @param internalEvent The internal request event.
12
+ * @param initialSearch The initial query string received by the handler.
13
+ * @param middlewareLoader The middleware loader, overridden by unit tests.
14
+ * @return The middleware-adjusted event or a terminal middleware response.
15
+ * @throws When middleware loading, execution, or response processing fails.
12
16
  */
13
17
  export declare function handleMiddleware(internalEvent: InternalEvent, initialSearch: string, middlewareLoader?: MiddlewareLoader): Promise<MiddlewareEvent | InternalResult>;
14
18
  export {};
@@ -14,11 +14,15 @@ function defaultMiddlewareLoader() {
14
14
  return import("./middleware.mjs");
15
15
  }
16
16
  /**
17
+ * Runs matching Next.js middleware and applies its routing result.
17
18
  *
18
- * @param internalEvent the internal event
19
- * @param initialSearch the initial query string as it was received in the handler
20
- * @param middlewareLoader Only used for unit test
21
- * @returns `Promise<MiddlewareEvent | InternalResult>`
19
+ * Middleware request-header overrides are normalized and filtered to Next.js's allowlist.
20
+ *
21
+ * @param internalEvent The internal request event.
22
+ * @param initialSearch The initial query string received by the handler.
23
+ * @param middlewareLoader The middleware loader, overridden by unit tests.
24
+ * @return The middleware-adjusted event or a terminal middleware response.
25
+ * @throws When middleware loading, execution, or response processing fails.
22
26
  */
23
27
  export async function handleMiddleware(internalEvent, initialSearch, middlewareLoader = defaultMiddlewareLoader) {
24
28
  const headers = internalEvent.headers;
@@ -81,11 +85,15 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
81
85
 
82
86
  We can delete `x-middleware-override-headers` and check if the key starts with
83
87
  x-middleware-request- to set the req headers
88
+
89
+ The request headers that are not listed in `x-middleware-override-headers` have been
90
+ deleted by the middleware and must not be forwarded.
84
91
  */
85
92
  const responseHeaders = result.headers;
86
93
  const reqHeaders = {};
87
94
  const resHeaders = {};
88
95
  // These are internal headers used by Next.js, we don't want to expose them to the client
96
+ // NOTE: keys must be in lowercase to match the normalized header keys.
89
97
  const filteredHeaders = [
90
98
  "x-middleware-override-headers",
91
99
  "x-middleware-next",
@@ -95,21 +103,23 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
95
103
  ];
96
104
  const xMiddlewareKey = "x-middleware-request-";
97
105
  responseHeaders.forEach((value, key) => {
98
- if (key.startsWith(xMiddlewareKey)) {
99
- const k = key.substring(xMiddlewareKey.length);
106
+ // Always use the normalized key (lowercase) for comparison and storage.
107
+ const normalizedKey = key.toLowerCase();
108
+ if (normalizedKey.startsWith(xMiddlewareKey)) {
109
+ const k = normalizedKey.substring(xMiddlewareKey.length);
100
110
  reqHeaders[k] = value;
101
111
  }
102
112
  else {
103
- if (filteredHeaders.includes(key.toLowerCase()))
113
+ if (filteredHeaders.includes(normalizedKey))
104
114
  return;
105
115
  // Headers.forEach folds same-name headers; use getSetCookie() below instead.
106
- if (key.toLowerCase() === "set-cookie")
116
+ if (normalizedKey === "set-cookie")
107
117
  return;
108
- if (REDIRECTS.has(statusCode) && key.toLowerCase() === "location") {
109
- resHeaders[key] = normalizeLocationHeader(value, internalEvent.url);
118
+ if (REDIRECTS.has(statusCode) && normalizedKey === "location") {
119
+ resHeaders[normalizedKey] = normalizeLocationHeader(value, internalEvent.url);
110
120
  }
111
121
  else {
112
- resHeaders[key] = value;
122
+ resHeaders[normalizedKey] = value;
113
123
  }
114
124
  }
115
125
  });
@@ -122,6 +132,13 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
122
132
  if (setCookies.length > 0) {
123
133
  resHeaders["set-cookie"] = setCookies;
124
134
  }
135
+ const overrideHeaders = responseHeaders.get("x-middleware-override-headers");
136
+ const overriddenHeaders = overrideHeaders === null
137
+ ? undefined
138
+ : new Set(overrideHeaders.split(",").map((key) => key.trim().toLowerCase()));
139
+ const newHeaders = Object.fromEntries([...Object.entries(internalEvent.headers), ...Object.entries(reqHeaders)]
140
+ .map(([key, value]) => [key.toLowerCase(), value])
141
+ .filter(([key]) => !overriddenHeaders || overriddenHeaders.has(key)));
125
142
  // If the middleware returned a Rewrite, set the `url` to the pathname of the rewrite
126
143
  // NOTE: the header was added to `req` from above
127
144
  const rewriteUrl = responseHeaders.get("x-middleware-rewrite");
@@ -162,7 +179,7 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
162
179
  url: newUrl,
163
180
  rawPath: new URL(newUrl).pathname,
164
181
  type: internalEvent.type,
165
- headers: { ...internalEvent.headers, ...reqHeaders },
182
+ headers: newHeaders,
166
183
  body: internalEvent.body,
167
184
  method: internalEvent.method,
168
185
  query: middlewareQuery,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "access": "public"
4
4
  },
5
5
  "name": "@opennextjs/aws",
6
- "version": "4.1.9",
6
+ "version": "4.1.10",
7
7
  "bin": {
8
8
  "open-next": "./dist/index.js"
9
9
  },