Ghost/core/server/middleware/serve-public-file.js

53 lines
2.0 KiB
JavaScript
Raw Normal View History

var crypto = require('crypto'),
fs = require('fs'),
path = require('path'),
config = require('../config'),
utils = require('../utils');
// ### servePublicFile Middleware
// Handles requests to robots.txt and favicon.ico (and caches them)
function servePublicFile(file, type, maxAge) {
var content,
publicFilePath = config.get('paths').publicFilePath,
Prep shared API URL util for use on external sites refs #5942, #6150 There were a few key problems I was looking to solve with this: - Introduce a single point of truth for what the URL for accessing the API should be - Provide a simple way to configure the utility (much like a true SDK) As of this commit, this utility is still automatically available in a Ghost theme. To use it on an external site, the code would look like: ``` <script type="text/javascript" src="http://my-ghost-blog.com/shared/ghost-url.min.js"></script> <script type="text/javascript"> ghost.init({ clientId: "<your-client-id>", clientSecret: "<your-client-secret>" }); </script> ``` To achieve this, there have been a number of changes: - A new `apiUrl` function has been added to config, which calculates the correct URL. This needs to be unified with the other url generation functions as a separate piece of work. - The serveSharedFile middleware has been updated, so that it can serve files from / or /shared and to substitute `{{api-url}}` as it does `{{blog-url}}`. - ghost-url.js and ghost-url.min.js have been updated to be served via the serveSharedFile middleware - ghost-url.js has been changed slightly, to take the url from an inline variable which is substituted the first time it is served - `{{ghost_head}}` has been updated, removing the api url handling which is now in config/url.js and removing the configuration of the utility in favour of calling `init()` after the script is required - `{{ghost_head}}` has also had the meta tags for client id and secret removed - tests have been updated
2015-12-15 13:41:53 +03:00
filePath,
blogRegex = /(\{\{blog-url\}\})/g,
apiRegex = /(\{\{api-url\}\})/g;
filePath = file.match(/^public/) ? path.join(publicFilePath, file.replace(/^public/, '')) : path.join(publicFilePath, file);
return function servePublicFile(req, res, next) {
Prep shared API URL util for use on external sites refs #5942, #6150 There were a few key problems I was looking to solve with this: - Introduce a single point of truth for what the URL for accessing the API should be - Provide a simple way to configure the utility (much like a true SDK) As of this commit, this utility is still automatically available in a Ghost theme. To use it on an external site, the code would look like: ``` <script type="text/javascript" src="http://my-ghost-blog.com/shared/ghost-url.min.js"></script> <script type="text/javascript"> ghost.init({ clientId: "<your-client-id>", clientSecret: "<your-client-secret>" }); </script> ``` To achieve this, there have been a number of changes: - A new `apiUrl` function has been added to config, which calculates the correct URL. This needs to be unified with the other url generation functions as a separate piece of work. - The serveSharedFile middleware has been updated, so that it can serve files from / or /shared and to substitute `{{api-url}}` as it does `{{blog-url}}`. - ghost-url.js and ghost-url.min.js have been updated to be served via the serveSharedFile middleware - ghost-url.js has been changed slightly, to take the url from an inline variable which is substituted the first time it is served - `{{ghost_head}}` has been updated, removing the api url handling which is now in config/url.js and removing the configuration of the utility in favour of calling `init()` after the script is required - `{{ghost_head}}` has also had the meta tags for client id and secret removed - tests have been updated
2015-12-15 13:41:53 +03:00
if (req.path === '/' + file) {
if (content) {
res.writeHead(200, content.headers);
res.end(content.body);
} else {
fs.readFile(filePath, function readFile(err, buf) {
if (err) {
return next(err);
}
Prep shared API URL util for use on external sites refs #5942, #6150 There were a few key problems I was looking to solve with this: - Introduce a single point of truth for what the URL for accessing the API should be - Provide a simple way to configure the utility (much like a true SDK) As of this commit, this utility is still automatically available in a Ghost theme. To use it on an external site, the code would look like: ``` <script type="text/javascript" src="http://my-ghost-blog.com/shared/ghost-url.min.js"></script> <script type="text/javascript"> ghost.init({ clientId: "<your-client-id>", clientSecret: "<your-client-secret>" }); </script> ``` To achieve this, there have been a number of changes: - A new `apiUrl` function has been added to config, which calculates the correct URL. This needs to be unified with the other url generation functions as a separate piece of work. - The serveSharedFile middleware has been updated, so that it can serve files from / or /shared and to substitute `{{api-url}}` as it does `{{blog-url}}`. - ghost-url.js and ghost-url.min.js have been updated to be served via the serveSharedFile middleware - ghost-url.js has been changed slightly, to take the url from an inline variable which is substituted the first time it is served - `{{ghost_head}}` has been updated, removing the api url handling which is now in config/url.js and removing the configuration of the utility in favour of calling `init()` after the script is required - `{{ghost_head}}` has also had the meta tags for client id and secret removed - tests have been updated
2015-12-15 13:41:53 +03:00
if (type === 'text/xsl' || type === 'text/plain' || type === 'application/javascript') {
buf = buf.toString().replace(blogRegex, utils.url.urlFor('home', true).replace(/\/$/, ''));
🔥✨ remove forceAdminSSL and urlSSL, add admin url (#7937) * 🔥 kill apiUrl helper, use urlFor helper instead More consistency of creating urls. Creates an easier ability to add config changes. Attention: urlFor function is getting a little nesty, BUT that is for now wanted to make easier and centralised changes to the configs. The url util need's refactoring anyway. * 🔥 urlSSL Remove all urlSSL usages. Add TODO's for the next commit to re-add logic for deleted logic. e.g. - cors helper generated an array of url's to allow requests from the defined config url's -> will be replaced by the admin url if available - theme handler prefered the urlSSL in case it was defined -> will be replaced by using the urlFor helper to get the blog url (based on the request secure flag) The changes in this commit doesn't have to be right, but it helped going step by step. The next commit is the more interesting one. * 🔥 ✨ remove forceAdminSSL, add new admin url and adapt logic I wanted to remove the forceAdminSSL as separate commit, but was hard to realise. That's why both changes are in one commit: 1. remove forceAdminSSL 2. add admin.url option - fix TODO's from last commits - rewrite the ssl middleware! - create some private helper functions in the url helper to realise the changes - rename some wordings and functions e.g. base === blog (we have so much different wordings) - i would like to do more, but this would end in a non readable PR - this commit contains the most important changes to offer admin.url option * 🤖 adapt tests IMPORTANT - all changes in the routing tests were needed, because each routing test did not start the ghost server - they just required the ghost application, which resulted in a random server port - having a random server port results in a redirect, caused by the ssl/redirect middleware * 😎 rename check-ssl middleware * 🎨 fix theme-handler because of master rebase
2017-02-03 21:13:22 +03:00
buf = buf.toString().replace(apiRegex, utils.url.urlFor('api', {cors: true}, true));
}
content = {
headers: {
'Content-Type': type,
'Content-Length': buf.length,
ETag: '"' + crypto.createHash('md5').update(buf, 'utf8').digest('hex') + '"',
'Cache-Control': 'public, max-age=' + maxAge
},
body: buf
};
res.writeHead(200, content.headers);
res.end(content.body);
});
}
} else {
next();
}
};
}
module.exports = servePublicFile;