From 55f1867c68d8c5b4ac10b51ab9e36a540c33a2c7 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Thu, 11 May 2023 16:24:58 -0500 Subject: [PATCH] Prevent Cloudflare from overriding our own 504 timeout page (#228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explored in https://gitlab.matrix.org/matrix-public-archive/deployment/-/issues/2 (internal deployment issue) > Cloudflare returns an Cloudflare-branded HTTP 502 or 504 error when your origin web server responds with a standard HTTP 502 bad gateway or 504 gateway timeout error: > > *-- https://developers.cloudflare.com/support/troubleshooting/cloudflare-errors/troubleshooting-cloudflare-5xx-errors/#502504-from-your-origin-web-server* The only way to disable this functionality is to have an Enterprise Cloudflare plan and use the `Enable Origin Error Pages` option: > **Enable Origin Error Pages** > > When Origin Error Page is set to “On”, Cloudflare will proxy the 502 and 504 error pages directly from the origin. > > Requires Enterprise or higher So instead of dealing with that headache, we're just working around this by responding with a 500 error when we timeout. Should be good enough I think. The user won't know any difference but may affect what Search Engines think. Not sure search engines care about the distinction since the page is slow to respond anyway which they punish. --- config/config.default.json | 3 ++- server/middleware/timeout-middleware.js | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/config/config.default.json b/config/config.default.json index 0b75b0b..742fdc4 100644 --- a/config/config.default.json +++ b/config/config.default.json @@ -6,11 +6,12 @@ "matrixServerUrl": "http://localhost:8008/", "matrixServerName": "localhost", // Set this to 100 since that is the max that Synapse will backfill even if you do a - // `/messges?limit=1000` and we don't want to miss messages in between. + // `/messages?limit=1000` and we don't want to miss messages in between. "archiveMessageLimit": 100, "requestTimeoutMs": 25000, "logOutputFromChildProcesses": false, //"stopSearchEngineIndexing": true, + "workaroundCloudflare504TimeoutErrors": false, // Tracing //"jaegerTracesEndpoint": "http://localhost:14268/api/traces", diff --git a/server/middleware/timeout-middleware.js b/server/middleware/timeout-middleware.js index 3e0428d..0319555 100644 --- a/server/middleware/timeout-middleware.js +++ b/server/middleware/timeout-middleware.js @@ -102,8 +102,17 @@ async function timeoutMiddleware(req, res, next) { }, }); - // 504 Gateway timeout - res.status(504); + // The most semantic HTTP status code to return here is a 504 Gateway timeout but if + // you use Cloudflare in front of the archive, it will serve its own + // Cloudflare-branded 504 page if your own origin server responds with a 504. And + // the only way to disable this functionality is to have an Enterprise Cloudflare + // plan. So to workaround this, we return a 500 instead. Relevant Cloudflare docs: + // https://developers.cloudflare.com/support/troubleshooting/cloudflare-errors/troubleshooting-cloudflare-5xx-errors/#502504-from-your-origin-web-server + // + // We want to show our own timeout page because it has more information about what + // went wrong (e.g. which external Matrix API requests were slow). + res.status(config.workaroundCloudflare504TimeoutErrors ? 500 : 504); + res.set('Content-Type', 'text/html'); res.send(pageHtml);