-
Notifications
You must be signed in to change notification settings - Fork 140
(perf): improve parsing of link header from fragments #248
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
'use strict'; | ||
/** | ||
* Parse link headers | ||
* '<http://example.com/script.js>; rel="fragment-script"' | ||
* | ||
* [ | ||
* { | ||
* rel: "fragment-script", | ||
* uri: "http://localhost:8080/script.js" | ||
* } | ||
* ] | ||
* | ||
* Based on code from parse-link-header! | ||
* https://github.com/thlorenz/parse-link-header/blob/master/index.js | ||
*/ | ||
module.exports = function parseLinkHeader(linkHeader) { | ||
const assets = linkHeader | ||
.split(/,\s*</) | ||
.map(link => { | ||
const match = link.match(/<?([^>]*)>(.*)/); | ||
if (!match) { | ||
return null; | ||
} | ||
const linkUrl = match[1]; | ||
const parts = match[2].split(';'); | ||
parts.shift(); | ||
return { | ||
uri: linkUrl, | ||
rel: getRelValue(parts[0]) | ||
}; | ||
}) | ||
.filter(v => v && v.rel != null) | ||
.reduce((acc, curr) => { | ||
return acc.concat(curr); | ||
}, []); | ||
|
||
return assets; | ||
}; | ||
|
||
/** | ||
* Get the value of rel attribute | ||
* | ||
* rel="fragment-script" -> ["rel", "fragment-script"] | ||
*/ | ||
function getRelValue(parts) { | ||
const m = parts.match(/\s*(.+)\s*=\s*"?([^"]+)"?/); | ||
if (!m) { | ||
return null; | ||
} | ||
return m[2]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
'use strict'; | ||
|
||
const parseLinkHeader = require('../lib/parse-link-header'); | ||
const assert = require('assert'); | ||
|
||
describe('Parse Link Header', () => { | ||
it('returns uri and rel of the passed header', () => { | ||
const linkHeader = | ||
'<http://a.com/app.js>; rel="script",<http://a.com/app.css>; rel="stylesheet"'; | ||
|
||
assert.deepStrictEqual(parseLinkHeader(linkHeader), [ | ||
{ uri: 'http://a.com/app.js', rel: 'script' }, | ||
{ uri: 'http://a.com/app.css', rel: 'stylesheet' } | ||
]); | ||
}); | ||
|
||
it('ignore attributes other than rel and uri', () => { | ||
const linkHeader = | ||
'<http://a.com/app.js>; rel="script"; crossorigin="anonymous"'; | ||
|
||
assert.deepStrictEqual(parseLinkHeader(linkHeader), [ | ||
{ uri: 'http://a.com/app.js', rel: 'script' } | ||
]); | ||
}); | ||
|
||
it('filters invalid header links', () => { | ||
const linkHeader = 'http://a.com/app.js; rel="script"'; | ||
|
||
assert.deepStrictEqual(parseLinkHeader(linkHeader), []); | ||
}); | ||
|
||
it('filters invalid rel attributes', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is an invalid rel attr? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ofcourse you can lol. its valid. But wont be loaded because of the check in getFragmentAssetUris. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But the test if for rel="" and no rel attribute at all. do you have any better naming suggestion if its confusing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe it could be rephrased... but it is fine. |
||
const linkHeader = | ||
'<http://a.com/app.js>; rel="script";, <http://a.com/app1.css>; rel="stylesheet", <http://a.com/app2.css>;, <http://a.com/app3.css>; rel=""'; | ||
|
||
assert.deepStrictEqual(parseLinkHeader(linkHeader), [ | ||
{ uri: 'http://a.com/app.js', rel: 'script' }, | ||
{ uri: 'http://a.com/app1.css', rel: 'stylesheet' } | ||
]); | ||
}); | ||
|
||
it('do not modify query parms in link urls', () => { | ||
const linkHeader = '<http://a.com/app.js?nocache=1>; rel="script";'; | ||
|
||
assert.deepStrictEqual(parseLinkHeader(linkHeader), [ | ||
{ uri: 'http://a.com/app.js?nocache=1', rel: 'script' } | ||
]); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Why put this in utils, is it used anywhere else?
Are we planning to add this to the exported API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, I can move inside fragment.js