ソースを参照

[web] disable buffering when downloading large files (#31874)

* [web] disable buffering when downloading large files

* [web] fix unit tests

GitOrigin-RevId: c8b0381962814fa62425364f03457600daf287ef
Jakob Ackermann 5 ヶ月 前
コミット
da50aee52c

+ 4 - 0
services/web/app/src/Features/Compile/ClsiCacheController.mjs

@@ -105,6 +105,10 @@ async function _downloadFromCacheWithParams(
   const TEN_MINUTES_IN_MS = 10 * 60 * 1000
   res.setTimeout(TEN_MINUTES_IN_MS)
   timer = setTimeout(() => ac.abort(), TEN_MINUTES_IN_MS)
+
+  // Disable buffering in nginx
+  res.setHeader('X-Accel-Buffering', 'no')
+
   try {
     res.writeHead(response.status)
     await pipeline(

+ 3 - 0
services/web/app/src/Features/Compile/CompileController.mjs

@@ -632,6 +632,9 @@ const _CompileController = {
       clearTimeout(timeout)
       timeout = setTimeout(() => ac.abort(), TEN_MINUTES_IN_MS)
 
+      // Disable buffering in nginx
+      res.setHeader('X-Accel-Buffering', 'no')
+
       res.writeHead(response.status)
       await pipeline(stream, res)
       timer.labels.status = 'success'

+ 3 - 0
services/web/app/src/Features/History/HistoryController.mjs

@@ -89,6 +89,9 @@ async function requestBlob(method, req, res) {
   res.setHeader('Content-Type', 'application/octet-stream')
   setBlobCacheHeaders(res, hash)
 
+  // Disable buffering in nginx
+  res.setHeader('X-Accel-Buffering', 'no')
+
   try {
     await pipeline(stream, res)
   } catch (err) {

+ 2 - 0
services/web/app/src/infrastructure/Response.mjs

@@ -31,6 +31,8 @@ export function prepareZipAttachment(res, filename) {
   // res.attachment sets both content-type and content-disposition headers.
   res.attachment(filename)
   res.setHeader('X-Content-Type-Options', 'nosniff')
+  // Disable buffering in nginx
+  res.setHeader('X-Accel-Buffering', 'no')
 }
 
 export function zipAttachment(res, body, filename) {

+ 2 - 0
services/web/test/unit/src/Downloads/ProjectDownloadsController.test.mjs

@@ -113,6 +113,7 @@ describe('ProjectDownloadsController', function () {
       ctx.res.headers.should.deep.equal({
         'Content-Disposition': `attachment; filename="project_name_with_accênts_and___special_characters.zip"`,
         'Content-Type': 'application/zip',
+        'X-Accel-Buffering': 'no',
         'X-Content-Type-Options': 'nosniff',
       })
     })
@@ -184,6 +185,7 @@ describe('ProjectDownloadsController', function () {
         'Content-Disposition':
           'attachment; filename="Overleaf Projects (2 items).zip"',
         'Content-Type': 'application/zip',
+        'X-Accel-Buffering': 'no',
         'X-Content-Type-Options': 'nosniff',
       })
     })