Skip to content
This repository has been archived by the owner on Feb 28, 2022. It is now read-only.

Commit

Permalink
feat(html): enable setting of HTTP headers through link and meta HTML…
Browse files Browse the repository at this point in the history
… tags

fixes #122
  • Loading branch information
trieloff committed Apr 29, 2019
1 parent 59665f7 commit 32e4494
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
41 changes: 41 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"fs-extra": "^7.0.0",
"github-slugger": "^1.2.1",
"hast-to-hyperscript": "^7.0.0",
"hast-util-select": "^3.0.0",
"hast-util-to-html": "^5.0.0",
"hyperscript": "^2.0.2",
"js-yaml": "^3.13.1",
Expand Down
2 changes: 2 additions & 0 deletions src/defaults/html.pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const parseFrontmatter = require('../html/parse-frontmatter');
const rewriteLinks = require('../html/static-asset-links');
const tohast = require('../html/html-to-hast');
const tohtml = require('../html/stringify-hast');
const addHeaders = require('../html/add-headers');

/* eslint no-param-reassign: off */
/* eslint newline-per-chained-call: off */
Expand Down Expand Up @@ -67,6 +68,7 @@ const htmlpipe = (cont, payload, action) => {
.after(debug)
.after(tohast) // start HTML post-processing
.after(rewriteLinks).when(production)
.after(addHeaders)
.after(tohtml) // end HTML post-processing
.after(flag).expose('esi').when(esi) // flag ESI when there is ESI in the response
.error(selectStatus(production()));
Expand Down
42 changes: 42 additions & 0 deletions src/html/add-headers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2019 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

const { selectAll } = require('hast-util-select');

function addHeaders({ response: { headers, hast } }) {
const linkheaders = selectAll('link[rel][href]', hast).reduce((h, { properties: { href, rel } }) => {
if (!href.match(/<esi:include/)) {
// eslint-disable-next-line no-param-reassign
h.Link = `${h.Link ? `${h.Link},` : ''
}<${href}>; rel="${rel}"`;
}
return h;
}, headers);

const metaheaders = selectAll('meta[http-equiv][content]', hast).reduce((h, { properties: { httpEquiv, content } }) => {
const name = httpEquiv;
const value = content;
if (!h[name]) {
// eslint-disable-next-line no-param-reassign
h[name] = value;
}
return h;
}, linkheaders);

return {
response: {
headers: metaheaders,
},
};
}

module.exports = addHeaders;
63 changes: 63 additions & 0 deletions test/testHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,69 @@ const crequest = {
url: '/test/test.html',
};

describe('Testing HTML Pipeline in Production', () => {
let production;
before('Fake Production Mode', () => {
// eslint-disable-next-line no-underscore-dangle
production = process.env.__OW_ACTIVATION_ID;
// eslint-disable-next-line no-underscore-dangle
process.env.__OW_ACTIVATION_ID = 'fake';
});


it('html.pipe adds headers from meta and link tags', async () => {
const result = await pipe(
({ content }) => ({
response: {
status: 201,
headers: {
Foo: 'bar',
},
body: `<html>
<head>
<title>Hello World</title>
<meta http-equiv="Expires" content="3000">
<meta http-equiv="Foo" content="baz">
<meta http-equiv="Exceeds" value="3000">
<link rel="next" href="next.html" />
<link rel="stylesheet" href="style.css" />
<link rel="first" href="index.html" />
<link rel="previous" src="previous.html" />
</head>
<body>
${content.document.body.innerHTML}
</body>
</html>`,
},
}),
{
request: crequest,
content: {
body: 'Hello World',
},
},
{
request: { params },
secrets,
logger,
},
);

assert.equal(result.response.status, 201);
assert.equal(result.response.headers['Content-Type'], 'text/html', 'keeps content-type');
assert.equal(result.response.headers['X-ESI'], 'enabled', 'detects ESI');
assert.equal(result.response.headers.Expires, '3000', 'allows setting through meta http-equiv');
assert.equal(result.response.headers.Exceeds, undefined, 'ignores invalid meta tags');
assert.equal(result.response.headers.Foo, 'bar', 'does not override existing headers');
assert.equal(result.response.headers.Link, '<next.html>; rel="next",<index.html>; rel="first"', 'allows setting through link');
});

after('Reset Production Mode', () => {
// eslint-disable-next-line no-underscore-dangle
process.env.__OW_ACTIVATION_ID = production;
});
});

describe('Testing HTML Pipeline', () => {
setupPolly({
logging: false,
Expand Down

0 comments on commit 32e4494

Please sign in to comment.