Skip to content

Commit 43d2370

Browse files
committed
Set "x-forwarded-host" as NextServer "host"
1 parent c7e4d44 commit 43d2370

File tree

3 files changed

+42
-16
lines changed

3 files changed

+42
-16
lines changed

.changeset/fresh-wombats-explode.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"open-next": patch
3+
---
4+
5+
Set "x-forwarded-host" as NextServer "host"

README.md

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -188,27 +188,27 @@ This ensures that the Lambda handler remains at `index.mjs`.
188188

189189
Create a CloudFront distribution, and dispatch requests to their corresponding handlers (behaviors). The following behaviors are configured:
190190

191-
| Behavior | Requests | Origin |
192-
| ----------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
193-
| `/_next/static/*` | Hashed static files | S3 bucket |
194-
| `/_next/image` | Image optimization | image optimization function |
195-
| `/_next/data/*` | data requests | server function |
196-
| `/api/*` | API | server function |
197-
| `/*` | catch all | server function fallback to<br />S3 bucket on 503<br />[see why](#workaround-public-static-files-served-out-by-server-function-aws-specific) |
191+
| Behavior | Requests | CloudFront Function | Origin |
192+
| ----------------- | ------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
193+
| `/_next/static/*` | Hashed static files | - | S3 bucket |
194+
| `/_next/image` | Image optimization | - | image optimization function |
195+
| `/_next/data/*` | data requests | set `x-forwarded-host`<br />[see why](#workaround-set-x-forwarded-host-header-aws-specific) | server function |
196+
| `/api/*` | API | set `x-forwarded-host`<br />[see why](#workaround-set-x-forwarded-host-header-aws-specific) | server function |
197+
| `/*` | catch all | set `x-forwarded-host`<br />[see why](#workaround-set-x-forwarded-host-header-aws-specific) | server function fallback to<br />S3 bucket on 503<br />[see why](#workaround-public-static-files-served-out-by-server-function-aws-specific) |
198198

199199
#### Running at edge
200200

201201
The server function can also run at edge locations by configuring it as Lambda@Edge on Origin Request. The server function can accept both regional request events (API payload version 2.0) and edge request events (CloudFront Origin Request payload). Depending on the shape of the Lambda event object, the function will process the request accordingly.
202202

203203
To configure the CloudFront distribution:
204204

205-
| Behavior | Requests | Lambda@Edge | Origin |
206-
| ----------------- | ------------------- | --------------- | ---------------------------------------------------------------------------------------------------- |
207-
| `/_next/static/*` | Hashed static files | - | S3 bucket |
208-
| `/_next/image` | Image optimization | - | image optimization function |
209-
| `/_next/data/*` | data requests | server function | - |
210-
| `/api/*` | API | server function | - |
211-
| `/*` | catch all | server function | S3 bucket<br />[see why](#workaround-public-static-files-served-out-by-server-function-aws-specific) |
205+
| Behavior | Requests | CloudFront Function | Lambda@Edge | Origin |
206+
| ----------------- | ------------------- | ------------------------------------------------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------- |
207+
| `/_next/static/*` | Hashed static files | - | - | S3 bucket |
208+
| `/_next/image` | Image optimization | - | - | image optimization function |
209+
| `/_next/data/*` | data requests | set `x-forwarded-host`<br />[see why](#workaround-set-x-forwarded-host-header-aws-specific) | server function | - |
210+
| `/api/*` | API | set `x-forwarded-host`<br />[see why](#workaround-set-x-forwarded-host-header-aws-specific) | server function | - |
211+
| `/*` | catch all | set `x-forwarded-host`<br />[see why](#workaround-set-x-forwarded-host-header-aws-specific) | server function | S3 bucket<br />[see why](#workaround-public-static-files-served-out-by-server-function-aws-specific) |
212212

213213
## Limitations and workarounds
214214

@@ -231,6 +231,22 @@ During the build process, the top-level file and directory names in the `public/
231231

232232
This means that on cache miss, the request may take slightly longer to process.
233233

234+
#### WORKAROUND: Set `x-forwarded-host` header (AWS specific)
235+
236+
When the server function receives a request, the `host` value in the Lambda request header is set to the hostname of the AWS Lambda service instead of the actual frontend hostname. This creates an issue for the server function (middleware, SSR routes, or API routes) when it needs to know the frontend host.
237+
238+
To work around the issue, a CloudFront function is run on Viewer Request, which sets the frontend hostname as the `x-forwarded-host` header. The function code looks like this:
239+
240+
```ts
241+
function handler(event) {
242+
var request = event.request;
243+
request.headers["x-forwarded-host"] = request.headers.host;
244+
return request;
245+
}
246+
```
247+
248+
The server function would then sets the `host` header of the request to the value of the `x-forwarded-host` header when sending the request to the `NextServer`.
249+
234250
#### WORKAROUND: `NextServer` does not set cache response headers for HTML pages
235251

236252
As mentioned in the [Server function](#server-lambda-function) section, the server function uses the `NextServer` class from Next.js' build output to handle requests. However, `NextServer` does not seem to set the correct `Cache Control` headers.

packages/open-next/src/adapters/server-adapter.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,15 @@ const requestHandler = new NextServer.default({
4343
export async function handler(
4444
event: APIGatewayProxyEventV2 | CloudFrontRequestEvent | APIGatewayProxyEvent
4545
) {
46-
debug("handler event", event);
47-
const internalEvent = convertFrom(event);
46+
debug("event", event);
4847

4948
// Parse Lambda event and create Next.js request
49+
const internalEvent = convertFrom(event);
50+
51+
// WORKAROUND: Set `x-forwarded-host` header (AWS specific) — https://github.com/serverless-stack/open-next#workaround-set-x-forwarded-host-header-aws-specific
52+
if (internalEvent.headers["x-forwarded-host"]) {
53+
internalEvent.headers.host = internalEvent.headers["x-forwarded-host"];
54+
}
5055

5156
// WORKAROUND: public/ static files served by the server function (AWS specific) — https://github.com/serverless-stack/open-next#workaround-public-static-files-served-by-the-server-function-aws-specific
5257
if (publicAssets.files.includes(internalEvent.rawPath)) {

0 commit comments

Comments
 (0)