* Middleware overhaul! - Remove unnecessary 'async' keywords from middleware functions - Ensure all middleware functions we create have names - Wrap the method contents of all async middleware functions in a try-catch+next(error) pattern * Use asyncMiddleware wrapper instead of try-catch+next(error) pattern * Remove unnecessary try-catch+next(error) pattern from context middleware
56 lines
2.0 KiB
JavaScript
56 lines
2.0 KiB
JavaScript
const patterns = require('../../lib/patterns')
|
|
const { URL } = require('url')
|
|
|
|
module.exports = function handleRedirects (req, res, next) {
|
|
// never redirect assets
|
|
if (patterns.assetPaths.test(req.path)) return next()
|
|
|
|
// blanket redirects for languageless homepage to English homepage
|
|
if (req.path === '/') {
|
|
return res.redirect(301, '/en')
|
|
}
|
|
|
|
// begin redirect handling
|
|
let redirect = req.path
|
|
let queryParams = req._parsedUrl.query
|
|
|
|
// update old-style query params (#9467)
|
|
// have to do this now because searchPath replacement changes the path as well as the query params
|
|
if (queryParams) {
|
|
queryParams = '?' + queryParams.replace('q=', 'query=')
|
|
redirect = (redirect + queryParams).replace(patterns.searchPath, '$1')
|
|
}
|
|
|
|
// remove query params temporarily so we can find the path in the redirects object
|
|
let redirectWithoutQueryParams = removeQueryParams(redirect)
|
|
|
|
// look for a redirect in the global object
|
|
// for example, given an incoming path /v3/activity/event_types
|
|
// find /en/developers/webhooks-and-events/github-event-types
|
|
redirectWithoutQueryParams = req.context.redirects[redirectWithoutQueryParams] || redirectWithoutQueryParams
|
|
|
|
// add query params back in
|
|
redirect = queryParams ? redirectWithoutQueryParams + queryParams : redirectWithoutQueryParams
|
|
|
|
// do not redirect a path to itself
|
|
// req._parsedUrl.path includes query params whereas req.path does not
|
|
if (redirect === req._parsedUrl.path) return next()
|
|
|
|
// do not redirect if the redirected page can't be found
|
|
if (!req.context.pages[removeQueryParams(redirect)]) {
|
|
// display error on the page in development, but not in production
|
|
// include final full redirect path in the message
|
|
if (process.env.NODE_ENV !== 'production' && req.context) {
|
|
req.context.redirectNotFound = redirect
|
|
}
|
|
return next()
|
|
}
|
|
|
|
// do the redirect!
|
|
return res.redirect(301, redirect)
|
|
}
|
|
|
|
function removeQueryParams (redirect) {
|
|
return new URL(redirect, 'https://docs.github.com').pathname
|
|
}
|