You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

117 lines
2.6 KiB

module.exports = preferredEncodings;
preferredEncodings.preferredEncodings = preferredEncodings;
function parseAcceptEncoding(accept) {
var acceptableEncodings;
if (accept) {
acceptableEncodings = accept.split(',').map(function(e, i) {
return parseEncoding(e.trim(), i);
});
} else {
acceptableEncodings = [];
}
if (!acceptableEncodings.some(function(e) {
return e && specify('identity', e);
})) {
/*
* If identity doesn't explicitly appear in the accept-encoding header,
* it's added to the list of acceptable encoding with the lowest q
*
*/
var lowestQ = 1;
for(var i = 0; i < acceptableEncodings.length; i++){
var e = acceptableEncodings[i];
if(e && e.q < lowestQ){
lowestQ = e.q;
}
}
acceptableEncodings.push({
encoding: 'identity',
q: lowestQ / 2,
});
}
return acceptableEncodings.filter(function(e) {
return e;
});
}
function parseEncoding(s, i) {
var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
if (!match) return null;
var encoding = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';');
for (var i = 0; i < params.length; i ++) {
var p = params[i].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
encoding: encoding,
q: q,
i: i
};
}
function getEncodingPriority(encoding, accepted) {
return (accepted.map(function(a) {
return specify(encoding, a);
}).filter(Boolean).sort(function (a, b) {
if(a.s == b.s) {
return a.q > b.q ? -1 : 1;
} else {
return a.s > b.s ? -1 : 1;
}
})[0] || {s: 0, q: 0});
}
function specify(encoding, spec) {
var s = 0;
if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
s |= 1;
} else if (spec.encoding !== '*' ) {
return null
}
return {
s: s,
q: spec.q,
}
};
function preferredEncodings(accept, provided) {
accept = parseAcceptEncoding(accept || '');
if (provided) {
return provided.map(function(type) {
return [type, getEncodingPriority(type, accept)];
}).filter(function(pair) {
return pair[1].q > 0;
}).sort(function(a, b) {
var pa = a[1];
var pb = b[1];
return (pb.q - pa.q) || (pb.s - pa.s) || (pa.i - pb.i);
}).map(function(pair) {
return pair[0];
});
} else {
return accept.sort(function (a, b) {
// revsort
return (b.q - a.q) || (a.i - b.i);
}).filter(function(type){
return type.q > 0;
}).map(function(type) {
return type.encoding;
});
}
}