route.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. 'use strict';
  2. const pathFn = require('path');
  3. const mime = require('mime');
  4. module.exports = function(app) {
  5. const { config, route } = this;
  6. const { args = {} } = this.env;
  7. const { root } = config;
  8. if (args.s || args.static) return;
  9. const { pretty_urls } = config;
  10. const { trailing_index, trailing_html } = pretty_urls ? pretty_urls : {};
  11. app.use(root, (req, res, next) => {
  12. const { method, url: requestUrl } = req;
  13. if (method !== 'GET' && method !== 'HEAD') return next();
  14. let url = route.format(decodeURIComponent(requestUrl));
  15. let data = route.get(url);
  16. let extname = pathFn.extname(url);
  17. if (!data) {
  18. if (route.get(url + '.html')) {
  19. // location `foo/bar.html`; request `foo/bar`; proxy to the location
  20. extname = '.html';
  21. data = route.get(url + extname);
  22. res.setHeader('Content-Type', 'text/html');
  23. req.url = encodeURI('/' + url + extname);
  24. data.pipe(res).on('error', next);
  25. return;
  26. } else if (route.get(url + '/index.html')) {
  27. // location `foo/index.html`; request `foo`; redirect to `foo/`
  28. url = encodeURI(url);
  29. res.statusCode = 301;
  30. res.setHeader('Location', `${root + url}/`);
  31. res.end('Redirecting');
  32. return;
  33. } else if (route.get(url.replace(/\/index\.html$/i, '') + '.html')) {
  34. // location `foo/bar.html`; request `foo/bar/`; redirect to `foo`
  35. // request with trailing slash is appended with index.html by route.format()
  36. url = encodeURI(url.replace(/\/index\.html$/i, ''));
  37. res.statusCode = 301;
  38. res.setHeader('Location', root + url);
  39. res.end('Redirecting');
  40. return;
  41. } return next();
  42. }
  43. if (trailing_html === false && !requestUrl.endsWith('/index.html') && requestUrl.endsWith('.html')) {
  44. // location `foo/bar.html`; request `foo/bar.html`; redirect to `foo/bar`
  45. url = encodeURI(url.replace(/\.html$/i, ''));
  46. res.statusCode = 301;
  47. res.setHeader('Location', root + url);
  48. res.end('Redirecting');
  49. return;
  50. } else if (trailing_index === false && requestUrl.endsWith('/index.html')) {
  51. // location `foo/index.html`; request `foo/index.html`; redirect to `foo/`
  52. url = encodeURI(url.replace(/index\.html$/i, ''));
  53. res.statusCode = 301;
  54. res.setHeader('Location', root + url);
  55. res.end('Redirecting');
  56. return;
  57. }
  58. res.setHeader('Content-Type', extname ? mime.getType(extname) : 'application/octet-stream');
  59. if (method === 'GET') {
  60. data.pipe(res).on('error', next);
  61. } else {
  62. res.end();
  63. }
  64. });
  65. };