mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-03 19:32:35 +02:00
Fix & refactor server routing + add tests (#799)
* Fix bad routing regex for sitemap & feed * add tests for sitemap & feed * use next middleware function if file nto found * add pages routing & test * refactor + add more test for page routing * extension-less url routing + test * refactor out requestFile * add dot routing + test to handle special case like http://localhost:3000/blog/2018/05/27/1.13.0 * exit properly * add more test for sitemap * update nits from my phone
This commit is contained in:
parent
e9f290f788
commit
e9eef39760
3 changed files with 231 additions and 37 deletions
|
@ -20,7 +20,15 @@ function execute(port, options) {
|
|||
const path = require('path');
|
||||
const color = require('color');
|
||||
const getTOC = require('../core/getTOC');
|
||||
const {docsRouting, blogRouting} = require('../core/routing');
|
||||
const {
|
||||
blogRouting,
|
||||
docsRouting,
|
||||
dotRouting,
|
||||
feedRouting,
|
||||
pageRouting,
|
||||
noExtRouting,
|
||||
sitemapRouting,
|
||||
} = require('../core/routing');
|
||||
const mkdirp = require('mkdirp');
|
||||
const glob = require('glob');
|
||||
const chalk = require('chalk');
|
||||
|
@ -123,6 +131,24 @@ function execute(port, options) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function requestFile(url, res, notFoundCallback) {
|
||||
request.get(url, (error, response, body) => {
|
||||
if (!error) {
|
||||
if (response) {
|
||||
if (response.statusCode === 404 && notFoundCallback) {
|
||||
notFoundCallback();
|
||||
} else {
|
||||
res.status(response.statusCode).send(body);
|
||||
}
|
||||
} else {
|
||||
console.error('No response');
|
||||
}
|
||||
} else {
|
||||
console.error('Request failed:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
reloadMetadata();
|
||||
|
@ -257,7 +283,7 @@ function execute(port, options) {
|
|||
res.send(renderToStaticMarkupWithDoctype(docComp));
|
||||
});
|
||||
|
||||
app.get('/sitemap.xml', function(req, res) {
|
||||
app.get(sitemapRouting(siteConfig.baseUrl), (req, res) => {
|
||||
res.set('Content-Type', 'application/xml');
|
||||
|
||||
sitemap(xml => {
|
||||
|
@ -265,18 +291,22 @@ function execute(port, options) {
|
|||
});
|
||||
});
|
||||
|
||||
app.get(/blog\/.*xml$/, (req, res) => {
|
||||
app.get(feedRouting(siteConfig.baseUrl), (req, res, next) => {
|
||||
res.set('Content-Type', 'application/rss+xml');
|
||||
let parts = req.path.toString().split('blog/');
|
||||
if (parts[1].toLowerCase() == 'atom.xml') {
|
||||
let file = req.path
|
||||
.toString()
|
||||
.split('blog/')[1]
|
||||
.toLowerCase();
|
||||
if (file === 'atom.xml') {
|
||||
res.send(feed('atom'));
|
||||
return;
|
||||
} else if (file === 'feed.xml') {
|
||||
res.send(feed('rss'));
|
||||
}
|
||||
res.send(feed('rss'));
|
||||
next();
|
||||
});
|
||||
|
||||
// Handle all requests for blog pages and posts.
|
||||
app.get(blogRouting(siteConfig.baseUrl), (req, res) => {
|
||||
app.get(blogRouting(siteConfig.baseUrl), (req, res, next) => {
|
||||
// Regenerate the blog metadata in case it has changed. Consider improving
|
||||
// this to regenerate on file save rather than on page request.
|
||||
reloadMetadataBlog();
|
||||
|
@ -330,6 +360,11 @@ function execute(port, options) {
|
|||
file = file.replace(new RegExp('/', 'g'), '-');
|
||||
file = join(CWD, 'blog', file);
|
||||
|
||||
if (!fs.existsSync(file)) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
const result = metadataUtils.extractMetadata(
|
||||
fs.readFileSync(file, {encoding: 'utf8'})
|
||||
);
|
||||
|
@ -361,7 +396,7 @@ function execute(port, options) {
|
|||
});
|
||||
|
||||
// handle all other main pages
|
||||
app.get('*.html', (req, res, next) => {
|
||||
app.get(pageRouting(siteConfig.baseUrl), (req, res, next) => {
|
||||
// look for user provided html file first
|
||||
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
|
||||
htmlFile = join(CWD, 'pages', htmlFile);
|
||||
|
@ -394,6 +429,7 @@ function execute(port, options) {
|
|||
} else {
|
||||
res.send(fs.readFileSync(htmlFile, {encoding: 'utf8'}));
|
||||
}
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -535,36 +571,30 @@ function execute(port, options) {
|
|||
|
||||
// "redirect" requests to pages ending with "/" or no extension so that,
|
||||
// for example, request to "blog" returns "blog/index.html" or "blog.html"
|
||||
app.get(/\/[^\.]*\/?$/, (req, res) => {
|
||||
const requestFile = (url, notFoundCallback) => {
|
||||
request.get(url, (error, response, body) => {
|
||||
if (!error) {
|
||||
if (response) {
|
||||
if (response.statusCode === 404 && notFoundCallback) {
|
||||
notFoundCallback();
|
||||
} else {
|
||||
res.status(response.statusCode).send(body);
|
||||
}
|
||||
} else {
|
||||
console.error('No response');
|
||||
}
|
||||
} else {
|
||||
console.error('Request failed:', error);
|
||||
}
|
||||
});
|
||||
};
|
||||
app.get(noExtRouting(), (req, res, next) => {
|
||||
let slash = req.path.toString().endsWith('/') ? '' : '/';
|
||||
let requestUrl = 'http://localhost:' + port + req.path;
|
||||
requestFile(requestUrl + slash + 'index.html', () => {
|
||||
requestFile(requestUrl + slash + 'index.html', res, () => {
|
||||
requestFile(
|
||||
slash === '/'
|
||||
? requestUrl + '.html'
|
||||
: requestUrl.replace(/\/$/, '.html'),
|
||||
null
|
||||
res,
|
||||
next
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// handle special cleanUrl case like '/blog/1.2.3' & '/blog.robots.hai'
|
||||
// where we should try to serve 'blog/1.2.3.html' & '/blog.robots.hai.html'
|
||||
app.get(dotRouting(), (req, res, next) => {
|
||||
if (!siteConfig.cleanUrl) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
requestFile('http://localhost:' + port + req.path + '.html', res, next);
|
||||
});
|
||||
|
||||
if (options.watch) startLiveReload();
|
||||
app.listen(port);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue