'use strict'; const assert = require('assert'); const urlJoin = require('url-join'); const asyncHandler = require('../lib/express-async-handler'); const { getSerializableSpans, getActiveTraceId } = require('../tracing/tracing-middleware'); const sanitizeHtml = require('../lib/sanitize-html'); const safeJson = require('../lib/safe-json'); const config = require('../lib/config'); const basePath = config.get('basePath'); assert(basePath); const requestTimeoutMs = config.get('requestTimeoutMs'); assert(requestTimeoutMs); // Based off of the `connect-timeout` middleware, // https://github.com/expressjs/timeout/blob/f2f520f335f2f2ae255d4778e908e8d38e3a4e68/index.js async function timeoutMiddleware(req, res, next) { const timeoutId = setTimeout(() => { const traceId = getActiveTraceId(); const serializableSpans = getSerializableSpans(); const serializedSpans = JSON.stringify(serializableSpans); let humanReadableSpans; if (serializableSpans.length > 0) { humanReadableSpans = serializableSpans.map((serializableSpan) => { const method = serializableSpan.attributes['http.method']; const url = serializableSpan.attributes['http.url']; const statusCode = serializableSpan.attributes['http.status_code']; let durationString = `request is still running (${ Date.now() - serializableSpan.startTimeInMs }ms so far)`; if (serializableSpan.durationInMs) { durationString = `took ${serializableSpan.durationInMs}ms`; } return `
  • ${statusCode ?? '🏃'}: ${method} ${url}
    ${durationString}
  • `; }); } else { const noTracingDataAvailableItem = `
  • No tracing data available
  • `; humanReadableSpans = [noTracingDataAvailableItem]; } const cspNonce = res.locals.cspNonce; const hydrogenStylesUrl = urlJoin(basePath, '/hydrogen-styles.css'); const stylesUrl = urlJoin(basePath, '/css/styles.css'); const pageHtml = ` Server timeout - Matrix Public Archive ${/* We add the .hydrogen class here just to get normal body styles */ ''}

    504: Server timeout

    Server was unable to respond in time (${requestTimeoutMs / 1000}s)

    These are the external API requests that made it slow:

    ${sanitizeHtml(``)} ${sanitizeHtml( `

    Trace ID: ${ traceId ?? `none (tracing is probably not enabled)` }

    ` )} `; // 504 Gateway timeout res.status(504); res.set('Content-Type', 'text/html'); res.send(pageHtml); }, requestTimeoutMs); res.on('finish', function () { clearTimeout(timeoutId); }); next(); } module.exports = asyncHandler(timeoutMiddleware);