diff --git a/benchmark/parse-top.js b/benchmark/parse-top.js index eebfdec..4cbfd00 100644 --- a/benchmark/parse-top.js +++ b/benchmark/parse-top.js @@ -22,26 +22,16 @@ Object.keys(top).forEach(function (domain) { }) }) -suite.on('start', function onCycle (event) { +suite.on('start', function () { process.stdout.write(' cookie.parse - top sites\n\n') }) -suite.on('cycle', function onCycle (event) { +suite.on('cycle', function (event) { benchmarks.add(event.target) }) -suite.on('complete', function onComplete () { +suite.on('complete', function () { benchmarks.log() }) -suite.run({async: false}) - -function gencookies (num) { - var str = '' - - for (var i = 0; i < num; i++) { - str += '; foo' + i + '=bar' - } - - return str.slice(2) -} +suite.run({ async: false }) diff --git a/benchmark/parse.js b/benchmark/parse.js index e9c3c1d..567f4b6 100644 --- a/benchmark/parse.js +++ b/benchmark/parse.js @@ -49,11 +49,11 @@ suite.add({ fn: 'var val = cookie.parse(' + JSON.stringify(gencookies(100)) + ')' }) -suite.on('start', function onCycle (event) { +suite.on('start', function () { process.stdout.write(' cookie.parse - generic\n\n') }) -suite.on('cycle', function onCycle (event) { +suite.on('cycle', function (event) { benchmarks.add(event.target) }) @@ -61,7 +61,7 @@ suite.on('complete', function onComplete () { benchmarks.log() }) -suite.run({async: false}) +suite.run({ async: false }) function gencookies (num) { var str = '' diff --git a/index.js b/index.js index 56ed1e6..47aca9e 100644 --- a/index.js +++ b/index.js @@ -85,12 +85,12 @@ var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/; * The object has the various cookies as keys(names) => values * * @param {string} str - * @param {object} [options] + * @param {object} [opt] * @return {object} * @public */ -function parse(str, options) { +function parse(str, opt) { if (typeof str !== 'string') { throw new TypeError('argument str must be a string'); } @@ -98,21 +98,16 @@ function parse(str, options) { var obj = {}; var len = str.length; // RFC 6265 sec 4.1.1, RFC 2616 2.2 defines a cookie name consists of one char minimum, plus '='. - var max = len - 2; - if (max < 0) return obj; + if (len < 2) return obj; - var dec = (options && options.decode) || decode; + var dec = (opt && opt.decode) || decode; var index = 0; var eqIdx = 0; var endIdx = 0; do { eqIdx = str.indexOf('=', index); - - // no more cookie pairs - if (eqIdx === -1) { - break; - } + if (eqIdx === -1) break; // No more cookie pairs. endIdx = str.indexOf(';', index); @@ -129,7 +124,7 @@ function parse(str, options) { var key = str.slice(keyStartIdx, keyEndIdx); // only assign once - if (undefined === obj[key]) { + if (!obj.hasOwnProperty(key)) { var valStartIdx = startIndex(str, eqIdx + 1, endIdx); var valEndIdx = endIndex(str, endIdx, valStartIdx); @@ -143,7 +138,7 @@ function parse(str, options) { } index = endIdx + 1 - } while (index < max); + } while (index < len); return obj; } @@ -175,14 +170,13 @@ function endIndex(str, index, min) { * * @param {string} name * @param {string} val - * @param {object} [options] + * @param {object} [opt] * @return {string} * @public */ -function serialize(name, val, options) { - var opt = options || {}; - var enc = opt.encode || encode; +function serialize(name, val, opt) { + var enc = (opt && opt.encode) || encodeURIComponent; if (typeof enc !== 'function') { throw new TypeError('option encode is invalid'); @@ -194,20 +188,21 @@ function serialize(name, val, options) { var value = enc(val); - if (value && !cookieValueRegExp.test(value)) { + if (!cookieValueRegExp.test(value)) { throw new TypeError('argument val is invalid'); } var str = name + '=' + value; + if (!opt) return str; if (null != opt.maxAge) { - var maxAge = opt.maxAge - 0; + var maxAge = Math.floor(opt.maxAge); if (!isFinite(maxAge)) { throw new TypeError('option maxAge is invalid') } - str += '; Max-Age=' + Math.floor(maxAge); + str += '; Max-Age=' + maxAge; } if (opt.domain) { @@ -250,8 +245,7 @@ function serialize(name, val, options) { if (opt.priority) { var priority = typeof opt.priority === 'string' - ? opt.priority.toLowerCase() - : opt.priority + ? opt.priority.toLowerCase() : opt.priority; switch (priority) { case 'low': @@ -306,17 +300,6 @@ function decode (str) { : str } -/** - * URL-encode value. - * - * @param {string} val - * @returns {string} - */ - -function encode (val) { - return encodeURIComponent(val) -} - /** * Determine if value is a Date. * @@ -325,8 +308,7 @@ function encode (val) { */ function isDate (val) { - return __toString.call(val) === '[object Date]' || - val instanceof Date + return __toString.call(val) === '[object Date]'; } /** diff --git a/test/parse.js b/test/parse.js index f223b16..b5f65ed 100644 --- a/test/parse.js +++ b/test/parse.js @@ -29,6 +29,7 @@ describe('cookie.parse(str)', function () { it('should parse cookie with minimum length', function () { assert.deepEqual(cookie.parse('f='), { f: '' }) + assert.deepEqual(cookie.parse('f=;b='), { f: '', b: '' }) }) it('should URL-decode values', function () { @@ -67,6 +68,10 @@ describe('cookie.parse(str)', function () { assert.deepEqual(cookie.parse('foo=false;bar=bar;foo=true'), { foo: 'false', bar: 'bar' }) assert.deepEqual(cookie.parse('foo=;bar=bar;foo=boo'), { foo: '', bar: 'bar' }) }) + + it('should parse native properties', function () { + assert.deepEqual(cookie.parse('toString=foo;valueOf=bar'), { toString: 'foo', valueOf: 'bar' }) + }) }) describe('cookie.parse(str, options)', function () {