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

Commit

Permalink
feat(add-headers): support meta http-equiv Link tag
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-guggisberg committed Nov 11, 2019
1 parent 5cacac8 commit 2f21440
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 12 deletions.
21 changes: 14 additions & 7 deletions src/html/add-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,27 @@

function addHeaders({ response: { headers, document } }) {
const linkHeader = [];
document.querySelectorAll('link').forEach(({ href, rel }) => {
document.querySelectorAll('link').forEach(({ href, rel, as }) => {
if (href && rel && !href.match(/<esi:include/)) {
linkHeader.push(`<${href}>; rel="${rel}"`);
if (as && rel.indexOf('preload' > -1)) {
// https://www.w3.org/TR/preload/#as-attribute
linkHeader.push(`<${href}>; rel="${rel}"; as="${as}"`);
} else {
linkHeader.push(`<${href}>; rel="${rel}"`);
}
}
});
if (linkHeader.length > 0) {
headers.Link = linkHeader.join();
}

document.querySelectorAll('meta').forEach(({ httpEquiv, content }) => {
if (httpEquiv && content && !headers[httpEquiv]) {
if (httpEquiv === 'Link') {
linkHeader.push(content);
} else if (httpEquiv && content && !headers[httpEquiv]) {
headers[httpEquiv] = content;
}
});

if (linkHeader.length > 0) {
headers.Link = linkHeader.join();
}
}

module.exports = addHeaders;
82 changes: 77 additions & 5 deletions test/testHTMLProduction.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('Testing HTML Pipeline in Production', () => {
});


it('html.pipe adds headers from meta and link tags', async () => {
it('html.pipe adds headers from meta tags', async () => {
const result = await pipe(
(context) => {
context.response = {
Expand All @@ -94,10 +94,7 @@ describe('Testing HTML Pipeline in Production', () => {
<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" />
<meta http-equiv="Link" content="</some_image.jpeg>; rel=preload; as=image" />
</head>
<body>
${context.content.document.body.innerHTML}
Expand All @@ -124,9 +121,84 @@ describe('Testing HTML Pipeline in Production', () => {
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, '</some_image.jpeg>; rel=preload; as=image', 'allows setting Link header through meta http-equiv');
});

it('html.pipe adds headers from link tags', async () => {
const result = await pipe(
(context) => {
context.response = {
status: 201,
headers: {
Foo: 'bar',
},
body: `<html>
<head>
<title>Hello World</title>
<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>
${context.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.Link, '<next.html>; rel="next",<index.html>; rel="first"', 'allows setting through link');
});

it('html.pipe propagates \'as\' attribute of link tags', async () => {
const result = await pipe(
(context) => {
context.response = {
status: 201,
headers: {
Foo: 'bar',
},
body: `<html>
<head>
<link rel="preload" href="/some_image.jpeg" as="image" />
<link rel="preload" href="/some_lib.js" as="script" />
</head>
<body>
${context.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.Link, '</some_image.jpeg>; rel=preload; as=image,</some_lib.js>; rel=preload; as=script', 'allows setting Link header through meta http-equiv');
});

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

0 comments on commit 2f21440

Please sign in to comment.