Skip to content

Commit 4bc4701

Browse files
authored
Merge pull request #1736 from nakrovati/refactor/server
refactor: rewrite server in typescript
2 parents 828ac3a + d0f6a22 commit 4bc4701

29 files changed

+1152
-744
lines changed

server/app.js

Lines changed: 0 additions & 129 deletions
This file was deleted.

server/app.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import Fastify, { FastifyServerOptions } from "fastify";
2+
import frameworksRouter from "./src/frameworks/frameworksRouter.js";
3+
import cspRouter from "./src/csp/cspRouter.js";
4+
import staticRouter from "./src/static/staticRouter.js";
5+
import ejs from "ejs";
6+
import fastifyView from "@fastify/view";
7+
import minifier from "html-minifier";
8+
import { Readable } from "node:stream";
9+
import zlib from "node:zlib";
10+
import { responseSizeRouter } from "./src/responseSize/responseSizeRouter.js";
11+
import { createResponseSizeDecorator } from "./src/responseSize/responseSizeDecorator.js";
12+
import { createCSPDecorator } from "./src/csp/cspDecorator.js";
13+
14+
/**
15+
* Builds the server but does not start it. Need it for testing API
16+
*/
17+
function buildServer(options: FastifyServerOptions = {}) {
18+
const fastify = Fastify(options);
19+
20+
fastify.register(fastifyView, {
21+
engine: {
22+
ejs,
23+
},
24+
options: {
25+
useHtmlMinifier: minifier,
26+
},
27+
});
28+
29+
fastify.decorate("csp", createCSPDecorator());
30+
fastify.decorate("responseSize", createResponseSizeDecorator());
31+
32+
fastify.addHook("onSend", async function (request, reply, payload) {
33+
// const MISSING_HEADERS_AND_HTTP = 99;
34+
function getSizeInfo(original: Buffer | string, compressed?: Buffer | string) {
35+
if (compressed) {
36+
reply.header("Content-Length", compressed.length);
37+
reply.header("Content-Encoding", "br");
38+
} else {
39+
compressed = original;
40+
}
41+
// let headers = Object.entries(reply.getHeaders()).reduce((p, [e, v]) => p + `${e}: ${v} \n`, "");
42+
// console.log(request.url, reply.statusCode, "\n", headers);
43+
return {
44+
compressed: compressed.length, // + headers.length + MISSING_HEADERS_AND_HTTP,
45+
uncompressed: original.length, // + headers.length + MISSING_HEADERS_AND_HTTP
46+
};
47+
}
48+
49+
if (request.url.startsWith("/css") || reply.statusCode !== 200 || !fastify.responseSize.use_compression) {
50+
return payload;
51+
}
52+
53+
if (typeof payload === "string") {
54+
const { uncompressed, compressed } = getSizeInfo(payload);
55+
fastify.responseSize.add(uncompressed, compressed);
56+
console.log(
57+
`onSend: ${request.url} as string with uncompressed size ${uncompressed} sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
58+
);
59+
return payload;
60+
}
61+
62+
if (payload instanceof Readable) {
63+
try {
64+
const chunks = await payload.toArray();
65+
const buffer = Buffer.concat(chunks);
66+
67+
if (buffer.length >= 1024) {
68+
const compressedBuffer = zlib.brotliCompressSync(buffer);
69+
const { uncompressed, compressed } = getSizeInfo(buffer, compressedBuffer);
70+
fastify.responseSize.add(uncompressed, compressed);
71+
console.log(
72+
`onSend: ${request.url} as stream with uncompressed size ${uncompressed} compressed ${compressed} sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
73+
);
74+
return compressedBuffer;
75+
} else {
76+
const { uncompressed, compressed } = getSizeInfo(buffer);
77+
fastify.responseSize.add(uncompressed, compressed);
78+
console.log(
79+
`onSend: ${request.url} as stream with uncompressed size ${uncompressed} (not compressed since below threshold) sum uncompressed ${fastify.responseSize.size_uncompressed}, compressed ${fastify.responseSize.size_compressed}`
80+
);
81+
return buffer;
82+
}
83+
} catch (error) {
84+
console.log("onSend: Error", error);
85+
return payload;
86+
}
87+
}
88+
89+
console.log("onSend: Unknown payload type", typeof payload, payload);
90+
return payload;
91+
});
92+
93+
fastify.addHook("onRequest", function (request, reply, done) {
94+
if (request.url.endsWith("index.html")) {
95+
this.responseSize.reset();
96+
reply.header("Cross-Origin-Embedder-Policy", "require-corp");
97+
reply.header("Cross-Origin-Opener-Policy", "same-origin");
98+
}
99+
done();
100+
});
101+
102+
fastify.register(responseSizeRouter);
103+
fastify.register(staticRouter);
104+
fastify.register(frameworksRouter);
105+
fastify.register(cspRouter, { prefix: "/csp" });
106+
107+
return fastify;
108+
}
109+
110+
export { buildServer };

server/index.js renamed to server/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const PORT = 8080;
55
const server = buildServer();
66

77
try {
8-
await server.listen({ port: PORT}); //, host: '0.0.0.0' });
8+
await server.listen({ port: PORT }); //, host: '0.0.0.0' });
99
console.log(`Server running on port ${PORT}`);
1010
} catch (error) {
1111
server.log.error(error);

0 commit comments

Comments
 (0)