diff --git a/deploy/nginx/limits.spec.ts b/deploy/nginx/limits.spec.ts index dc43b336..e836311a 100644 --- a/deploy/nginx/limits.spec.ts +++ b/deploy/nginx/limits.spec.ts @@ -28,3 +28,28 @@ describe('per-client request limits', () => { }); } }); + +/** + * Uploads must reach the services: Java's own cap is 50 MiB, and a result for + * many samples is several megabytes. local.conf once set nothing, so nginx's + * 1 MB default refused local uploads that every deployment accepted. + */ +const JAVA_UPLOAD_CAP_MB = 50; + +describe('request body limits', () => { + for (const file of ['dev.conf', 'release.conf', 'production.conf', 'local.conf']) { + it(`${file} lets an upload of Java's size through`, () => { + const conf = readFileSync(join(__dirname, file), 'utf8'); + // Every value, in any unit nginx takes: matching only "64m" let a smaller + // limit written as "512k" pass unseen. A value it cannot read fails. + const values = [...conf.matchAll(/^\s*client_max_body_size\s+(\S+);/gm)].map((m) => m[1]); + expect(values.length, 'no client_max_body_size').toBeGreaterThan(0); + const unit: Record = { '': 1, k: 1024, m: 1024 ** 2, g: 1024 ** 3 }; + for (const value of values) { + const parsed = /^(\d+)([kKmMgG]?)$/.exec(value); + const bytes = parsed ? Number(parsed[1]) * unit[parsed[2].toLowerCase()] : NaN; + expect([value, bytes >= JAVA_UPLOAD_CAP_MB * 1024 ** 2]).toEqual([value, true]); + } + }); + } +}); diff --git a/deploy/nginx/local.conf b/deploy/nginx/local.conf index 4b508f07..445f9913 100644 --- a/deploy/nginx/local.conf +++ b/deploy/nginx/local.conf @@ -64,6 +64,10 @@ server { listen 80; server_name localhost; + # As every deployment: a result for many samples is several megabytes, and + # nginx's 1 MB default refused local uploads the deployments accept. + client_max_body_size 64m; + # The Tina admin is reachable here, and deliberately so: editing content is # the point of running locally. Every deployed environment denies it. location ~ ^/admin(/|$) { diff --git a/package-lock.json b/package-lock.json index 7fde382c..40d49d68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "express": "4.22.3", "fflate": "0.8.3", "gifenc": "1.0.3", + "http-proxy-middleware": "3.0.7", "immer": "^10.2.0", "lodash": "^4.18.1", "marked": "^17.0.6", @@ -11922,7 +11923,6 @@ }, "node_modules/@types/http-proxy": { "version": "1.17.17", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -17453,7 +17453,6 @@ }, "node_modules/follow-redirects": { "version": "1.15.11", - "dev": true, "funding": [ { "type": "individual", @@ -18191,7 +18190,6 @@ }, "node_modules/http-proxy": { "version": "1.18.1", - "dev": true, "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", @@ -18216,7 +18214,8 @@ }, "node_modules/http-proxy-middleware": { "version": "3.0.7", - "dev": true, + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.7.tgz", + "integrity": "sha512-iwbQltVlx8bCrqePUM8C+hllHvdawVhQJaLrj1X7qllkvFQdXFsr16pW/mo9+JDVjN+QO2XUx9jd8SmoFkE5qw==", "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.15", @@ -25287,7 +25286,6 @@ }, "node_modules/requires-port": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/resize-observer-polyfill": { diff --git a/package.json b/package.json index 497c49b8..be95cb4a 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "express": "4.22.3", "fflate": "0.8.3", "gifenc": "1.0.3", + "http-proxy-middleware": "3.0.7", "immer": "^10.2.0", "lodash": "^4.18.1", "marked": "^17.0.6", diff --git a/specs/010-java-services/tasks.md b/specs/010-java-services/tasks.md index 3c7c2cae..fdf9320c 100644 --- a/specs/010-java-services/tasks.md +++ b/specs/010-java-services/tasks.md @@ -205,8 +205,8 @@ Each cutover is one PR. It adds the group's patterns to node's table, one nginx ## Phase 8: Polish and side findings -- [ ] T054 [P] Set `client_max_body_size` in `deploy/nginx/local.conf` to match the other deployments (64 MB), so local uploads over 1 MB are not refused. Test it with `deploy/nginx/test-config.sh`. -- [ ] T055 [P] Declare the proxy package that `projects/website-angular/src/scripts/serve-prod.js` uses in `package.json` (it is only present as a dev-only transitive dependency), and check the lockfile changes only that entry +- [x] T054 [P] Set `client_max_body_size` in `deploy/nginx/local.conf` to match the other deployments (64 MB), so local uploads over 1 MB are not refused. Test it with `deploy/nginx/test-config.sh`. — #508 +- [x] T055 [P] Declare the proxy package that `projects/website-angular/src/scripts/serve-prod.js` uses in `package.json` (it is only present as a dev-only transitive dependency), and check the lockfile changes only that entry — #508 - [ ] T056 Update `specs/006-content-service-to-node/tasks.md` Phase 9 rows with the PR that moved each Java-homed operation, as each moves - [ ] T057 Update the curator-facing documents if any reader-visible behaviour is touched by a cutover (constitution: Development Workflow) - [ ] T058 [EXT] Decide the analysis report's species overview figure. The PDF report embeds the retired Fireworks image, drawn by Java's fireworks-exporter; the site's overview is now the Reacfoam (Voronoi) map. Showing that in the report needs analysis-report changed upstream (its owners) or the figure supplied to it.