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