| import type { Response, NextFunction } from 'express' |
|
|
| import { defaultCacheControl } from '@/frame/middleware/cache-control' |
| import { ExtendedRequest } from '@/types' |
|
|
| |
| |
| |
| |
| const JUNK_STARTS = ['///', '/\\', '/\\.'] |
| const JUNK_ENDS = [ |
| '/package.json', |
| '/package-lock.json', |
| '/etc/passwd', |
| '/Gemfile', |
| '/Gemfile.lock', |
| '/WEB-INF/web.xml', |
| '/WEB-INF/web.xml%C0%80.jsp', |
| ] |
| const JUNK_PATHS = new Set([ |
| ...JUNK_ENDS, |
| '/env', |
| '/xmlrpc.php', |
| '/wp-login.php', |
| '/README.md', |
| '/server.js', |
| '/.git', |
| '/_next', |
| ]) |
|
|
| |
| |
| const JUNK_BASENAMES = new Set([ |
| |
| '.env', |
| ]) |
|
|
| function isJunkPath(path: string) { |
| if (JUNK_PATHS.has(path)) return true |
|
|
| for (const junkPath of JUNK_STARTS) { |
| if (path.startsWith(junkPath)) { |
| return true |
| } |
| } |
|
|
| for (const junkPath of JUNK_ENDS) { |
| if (path.endsWith(junkPath)) { |
| return true |
| } |
| } |
|
|
| const basename = path.split('/').pop() |
| |
| if (basename && /^\.env(.|_)[\w.]+/.test(basename)) return true |
| if (basename && JUNK_BASENAMES.has(basename)) return true |
|
|
| |
| if (path.match(/^\/_next[^/]/) || path === '/_next/data' || path === '/_next/data/') { |
| return true |
| } |
|
|
| |
| |
| |
| if (path.startsWith('/_next/image')) { |
| return true |
| } |
|
|
| return false |
| } |
|
|
| export default function handleInvalidPaths( |
| req: ExtendedRequest, |
| res: Response, |
| next: NextFunction, |
| ) { |
| if (isJunkPath(req.path)) { |
| |
| |
| defaultCacheControl(res) |
| res.setHeader('content-type', 'text/plain') |
| res.status(404).send('Not found') |
| return |
| } |
|
|
| if (req.path.endsWith('/index.md')) { |
| defaultCacheControl(res) |
| |
| |
| const newUrl = req.originalUrl.replace(req.path, req.path.replace(/\/index\.md$/, '')) |
| return res.redirect(newUrl) |
| } else if (req.path.endsWith('.md')) { |
| |
| |
| |
| |
| const encodedPath = encodeURIComponent(req.path.replace(/\.md$/, '')) |
| .replace(/%2F/g, '/') |
| .replace(/%40/g, '@') |
| const newUrl = `/api/article/body?pathname=${encodedPath}` |
| res.redirect(newUrl) |
| return |
| } |
| return next() |
| } |
|
|