summaryrefslogtreecommitdiff
path: root/packages/integrations/node/src/nodeMiddleware.ts
diff options
context:
space:
mode:
authorGravatar Emanuele Stoppa <my.burning@gmail.com> 2023-05-03 17:40:47 +0100
committerGravatar GitHub <noreply@github.com> 2023-05-03 17:40:47 +0100
commit831b67cdb8250f93f66e3b171fab024652bf80f2 (patch)
treef2b32803f20b581985ca29af960cdc03835f8848 /packages/integrations/node/src/nodeMiddleware.ts
parentad907196cb42f21d9540ae0d77aa742bf7adf030 (diff)
downloadastro-831b67cdb8250f93f66e3b171fab024652bf80f2.tar.gz
astro-831b67cdb8250f93f66e3b171fab024652bf80f2.tar.zst
astro-831b67cdb8250f93f66e3b171fab024652bf80f2.zip
feat(astro): experimental middleware (#6721)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Diffstat (limited to 'packages/integrations/node/src/nodeMiddleware.ts')
-rw-r--r--packages/integrations/node/src/nodeMiddleware.ts64
1 files changed, 64 insertions, 0 deletions
diff --git a/packages/integrations/node/src/nodeMiddleware.ts b/packages/integrations/node/src/nodeMiddleware.ts
new file mode 100644
index 000000000..c23cdb89c
--- /dev/null
+++ b/packages/integrations/node/src/nodeMiddleware.ts
@@ -0,0 +1,64 @@
+import type { NodeApp } from 'astro/app/node';
+import type { IncomingMessage, ServerResponse } from 'http';
+import type { Readable } from 'stream';
+import { responseIterator } from './response-iterator';
+import type { Options } from './types';
+
+export default function (app: NodeApp, mode: Options['mode']) {
+ return async function (
+ req: IncomingMessage,
+ res: ServerResponse,
+ next?: (err?: unknown) => void
+ ) {
+ try {
+ const route =
+ mode === 'standalone' ? app.match(req, { matchNotFound: true }) : app.match(req);
+ if (route) {
+ try {
+ const response = await app.render(req);
+ await writeWebResponse(app, res, response);
+ } catch (err: unknown) {
+ if (next) {
+ next(err);
+ } else {
+ throw err;
+ }
+ }
+ } else if (next) {
+ return next();
+ } else {
+ res.writeHead(404);
+ res.end('Not found');
+ }
+ } catch (err: unknown) {
+ if (!res.headersSent) {
+ res.writeHead(500, `Server error`);
+ res.end();
+ }
+ }
+ };
+}
+
+async function writeWebResponse(app: NodeApp, res: ServerResponse, webResponse: Response) {
+ const { status, headers } = webResponse;
+
+ if (app.setCookieHeaders) {
+ const setCookieHeaders: Array<string> = Array.from(app.setCookieHeaders(webResponse));
+ if (setCookieHeaders.length) {
+ res.setHeader('Set-Cookie', setCookieHeaders);
+ }
+ }
+
+ res.writeHead(status, Object.fromEntries(headers.entries()));
+ if (webResponse.body) {
+ try {
+ for await (const chunk of responseIterator(webResponse) as unknown as Readable) {
+ res.write(chunk);
+ }
+ } catch (err: any) {
+ console.error(err?.stack || err?.message || String(err));
+ res.write('Internal server error');
+ }
+ }
+ res.end();
+}