Skip to content
This repository has been archived by the owner on Jan 12, 2023. It is now read-only.

Commit

Permalink
fix(static): normalize URLs in rewritten CSS and JS
Browse files Browse the repository at this point in the history
  • Loading branch information
trieloff committed Apr 26, 2019
1 parent a6d96b8 commit f238adb
Showing 1 changed file with 51 additions and 47 deletions.
98 changes: 51 additions & 47 deletions static.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,61 +97,62 @@ function isBinary(type) {
return true;
}

function rewriteImports(tree) {
tree.walkAtRules('import', (rule) => {
if (rule.name === 'import') {
const [url, queries] = space(rule.params);
const parsedurl = parser(url);
if (parsedurl.nodes
&& parsedurl.nodes.length === 1
&& parsedurl.nodes[0].value === 'url'
&& parsedurl.nodes[0].nodes
&& parsedurl.nodes[0].nodes.length === 1
&& parsedurl.nodes[0].nodes[0].type === 'string'
&& typeof parsedurl.nodes[0].nodes[0].value === 'string'
&& typeof parsedurl.nodes[0].nodes[0].quote === 'string') {
const importuri = uri.parse(parsedurl.nodes[0].nodes[0].value);
const { quote } = parsedurl.nodes[0].nodes[0];
if (importuri.reference === 'relative' && !importuri.query) {
rule.replaceWith(postcss.atRule({
name: 'import',
params: `url(${quote}<esi:include src="${importuri.path}.esi"/><esi:remove>${importuri.path}</esi:remove>${quote}) ${queries}`,
}));
}
} else if (parsedurl.nodes
&& parsedurl.nodes[0].type === 'string'
&& typeof parsedurl.nodes[0].value === 'string'
&& typeof parsedurl.nodes[0].quote === 'string') {
const importuri = uri.parse(parsedurl.nodes[0].value);
const { quote } = parsedurl.nodes[0];
if (importuri.reference === 'relative' && !importuri.query) {
rule.replaceWith(postcss.atRule({
name: 'import',
params: `${quote}<esi:include src="${importuri.path}.esi"/><esi:remove>${importuri.path}</esi:remove>${quote} ${queries}`,
}));
function rewriteCSS(css, base = '') {
function rewriteImports(tree) {
tree.walkAtRules('import', (rule) => {
if (rule.name === 'import') {
const [url, queries] = space(rule.params);
const parsedurl = parser(url);
if (parsedurl.nodes
&& parsedurl.nodes.length === 1
&& parsedurl.nodes[0].value === 'url'
&& parsedurl.nodes[0].nodes
&& parsedurl.nodes[0].nodes.length === 1
&& parsedurl.nodes[0].nodes[0].type === 'string'
&& typeof parsedurl.nodes[0].nodes[0].value === 'string'
&& typeof parsedurl.nodes[0].nodes[0].quote === 'string') {
const importuri = uri.parse(parsedurl.nodes[0].nodes[0].value);
const { quote } = parsedurl.nodes[0].nodes[0];
if (importuri.reference === 'relative' && !importuri.query) {
rule.replaceWith(postcss.atRule({
name: 'import',
params: `url(${quote}<esi:include src="${importuri.path}.esi"/><esi:remove>${importuri.path}</esi:remove>${quote}) ${queries}`,
}));
}
} else if (parsedurl.nodes
&& parsedurl.nodes[0].type === 'string'
&& typeof parsedurl.nodes[0].value === 'string'
&& typeof parsedurl.nodes[0].quote === 'string') {
const importuri = uri.parse(parsedurl.nodes[0].value);
const { quote } = parsedurl.nodes[0];
if (importuri.reference === 'relative' && !importuri.query) {
rule.replaceWith(postcss.atRule({
name: 'import',
params: `${quote}<esi:include src="${uri.resolve(base, importuri.path)}.esi"/><esi:remove>${importuri.path}</esi:remove>${quote} ${queries}`,
}));
}
}
}
}
});
return tree;
}
});
return tree;
}


function rewriteCSS(css) {
const processor = postcss()
.use(rewriteImports)
.use(postcssurl({
url: (asset) => {
// TODO pass in request URL and make it absolute.
if (asset.search === '' && asset.absolutePath !== '.' && asset.relativePath !== '.') {
return `<esi:include src="${asset.relativePath}.esi"/><esi:remove>${asset.relativePath}</esi:remove>`;
return `<esi:include src="${uri.resolve(base, asset.relativePath)}.esi"/><esi:remove>${asset.relativePath}</esi:remove>`;
}
return asset.url;
},
}));
return processor.process(css, { from: undefined }).then(result => result.css);
}

function rewriteJavaScript(javascript) {
function rewriteJavaScript(javascript, base = '') {
const importmap = {};

function rewriteJSImports(bab) {
Expand All @@ -169,7 +170,7 @@ function rewriteJavaScript(javascript) {
const { specifiers } = path.node;
// console.log(srcuri);
const h = ohash(srcuri.path);
importmap[h] = `<esi:include src="${srcuri.path}.esi"/><esi:remove>${path.node.source.value}</esi:remove>`;
importmap[h] = `<esi:include src="${uri.resolve(base, srcuri.path)}.esi"/><esi:remove>${path.node.source.value}</esi:remove>`;
path.replaceWith(t.importDeclaration(specifiers, t.stringLiteral(h)));
}
}
Expand All @@ -194,18 +195,18 @@ function isJSON(type) {
return !!type.match(/json/);
}

function getBody(type, responsebody, esi = false) {
function getBody(type, responsebody, esi = false, entry) {
if (isBinary(type)) {
return Buffer.from(responsebody).toString('base64');
}
if (isJSON(type)) {
return JSON.parse(responsebody);
}
if (esi && isCSS(type)) {
return rewriteCSS(responsebody.toString());
return rewriteCSS(responsebody.toString(), entry);
}
if (esi && isJavaScript(type)) {
return rewriteJavaScript(responsebody.toString());
return rewriteJavaScript(responsebody.toString(), entry);
}
return responsebody.toString();
}
Expand All @@ -229,6 +230,7 @@ function deliverPlain(owner, repo, ref, entry, root, esi = false) {
const cleanentry = (`${root}/${entry}`).replace(/^\//, '').replace(/[/]+/g, '/');
console.log('deliverPlain()', owner, repo, ref, cleanentry);
const url = `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${cleanentry}`;
console.log(url);
const rawopts = {
url,
headers: {
Expand All @@ -243,14 +245,14 @@ function deliverPlain(owner, repo, ref, entry, root, esi = false) {
const size = parseInt(response.headers['content-length'], 10);
console.log('size', size);
if (size < REDIRECT_LIMIT) {
const body = await getBody(type, response.body, esi);
const body = await getBody(type, response.body, esi, entry);
console.log(`delivering file ${cleanentry} type ${type} binary: ${isBinary(type)}`);
return {
statusCode: 200,
headers: addHeaders({
'Content-Type': type,
'X-Static': 'Raw/Static',
'X-ESI': esi ? 'enabled' : undefined
'X-ESI': esi ? 'enabled' : undefined,
}, ref, response.body),
body,
};
Expand Down Expand Up @@ -324,12 +326,14 @@ async function main({
}) {
console.log('main()', owner, repo, ref, path, entry, strain, plain, allow, deny, root);

if (blacklisted(path, allow, deny) || blacklisted(entry, allow, deny)) {
const file = uri.normalize(entry);
console.log(file);
if (blacklisted(file, allow, deny) || blacklisted(file, allow, deny)) {
return forbidden();
}

if (plain) {
return deliverPlain(owner, repo, ref, entry, root, esi);
return deliverPlain(owner, repo, ref, file, root, esi);
}

return forbidden();
Expand Down

0 comments on commit f238adb

Please sign in to comment.