summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/healthy-planets-dream.md7
-rw-r--r--packages/astro/src/core/app/node.ts6
-rw-r--r--packages/astro/test/client-address-node.test.js27
-rw-r--r--packages/astro/test/fixtures/client-address-node/astro.config.mjs8
-rw-r--r--packages/astro/test/fixtures/client-address-node/package.json9
-rw-r--r--packages/astro/test/fixtures/client-address-node/src/pages/index.astro13
-rw-r--r--packages/astro/test/test-utils.js8
-rw-r--r--pnpm-lock.yaml9
8 files changed, 86 insertions, 1 deletions
diff --git a/.changeset/healthy-planets-dream.md b/.changeset/healthy-planets-dream.md
new file mode 100644
index 000000000..52f42fc5e
--- /dev/null
+++ b/.changeset/healthy-planets-dream.md
@@ -0,0 +1,7 @@
+---
+"astro": minor
+---
+
+Updates Astro's code for adapters to use the header `x-forwarded-for` to initialize the `clientAddress`.
+
+To take advantage of the new change, integration authors must upgrade the version of Astro in their adapter `peerDependencies` to `4.9.0`.
diff --git a/packages/astro/src/core/app/node.ts b/packages/astro/src/core/app/node.ts
index c28fa8754..537c7f5e7 100644
--- a/packages/astro/src/core/app/node.ts
+++ b/packages/astro/src/core/app/node.ts
@@ -81,7 +81,11 @@ export class NodeApp extends App {
Object.assign(options, makeRequestBody(req));
}
const request = new Request(url, options);
- if (req.socket?.remoteAddress) {
+
+ const clientIp = req.headers['x-forwarded-for'];
+ if (clientIp) {
+ Reflect.set(request, clientAddressSymbol, clientIp);
+ } else if (req.socket?.remoteAddress) {
Reflect.set(request, clientAddressSymbol, req.socket.remoteAddress);
}
return request;
diff --git a/packages/astro/test/client-address-node.test.js b/packages/astro/test/client-address-node.test.js
new file mode 100644
index 000000000..8114ea42d
--- /dev/null
+++ b/packages/astro/test/client-address-node.test.js
@@ -0,0 +1,27 @@
+import * as assert from 'node:assert/strict';
+import { describe, it } from 'node:test';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+import { createRequestAndResponse } from './units/test-utils.js';
+
+describe('NodeClientAddress', () => {
+ it('clientAddress is 1.1.1.1', async () => {
+ const fixture = await loadFixture({
+ root: './fixtures/client-address-node/',
+ });
+ await fixture.build();
+ const handle = await fixture.loadNodeAdapterHandler();
+ const { req, res, text } = createRequestAndResponse({
+ method: 'GET',
+ url: '/',
+ headers: {
+ 'x-forwarded-for': '1.1.1.1',
+ },
+ });
+ handle(req, res);
+ const html = await text();
+ const $ = cheerio.load(html);
+ assert.equal(res.statusCode, 200);
+ assert.equal($('#address').text(), '1.1.1.1');
+ });
+});
diff --git a/packages/astro/test/fixtures/client-address-node/astro.config.mjs b/packages/astro/test/fixtures/client-address-node/astro.config.mjs
new file mode 100644
index 000000000..ad9b3a3b1
--- /dev/null
+++ b/packages/astro/test/fixtures/client-address-node/astro.config.mjs
@@ -0,0 +1,8 @@
+import node from '@astrojs/node';
+import { defineConfig } from 'astro/config';
+
+// https://astro.build/config
+export default defineConfig({
+ output: 'server',
+ adapter: node({ mode: 'middleware' }),
+});
diff --git a/packages/astro/test/fixtures/client-address-node/package.json b/packages/astro/test/fixtures/client-address-node/package.json
new file mode 100644
index 000000000..4b1c6a5ee
--- /dev/null
+++ b/packages/astro/test/fixtures/client-address-node/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/client-address-node",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/client-address-node/src/pages/index.astro b/packages/astro/test/fixtures/client-address-node/src/pages/index.astro
new file mode 100644
index 000000000..b720cfd34
--- /dev/null
+++ b/packages/astro/test/fixtures/client-address-node/src/pages/index.astro
@@ -0,0 +1,13 @@
+---
+export const prerender = false;
+const address = Astro.clientAddress;
+---
+<html>
+ <head>
+ <title>Astro.clientAddress</title>
+ </head>
+ <body>
+ <h1>Astro.clientAddress</h1>
+ <div id="address">{ address }</div>
+ </body>
+</html>
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index bd7e1f903..65968a0bc 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -25,6 +25,8 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
* @typedef {import('../src/core/app/index').App} App
* @typedef {import('../src/cli/check/index').AstroChecker} AstroChecker
* @typedef {import('../src/cli/check/index').CheckPayload} CheckPayload
+ * @typedef {import('http').IncomingMessage} NodeRequest
+ * @typedef {import('http').ServerResponse} NodeResponse
*
*
* @typedef {Object} Fixture
@@ -40,6 +42,7 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
* @property {typeof preview} preview
* @property {() => Promise<void>} clean
* @property {() => Promise<App>} loadTestAdapterApp
+ * @property {() => Promise<(req: NodeRequest, res: NodeResponse) => void>} loadNodeAdapterHandler
* @property {() => Promise<void>} onNextChange
* @property {typeof check} check
* @property {typeof sync} sync
@@ -213,6 +216,11 @@ export async function loadFixture(inlineConfig) {
});
}
},
+ loadNodeAdapterHandler: async () => {
+ const url = new URL(`./server/entry.mjs?id=${fixtureId}`, config.outDir);
+ const { handler } = await import(url);
+ return handler;
+ },
loadTestAdapterApp: async (streaming) => {
const url = new URL(`./server/entry.mjs?id=${fixtureId}`, config.outDir);
const { createApp, manifest } = await import(url);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index cbc289056..829ec7013 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2381,6 +2381,15 @@ importers:
specifier: workspace:*
version: link:../../..
+ packages/astro/test/fixtures/client-address-node:
+ dependencies:
+ '@astrojs/node':
+ specifier: workspace:*
+ version: link:../../../../integrations/node
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
packages/astro/test/fixtures/code-component:
dependencies:
astro: