From 460d594791c5d4674f162345d40bb2e98e9bac8a Mon Sep 17 00:00:00 2001
From: Zack Pollard <zackpollard@ymail.com>
Date: Mon, 28 Apr 2025 14:54:11 +0100
Subject: [PATCH] feat: api response compression (#17878)

---
 server/package-lock.json  | 66 +++++++++++++++++++++++++++++++++++++++
 server/package.json       |  2 ++
 server/src/workers/api.ts |  2 ++
 3 files changed, 70 insertions(+)

diff --git a/server/package-lock.json b/server/package-lock.json
index b1fdfa1f9d..24180f7cac 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -32,6 +32,7 @@
         "chokidar": "^3.5.3",
         "class-transformer": "^0.5.1",
         "class-validator": "^0.14.0",
+        "compression": "^1.8.0",
         "cookie": "^1.0.2",
         "cookie-parser": "^1.4.7",
         "exiftool-vendored": "^28.3.1",
@@ -83,6 +84,7 @@
         "@types/archiver": "^6.0.0",
         "@types/async-lock": "^1.4.2",
         "@types/bcrypt": "^5.0.0",
+        "@types/compression": "^1.7.5",
         "@types/cookie-parser": "^1.4.8",
         "@types/express": "^4.17.17",
         "@types/fluent-ffmpeg": "^2.1.21",
@@ -5009,6 +5011,16 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/compression": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.5.tgz",
+      "integrity": "sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
     "node_modules/@types/connect": {
       "version": "3.4.38",
       "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
@@ -7603,6 +7615,60 @@
         "node": ">= 14"
       }
     },
+    "node_modules/compressible": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": ">= 1.43.0 < 2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/compression": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
+      "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
+      "license": "MIT",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "compressible": "~2.0.18",
+        "debug": "2.6.9",
+        "negotiator": "~0.6.4",
+        "on-headers": "~1.0.2",
+        "safe-buffer": "5.2.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/compression/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/compression/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "license": "MIT"
+    },
+    "node_modules/compression/node_modules/negotiator": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+      "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
diff --git a/server/package.json b/server/package.json
index f68ba71564..33d1450a53 100644
--- a/server/package.json
+++ b/server/package.json
@@ -57,6 +57,7 @@
     "chokidar": "^3.5.3",
     "class-transformer": "^0.5.1",
     "class-validator": "^0.14.0",
+    "compression": "^1.8.0",
     "cookie": "^1.0.2",
     "cookie-parser": "^1.4.7",
     "exiftool-vendored": "^28.3.1",
@@ -108,6 +109,7 @@
     "@types/archiver": "^6.0.0",
     "@types/async-lock": "^1.4.2",
     "@types/bcrypt": "^5.0.0",
+    "@types/compression": "^1.7.5",
     "@types/cookie-parser": "^1.4.8",
     "@types/express": "^4.17.17",
     "@types/fluent-ffmpeg": "^2.1.21",
diff --git a/server/src/workers/api.ts b/server/src/workers/api.ts
index ddf6e50aa2..4248b23d30 100644
--- a/server/src/workers/api.ts
+++ b/server/src/workers/api.ts
@@ -1,6 +1,7 @@
 import { NestFactory } from '@nestjs/core';
 import { NestExpressApplication } from '@nestjs/platform-express';
 import { json } from 'body-parser';
+import compression from 'compression';
 import cookieParser from 'cookie-parser';
 import { existsSync } from 'node:fs';
 import sirv from 'sirv';
@@ -60,6 +61,7 @@ async function bootstrap() {
     );
   }
   app.use(app.get(ApiService).ssr(excludePaths));
+  app.use(compression());
 
   const server = await (host ? app.listen(port, host) : app.listen(port));
   server.requestTimeout = 24 * 60 * 60 * 1000;