-
-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathindex.js
72 lines (57 loc) · 1.6 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'use strict';
var qs = require('querystring')
, url = require('url')
, xtend = require('xtend');
const PARSE_LINK_HEADER_MAXLEN = parseInt(process.env.PARSE_LINK_HEADER_MAXLEN) || 2000;
const PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED = process.env.PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED != null
function hasRel(x) {
return x && x.rel;
}
function intoRels (acc, x) {
function splitRel (rel) {
acc[rel] = xtend(x, { rel: rel });
}
x.rel.split(/\s+/).forEach(splitRel);
return acc;
}
function createObjects (acc, p) {
// rel="next" => 1: rel 2: next
var m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/)
if (m) acc[m[1]] = m[2];
return acc;
}
function parseLink(link) {
try {
var m = link.match(/<?([^>]*)>(.*)/)
, linkUrl = m[1]
, parts = m[2].split(';')
, parsedUrl = url.parse(linkUrl)
, qry = qs.parse(parsedUrl.query);
parts.shift();
var info = parts
.reduce(createObjects, {});
info = xtend(qry, info);
info.url = linkUrl;
return info;
} catch (e) {
return null;
}
}
function checkHeader(linkHeader){
if (!linkHeader) return false;
if (linkHeader.length > PARSE_LINK_HEADER_MAXLEN) {
if (PARSE_LINK_HEADER_THROW_ON_MAXLEN_EXCEEDED) {
throw new Error('Input string too long, it should be under ' + PARSE_LINK_HEADER_MAXLEN + ' characters.');
} else {
return false;
}
}
return true;
}
module.exports = function (linkHeader) {
if (!checkHeader(linkHeader)) return null;
return linkHeader.split(/,\s*</)
.map(parseLink)
.filter(hasRel)
.reduce(intoRels, {});
};