summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/light-moose-attend.md5
-rw-r--r--packages/astro/src/core/config/schema.ts3
-rw-r--r--packages/astro/src/core/dev/container.ts4
-rw-r--r--packages/astro/src/core/preview/index.ts4
-rw-r--r--packages/astro/src/core/preview/static-preview-server.ts19
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts5
-rw-r--r--packages/astro/test/astro-dev-headers.test.js39
-rw-r--r--packages/astro/test/astro-preview-headers.test.js40
-rw-r--r--packages/astro/test/fixtures/astro-dev-headers/package.json8
-rw-r--r--packages/astro/test/fixtures/astro-dev-headers/src/pages/index.astro8
-rw-r--r--packages/astro/test/fixtures/astro-preview-headers/package.json8
-rw-r--r--packages/astro/test/fixtures/astro-preview-headers/src/pages/index.astro8
-rw-r--r--pnpm-lock.yaml12
13 files changed, 157 insertions, 6 deletions
diff --git a/.changeset/light-moose-attend.md b/.changeset/light-moose-attend.md
new file mode 100644
index 000000000..0b32eba8f
--- /dev/null
+++ b/.changeset/light-moose-attend.md
@@ -0,0 +1,5 @@
+---
+'astro': minor
+---
+
+Add `server.headers` option
diff --git a/packages/astro/src/core/config/schema.ts b/packages/astro/src/core/config/schema.ts
index c2011926c..9e5fc377b 100644
--- a/packages/astro/src/core/config/schema.ts
+++ b/packages/astro/src/core/config/schema.ts
@@ -9,6 +9,7 @@ import { fileURLToPath } from 'url';
import { z } from 'zod';
import { appendForwardSlash, prependForwardSlash, trimSlashes } from '../path.js';
import { isObject } from '../util.js';
+import { OutgoingHttpHeaders } from 'http';
const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
root: '.',
@@ -125,6 +126,7 @@ export const AstroConfigSchema = z.object({
.optional()
.default(ASTRO_CONFIG_DEFAULTS.server.host),
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
+ headers: z.custom<OutgoingHttpHeaders>().optional(),
})
.optional()
.default({})
@@ -287,6 +289,7 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: URL) {
.optional()
.default(ASTRO_CONFIG_DEFAULTS.server.host),
port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
+ headers: z.custom<OutgoingHttpHeaders>().optional(),
streaming: z.boolean().optional().default(true),
})
.optional()
diff --git a/packages/astro/src/core/dev/container.ts b/packages/astro/src/core/dev/container.ts
index c9eaaa8eb..87cd2b7ad 100644
--- a/packages/astro/src/core/dev/container.ts
+++ b/packages/astro/src/core/dev/container.ts
@@ -65,7 +65,7 @@ export async function createContainer(params: CreateContainerParams = {}): Promi
logging,
isRestart,
});
- const { host } = settings.config.server;
+ const { host, headers } = settings.config.server;
// The client entrypoint for renderers. Since these are imported dynamically
// we need to tell Vite to preoptimize them.
@@ -76,7 +76,7 @@ export async function createContainer(params: CreateContainerParams = {}): Promi
const viteConfig = await createVite(
{
mode: 'development',
- server: { host },
+ server: { host, headers },
optimizeDeps: {
include: rendererClientEntries,
},
diff --git a/packages/astro/src/core/preview/index.ts b/packages/astro/src/core/preview/index.ts
index ea8eef1e1..d4a5c8bb2 100644
--- a/packages/astro/src/core/preview/index.ts
+++ b/packages/astro/src/core/preview/index.ts
@@ -24,10 +24,10 @@ export default async function preview(
});
await runHookConfigDone({ settings: settings, logging: logging });
const host = getResolvedHostForHttpServer(settings.config.server.host);
- const { port } = settings.config.server;
+ const { port, headers } = settings.config.server;
if (settings.config.output === 'static') {
- const server = await createStaticPreviewServer(settings, { logging, host, port });
+ const server = await createStaticPreviewServer(settings, { logging, host, port, headers });
return server;
}
if (!settings.adapter) {
diff --git a/packages/astro/src/core/preview/static-preview-server.ts b/packages/astro/src/core/preview/static-preview-server.ts
index 942567029..f74755aed 100644
--- a/packages/astro/src/core/preview/static-preview-server.ts
+++ b/packages/astro/src/core/preview/static-preview-server.ts
@@ -3,7 +3,7 @@ import type { AstroSettings } from '../../@types/astro';
import type { LogOptions } from '../logger/core';
import fs from 'fs';
-import http from 'http';
+import http, { OutgoingHttpHeaders } from 'http';
import { performance } from 'perf_hooks';
import sirv from 'sirv';
import { fileURLToPath } from 'url';
@@ -24,7 +24,17 @@ const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/;
/** The primary dev action */
export default async function createStaticPreviewServer(
settings: AstroSettings,
- { logging, host, port }: { logging: LogOptions; host: string | undefined; port: number }
+ {
+ logging,
+ host,
+ port,
+ headers,
+ }: {
+ logging: LogOptions;
+ host: string | undefined;
+ port: number;
+ headers: OutgoingHttpHeaders | undefined;
+ }
): Promise<PreviewServer> {
const startServerTime = performance.now();
const defaultOrigin = 'http://localhost';
@@ -35,6 +45,11 @@ export default async function createStaticPreviewServer(
dev: true,
etag: true,
maxAge: 0,
+ setHeaders: (res, pathname, stats) => {
+ for (const [name, value] of Object.entries(headers ?? {})) {
+ if (value) res.setHeader(name, value);
+ }
+ },
});
// Create the preview server, send static files out of the `dist/` directory.
const server = http.createServer((req, res) => {
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index 9cd4ab239..5bd551ca9 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -144,6 +144,11 @@ export async function handleRoute(
clientAddress: buildingToSSR ? req.socket.remoteAddress : undefined,
});
+ // Set user specified headers to response object.
+ for (const [name, value] of Object.entries(config.server.headers ?? {})) {
+ if (value) res.setHeader(name, value);
+ }
+
// attempt to get static paths
// if this fails, we have a bad URL match!
const paramsAndPropsRes = await getParamsAndProps({
diff --git a/packages/astro/test/astro-dev-headers.test.js b/packages/astro/test/astro-dev-headers.test.js
new file mode 100644
index 000000000..7cc2266c6
--- /dev/null
+++ b/packages/astro/test/astro-dev-headers.test.js
@@ -0,0 +1,39 @@
+import { expect } from 'chai';
+import { loadFixture } from './test-utils.js';
+
+describe('Astro dev headers', () => {
+ let fixture;
+ let devServer;
+ const headers = {
+ 'x-astro': 'test',
+ };
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/astro-dev-headers/',
+ server: {
+ headers,
+ },
+ });
+ await fixture.build();
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ describe('dev', () => {
+ it('returns custom headers for valid URLs', async () => {
+ const result = await fixture.fetch('/');
+ expect(result.status).to.equal(200);
+ expect(Object.fromEntries(result.headers)).to.include(headers);
+ });
+
+ it('does not return custom headers for invalid URLs', async () => {
+ const result = await fixture.fetch('/bad-url');
+ expect(result.status).to.equal(404);
+ expect(Object.fromEntries(result.headers)).not.to.include(headers);
+ });
+ });
+});
diff --git a/packages/astro/test/astro-preview-headers.test.js b/packages/astro/test/astro-preview-headers.test.js
new file mode 100644
index 000000000..ef05399de
--- /dev/null
+++ b/packages/astro/test/astro-preview-headers.test.js
@@ -0,0 +1,40 @@
+import { expect } from 'chai';
+import { loadFixture } from './test-utils.js';
+
+describe('Astro preview headers', () => {
+ let fixture;
+ let previewServer;
+ const headers = {
+ astro: 'test',
+ };
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/astro-preview-headers/',
+ server: {
+ headers,
+ },
+ });
+ await fixture.build();
+ previewServer = await fixture.preview();
+ });
+
+ // important: close preview server (free up port and connection)
+ after(async () => {
+ await previewServer.stop();
+ });
+
+ describe('preview', () => {
+ it('returns custom headers for valid URLs', async () => {
+ const result = await fixture.fetch('/');
+ expect(result.status).to.equal(200);
+ expect(Object.fromEntries(result.headers)).to.include(headers);
+ });
+
+ it('does not return custom headers for invalid URLs', async () => {
+ const result = await fixture.fetch('/bad-url');
+ expect(result.status).to.equal(404);
+ expect(Object.fromEntries(result.headers)).not.to.include(headers);
+ });
+ });
+});
diff --git a/packages/astro/test/fixtures/astro-dev-headers/package.json b/packages/astro/test/fixtures/astro-dev-headers/package.json
new file mode 100644
index 000000000..891529f80
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-dev-headers/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/astro-dev-headers",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/astro-dev-headers/src/pages/index.astro b/packages/astro/test/fixtures/astro-dev-headers/src/pages/index.astro
new file mode 100644
index 000000000..47d2f7fc6
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-dev-headers/src/pages/index.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ </head>
+ <body>
+ <h1>Hello world!</h1>
+ </body>
+</html>
+
diff --git a/packages/astro/test/fixtures/astro-preview-headers/package.json b/packages/astro/test/fixtures/astro-preview-headers/package.json
new file mode 100644
index 000000000..23d664eb4
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-preview-headers/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/astro-preview-headers",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/astro-preview-headers/src/pages/index.astro b/packages/astro/test/fixtures/astro-preview-headers/src/pages/index.astro
new file mode 100644
index 000000000..47d2f7fc6
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-preview-headers/src/pages/index.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ </head>
+ <body>
+ <h1>Hello world!</h1>
+ </body>
+</html>
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e3eb66897..c895ce128 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1288,6 +1288,12 @@ importers:
dependencies:
astro: link:../../..
+ packages/astro/test/fixtures/astro-dev-headers:
+ specifiers:
+ astro: workspace:*
+ dependencies:
+ astro: link:../../..
+
packages/astro/test/fixtures/astro-directives:
specifiers:
astro: workspace:*
@@ -1514,6 +1520,12 @@ importers:
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
+ packages/astro/test/fixtures/astro-preview-headers:
+ specifiers:
+ astro: workspace:*
+ dependencies:
+ astro: link:../../..
+
packages/astro/test/fixtures/astro-public:
specifiers:
astro: workspace:*