Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 4x 4x 4x 4x 4x 4x 4x 8x 8x 8x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import type express from "express"; import expressRateLimit from "express-rate-limit"; import type { Kysely } from "kysely"; import morgan from "morgan"; import type { Config } from "./config"; import type { GenericDatabase } from "./database"; import { fileRouter as plainFileRouter } from "./file-router"; import { randomId } from "./id"; import { getLogger } from "./log"; export function forceWWW(): express.RequestHandler { return function forceWWW( req: express.Request, res: express.Response, next: express.NextFunction, ) { const log = getLogger("www"); const host = req.header("host"); if (host) { const wwwRegex = /^www\./i; const isWww = wwwRegex.test(host); const isSubdomain = host.split(".").length > 2; if (!isWww && !isSubdomain) { const lowercaseHost = host.toLowerCase(); // Convert host to lowercase const newUrl = `https://www.${lowercaseHost}${req.url}`; log.info("redirecting to", newUrl); res.redirect(301, newUrl); } else { next(); } } else { next(); } }; } function logging(): express.RequestHandler { const logger = getLogger(); return morgan( ":method :url :status :res[content-length] - :response-time ms", { stream: { write: (message) => logger.info(message.trim()), }, }, ); } function rateLimit(opts?: { rateLimit?: { windowMs?: number; limit?: number; message?: string }; }): express.RequestHandler { const rateLimit = opts?.rateLimit; return expressRateLimit({ windowMs: rateLimit?.windowMs ?? 60 * 1000, limit: rateLimit?.limit ?? 60, message: rateLimit?.message ?? "Too many requests, please try again in a few seconds", }); } function database({ database, }: { database: GenericDatabase; }): express.RequestHandler { return (req, res, next) => { const log = getLogger("middleware"); log.debug("attach database to request"); res.locals.database = database; next(); }; } async function fileRouter({ dir, }: { dir: string; }): Promise<express.RequestHandler> { const { router } = await plainFileRouter({ cwd: dir }); return router; } // TODO use async local storage function id(): express.RequestHandler { return (req, res, next) => { res.locals.id = randomId("req"); next(); }; } export function defineHttp( handler: (config: Config) => Promise<express.Application>, ) { return handler; } /** A collection of built-in express middleware. */ export const middleware = { forceWWW, logging, rateLimit, database, fileRouter, id, }; |