-
-
Save niallo/3109252 to your computer and use it in GitHub Desktop.
/* | |
* parse_link_header() | |
* | |
* Parse the Github Link HTTP header used for pageination | |
* http://developer.github.com/v3/#pagination | |
*/ | |
function parse_link_header(header) { | |
if (header.length == 0) { | |
throw new Error("input must not be of zero length"); | |
} | |
// Split parts by comma | |
var parts = header.split(','); | |
var links = {}; | |
// Parse each part into a named link | |
_.each(parts, function(p) { | |
var section = p.split(';'); | |
if (section.length != 2) { | |
throw new Error("section could not be split on ';'"); | |
} | |
var url = section[0].replace(/<(.*)>/, '$1').trim(); | |
var name = section[1].replace(/rel="(.*)"/, '$1').trim(); | |
links[name] = url; | |
}); | |
return links; | |
} |
No, this code won't work for headers with links that contain ,
or ;
.
FOR THOSE WHO NEED IT WITHOUT JQUERY
function parse_link_header(header) {
if (header.length == 0) {
throw new Error("input must not be of zero length");
}
// Split parts by comma
var parts = header.split(',');
var links = {};
// Parse each part into a named link
for(i=0;i<parts.length;i++)
{
var section = parts[i].split(';');
if (section.length != 2) {
throw new Error("section could not be split on ';'");
}
var url = section[0].replace(/<(.)>/, '$1').trim();
var name = section[1].replace(/rel="(.)"/, '$1').trim();
links[name] = url;
}
return links;
}
Put @Gilmargolin 's code inside a code block for readability and fixed it up. No jquery or underscore here.
function parse_link_header(header) {
if (header.length === 0) {
throw new Error("input must not be of zero length");
}
// Split parts by comma
var parts = header.split(',');
var links = {};
// Parse each part into a named link
for(var i=0; i<parts.length; i++) {
var section = parts[i].split(';');
if (section.length !== 2) {
throw new Error("section could not be split on ';'");
}
var url = section[0].replace(/<(.*)>/, '$1').trim();
var name = section[1].replace(/rel="(.*)"/, '$1').trim();
links[name] = url;
}
return links;
}
If someone needs this the PHP way...:
function parseLinkHeader($header) {
if (strlen($header) == 0) {
throw new \Exception("input must not be of zero length");
}
$parts = explode(',', $header);
$links = [];
foreach($parts as $p) {
$section = explode(';', $p);
if (count($section) != 2) {
throw new \Exception("section could not be split on ';'");
}
$url = trim(preg_replace("/<(.*)>/", '$1', $section[0]));
$name = trim(preg_replace("/rel=\"(.*)\"/", '$1', $section[1]));
$links[$name] = $url;
}
return $links;
}
parse_link_header
doesn't work with:
'<http://mementoweb.org/wikipedia/>;rel="original", <http://mementoarchive.lanl.gov/twa/memento/20130919212835/http://mementoweb.org/wikipedia/>;rel="memento"; datetime="Thu, 19 Sep 2013 21:28:35 GMT", <http://mementoarchive.lanl.gov/twa/memento/20160920160128/http://mementoweb.org/wikipedia/>;rel="memento last"; datetime="Tue, 20 Sep 2016 16:01:28 GMT", <http://mementoarchive.lanl.gov/twa/memento/20130912190257/http://mementoweb.org/wikipedia/>;rel="memento first"; datetime="Thu, 12 Sep 2013 19:02:57 GMT", <http://mementoarchive.lanl.gov/twa/memento/20130919220632/http://mementoweb.org/wikipedia/>;rel="memento next"; datetime="Thu, 19 Sep 2013 22:06:32 GMT", <http://mementoarchive.lanl.gov/twa/memento/20130919212641/http://mementoweb.org/wikipedia/>;rel="memento prev"; datetime="Thu, 19 Sep 2013 21:26:41 GMT" , <http://mementoarchive.lanl.gov/twa/timemap/link/http://mementoweb.org/wikipedia/>;rel="timemap"; type="application/link-format" , <http://mementoarchive.lanl.gov/twa/timegate/http://mementoweb.org/wikipedia/>;rel="timegate"'
.
I'm using parse-link-header.
Handle the comma inside quotes with lookahead/lookbehind (only works on JS engines that support it)
function parseLinkHeader(header) {
if (header.length === 0) {
throw new Error("input must not be of zero length");
}
// Split parts by comma and parse each part into a named link
return header.split(/(?!\B"[^"]*),(?![^"]*"\B)/).reduce((links, part) => {
const section = part.split(/(?!\B"[^"]*);(?![^"]*"\B)/);
if (section.length < 2) {
throw new Error("section could not be split on ';'");
}
const url = section[0].replace(/<(.*)>/, '$1').trim();
const name = section[1].replace(/rel="(.*)"/, '$1').trim();
links[name] = url;
return links;
}, {});
}
Can't it be as simple as?
function parseLink(s) {
const output = {};
const regex = /<([^>]+)>; rel="([^"]+)"/g;
let m;
while (m = regex.exec(s)) {
const [_, v, k] = m;
output[k] = v;
}
return output;
}
Usage: parseLink(headers.get("link"))
There is a package for this github-parse-link
Lodash:
const links = _.chain(link)
.split(',')
.map(link => {
return {
ref: link.split(';')[1].replace(/rel="(.*)"/, '$1').trim(),
url: link.split(';')[0].replace(/<(.*)>/, '$1').trim(),
}
})
.keyBy('ref')
.mapValues('url')
.value()
Do you know if this can be used for parsing general (non gh specific) link headers?