Socket
Socket
Sign inDemoInstall

negotiator

Package Overview
Dependencies
0
Maintainers
3
Versions
26
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.5.3 to 0.6.0

14

HISTORY.md

@@ -0,1 +1,15 @@

0.6.0 / 2015-09-29
==================
* Fix including type extensions in parameters in `Accept` parsing
* Fix parsing `Accept` parameters with quoted equals
* Fix parsing `Accept` parameters with quoted semicolons
* Lazy-load modules from main entry point
* perf: delay type concatenation until needed
* perf: enable strict mode
* perf: hoist regular expressions
* perf: remove closures getting spec properties
* perf: remove a closure from media type parsing
* perf: remove property delete from media type parsing
0.5.3 / 2015-05-10

@@ -2,0 +16,0 @@ ==================

72

index.js

@@ -0,10 +1,32 @@

/*!
* negotiator
* Copyright(c) 2012 Federico Romero
* Copyright(c) 2012-2014 Isaac Z. Schlueter
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
var preferredCharsets = require('./lib/charset');
var preferredEncodings = require('./lib/encoding');
var preferredLanguages = require('./lib/language');
var preferredMediaTypes = require('./lib/mediaType');
'use strict';
/**
* Cached loaded submodules.
* @private
*/
var modules = Object.create(null);
/**
* Module exports.
* @public
*/
module.exports = Negotiator;
Negotiator.Negotiator = Negotiator;
module.exports.Negotiator = Negotiator;
/**
* Create a Negotiator instance from a request.
* @param {object} request
* @public
*/
function Negotiator(request) {

@@ -24,2 +46,3 @@ if (!(this instanceof Negotiator)) {

Negotiator.prototype.charsets = function charsets(available) {
var preferredCharsets = loadModule('charset').preferredCharsets;
return preferredCharsets(this.request.headers['accept-charset'], available);

@@ -34,2 +57,3 @@ };

Negotiator.prototype.encodings = function encodings(available) {
var preferredEncodings = loadModule('encoding').preferredEncodings;
return preferredEncodings(this.request.headers['accept-encoding'], available);

@@ -44,2 +68,3 @@ };

Negotiator.prototype.languages = function languages(available) {
var preferredLanguages = loadModule('language').preferredLanguages;
return preferredLanguages(this.request.headers['accept-language'], available);

@@ -54,2 +79,3 @@ };

Negotiator.prototype.mediaTypes = function mediaTypes(available) {
var preferredMediaTypes = loadModule('mediaType').preferredMediaTypes;
return preferredMediaTypes(this.request.headers.accept, available);

@@ -67,1 +93,37 @@ };

Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes;
/**
* Load the given module.
* @private
*/
function loadModule(moduleName) {
var module = modules[moduleName];
if (module !== undefined) {
return module;
}
// This uses a switch for static require analysis
switch (moduleName) {
case 'charset':
module = require('./lib/charset');
break;
case 'encoding':
module = require('./lib/encoding');
break;
case 'language':
module = require('./lib/language');
break;
case 'mediaType':
module = require('./lib/mediaType');
break;
default:
throw new Error('Cannot find module \'' + moduleName + '\'');
}
// Store to prevent invoking require()
modules[moduleName] = module;
return module;
}

@@ -0,4 +1,31 @@

/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredCharsets;
preferredCharsets.preferredCharsets = preferredCharsets;
module.exports.preferredCharsets = preferredCharsets;
/**
* Module variables.
* @private
*/
var simpleCharsetRegExp = /^\s*(\S+?)\s*(?:;(.*))?$/;
/**
* Parse the Accept-Charset header.
* @private
*/
function parseAcceptCharset(accept) {

@@ -21,4 +48,9 @@ var accepts = accept.split(',');

function parseCharset(s, i) {
var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
/**
* Parse a charset from the Accept-Charset header.
* @private
*/
function parseCharset(str, i) {
var match = simpleCharsetRegExp.exec(str);
if (!match) return null;

@@ -46,2 +78,7 @@

/**
* Get the priority of a charset.
* @private
*/
function getCharsetPriority(charset, accepted, index) {

@@ -61,2 +98,7 @@ var priority = {o: -1, q: 0, s: 0};

/**
* Get the specificity of the charset.
* @private
*/
function specify(charset, spec, index) {

@@ -78,2 +120,7 @@ var s = 0;

/**
* Get the preferred charsets from an Accept-Charset header.
* @public
*/
function preferredCharsets(accept, provided) {

@@ -85,5 +132,6 @@ // RFC 2616 sec 14.2: no header = *

// sorted list of all charsets
return accepts.filter(isQuality).sort(compareSpecs).map(function getCharset(spec) {
return spec.charset;
});
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullCharset);
}

@@ -101,2 +149,7 @@

/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {

@@ -106,4 +159,18 @@ return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;

/**
* Get full charset string.
* @private
*/
function getFullCharset(spec) {
return spec.charset;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}

@@ -0,4 +1,31 @@

/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredEncodings;
preferredEncodings.preferredEncodings = preferredEncodings;
module.exports.preferredEncodings = preferredEncodings;
/**
* Module variables.
* @private
*/
var simpleEncodingRegExp = /^\s*(\S+?)\s*(?:;(.*))?$/;
/**
* Parse the Accept-Encoding header.
* @private
*/
function parseAcceptEncoding(accept) {

@@ -37,5 +64,9 @@ var accepts = accept.split(',');

function parseEncoding(s, i) {
var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
/**
* Parse an encoding from the Accept-Encoding header.
* @private
*/
function parseEncoding(str, i) {
var match = simpleEncodingRegExp.exec(str);
if (!match) return null;

@@ -63,2 +94,7 @@

/**
* Get the priority of an encoding.
* @private
*/
function getEncodingPriority(encoding, accepted, index) {

@@ -78,2 +114,7 @@ var priority = {o: -1, q: 0, s: 0};

/**
* Get the specificity of the encoding.
* @private
*/
function specify(encoding, spec, index) {

@@ -95,2 +136,7 @@ var s = 0;

/**
* Get the preferred encodings from an Accept-Encoding header.
* @public
*/
function preferredEncodings(accept, provided) {

@@ -101,5 +147,6 @@ var accepts = parseAcceptEncoding(accept || '');

// sorted list of all encodings
return accepts.filter(isQuality).sort(compareSpecs).map(function getEncoding(spec) {
return spec.encoding;
});
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullEncoding);
}

@@ -117,2 +164,7 @@

/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {

@@ -122,4 +174,18 @@ return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;

/**
* Get full encoding string.
* @private
*/
function getFullEncoding(spec) {
return spec.encoding;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}

@@ -0,4 +1,31 @@

/**
* negotiator
* Copyright(c) 2012 Isaac Z. Schlueter
* Copyright(c) 2014 Federico Romero
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredLanguages;
preferredLanguages.preferredLanguages = preferredLanguages;
module.exports.preferredLanguages = preferredLanguages;
/**
* Module variables.
* @private
*/
var simpleLanguageRegExp = /^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/;
/**
* Parse the Accept-Language header.
* @private
*/
function parseAcceptLanguage(accept) {

@@ -21,4 +48,9 @@ var accepts = accept.split(',');

function parseLanguage(s, i) {
var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/);
/**
* Parse a language from the Accept-Language header.
* @private
*/
function parseLanguage(str, i) {
var match = simpleLanguageRegExp.exec(str);
if (!match) return null;

@@ -50,2 +82,7 @@

/**
* Get the priority of a language.
* @private
*/
function getLanguagePriority(language, accepted, index) {

@@ -65,2 +102,7 @@ var priority = {o: -1, q: 0, s: 0};

/**
* Get the specificity of the language.
* @private
*/
function specify(language, spec, index) {

@@ -88,2 +130,7 @@ var p = parseLanguage(language)

/**
* Get the preferred languages from an Accept-Language header.
* @public
*/
function preferredLanguages(accept, provided) {

@@ -95,5 +142,6 @@ // RFC 2616 sec 14.4: no header = *

// sorted list of all languages
return accepts.filter(isQuality).sort(compareSpecs).map(function getLanguage(spec) {
return spec.full;
});
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullLanguage);
}

@@ -111,2 +159,7 @@

/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {

@@ -116,4 +169,18 @@ return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;

/**
* Get full language string.
* @private
*/
function getFullLanguage(spec) {
return spec.full;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {
return spec.q > 0;
}

@@ -9,5 +9,24 @@ /**

'use strict';
/**
* Module exports.
* @public
*/
module.exports = preferredMediaTypes;
preferredMediaTypes.preferredMediaTypes = preferredMediaTypes;
module.exports.preferredMediaTypes = preferredMediaTypes;
/**
* Module variables.
* @private
*/
var simpleMediaTypeRegExp = /^\s*(\S+?)\/([^;\s]+)\s*(?:;(.*))?$/;
/**
* Parse the Accept header.
* @private
*/
function parseAccept(accept) {

@@ -28,31 +47,38 @@ var accepts = splitMediaTypes(accept);

return accepts;
};
}
function parseMediaType(s, i) {
var match = s.match(/\s*(\S+?)\/([^;\s]+)\s*(?:;(.*))?/);
/**
* Parse a media type from the Accept header.
* @private
*/
function parseMediaType(str, i) {
var match = simpleMediaTypeRegExp.exec(str);
if (!match) return null;
var type = match[1],
subtype = match[2],
full = "" + type + "/" + subtype,
params = {},
q = 1;
var params = Object.create(null);
var q = 1;
var subtype = match[2];
var type = match[1];
if (match[3]) {
params = match[3].split(';').map(function(s) {
return s.trim().split('=');
}).reduce(function (set, p) {
var name = p[0].toLowerCase();
var value = p[1];
var kvps = splitParameters(match[3]).map(splitKeyValuePair);
set[name] = value && value[0] === '"' && value[value.length - 1] === '"'
? value.substr(1, value.length - 2)
: value;
for (var j = 0; j < kvps.length; j++) {
var pair = kvps[j];
var key = pair[0].toLowerCase();
var val = pair[1];
return set;
}, params);
// get the value, unwrapping quotes
var value = val && val[0] === '"' && val[val.length - 1] === '"'
? val.substr(1, val.length - 2)
: val;
if (params.q != null) {
q = parseFloat(params.q);
delete params.q;
if (key === 'q') {
q = parseFloat(value);
break;
}
// store parameter
params[key] = value;
}

@@ -66,7 +92,11 @@ }

q: q,
i: i,
full: full
i: i
};
}
/**
* Get the priority of a media type.
* @private
*/
function getMediaTypePriority(type, accepted, index) {

@@ -86,2 +116,7 @@ var priority = {o: -1, q: 0, s: 0};

/**
* Get the specificity of the media type.
* @private
*/
function specify(type, spec, index) {

@@ -124,5 +159,9 @@ var p = parseMediaType(type);

}
}
/**
* Get the preferred media types from an Accept header.
* @public
*/
function preferredMediaTypes(accept, provided) {

@@ -134,5 +173,6 @@ // RFC 2616 sec 14.2: no header = */*

// sorted list of all types
return accepts.filter(isQuality).sort(compareSpecs).map(function getType(spec) {
return spec.full;
});
return accepts
.filter(isQuality)
.sort(compareSpecs)
.map(getFullType);
}

@@ -150,2 +190,7 @@

/**
* Compare two specs.
* @private
*/
function compareSpecs(a, b) {

@@ -155,2 +200,16 @@ return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;

/**
* Get full type string.
* @private
*/
function getFullType(spec) {
return spec.type + '/' + spec.subtype;
}
/**
* Check if a spec has any quality.
* @private
*/
function isQuality(spec) {

@@ -160,2 +219,7 @@ return spec.q > 0;

/**
* Count the number of quotes in a string.
* @private
*/
function quoteCount(string) {

@@ -173,2 +237,27 @@ var count = 0;

/**
* Split a key value pair.
* @private
*/
function splitKeyValuePair(str) {
var index = str.indexOf('=');
var key;
var val;
if (index === -1) {
key = str;
} else {
key = str.substr(0, index);
val = str.substr(index + 1);
}
return [key, val];
}
/**
* Split an Accept header into media types.
* @private
*/
function splitMediaTypes(accept) {

@@ -190,1 +279,27 @@ var accepts = accept.split(',');

}
/**
* Split a string of parameters.
* @private
*/
function splitParameters(str) {
var parameters = str.split(';');
for (var i = 1, j = 0; i < parameters.length; i++) {
if (quoteCount(parameters[j]) % 2 == 0) {
parameters[++j] = parameters[i];
} else {
parameters[j] += ';' + parameters[i];
}
}
// trim parameters
parameters.length = j + 1;
for (var i = 0; i < parameters.length; i++) {
parameters[i] = parameters[i].trim();
}
return parameters;
}

4

package.json
{
"name": "negotiator",
"description": "HTTP content negotiation",
"version": "0.5.3",
"version": "0.6.0",
"contributors": [

@@ -21,3 +21,3 @@ "Douglas Christopher Wilson <doug@somethingdoug.com>",

"devDependencies": {
"istanbul": "0.3.9",
"istanbul": "0.3.21",
"mocha": "~1.21.5"

@@ -24,0 +24,0 @@ },

@@ -69,3 +69,3 @@ # negotiator

availableLanguages = 'en', 'es', 'fr'
availableLanguages = ['en', 'es', 'fr']

@@ -72,0 +72,0 @@ // Let's say Accept-Language header is 'en;q=0.8, es, pt'

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc