From 677999caa75e08f5f28e9b135ffd80cbbdc0a1ad Mon Sep 17 00:00:00 2001 From: Sachin Shekhar Date: Thu, 4 Jun 2020 04:52:09 +0530 Subject: [PATCH] Add option to read multiple cookies with same name Fixes https://github.com/jshttp/cookie/issues/60 --- HISTORY.md | 6 ++++++ README.md | 5 +++++ index.js | 10 ++++++++-- test/parse.js | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ce080e0..d251773 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +0.5.0 / 2020-06-04 +================== + + * Add support for reading multiple cookies with same name + - This feature can be turned on by `multiValuedCookie` flag + 0.4.1 / 2020-04-21 ================== diff --git a/README.md b/README.md index 18b2c2c..2578597 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,11 @@ sequences into their byte representations. **note** if an error is thrown from this function, the original, non-decoded cookie value will be returned as the cookie's value. +##### multiValuedCookies + +Specifies a boolean flag which if set to `true` would allow reading multiple cookies with same name (key). All values will be put into an array. +By default (when `multiValuedCookies` isn't present or set to `false`), only first cookie's value is read which is not in accordance with [RFC 6265](https://tools.ietf.org/html/rfc6265#section-4.2.2) as discussed [here](https://github.com/jshttp/cookie/issues/60) (this behaviour is kept around for backward compatibility reason). + ### cookie.serialize(name, value, options) Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the diff --git a/index.js b/index.js index 760f32e..88d23d6 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,7 @@ var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; * Parse a cookie header. * * Parse the given cookie header string into an object - * The object has the various cookies as keys(names) => values + * The object has the various cookies as keys(names) => values or array of values * * @param {string} str * @param {object} [options] @@ -73,9 +73,15 @@ function parse(str, options) { val = val.slice(1, -1); } - // only assign once + // only assign once unless multiValuedCookies is true if (undefined == obj[key]) { obj[key] = tryDecode(val, dec); + } else if (opt.multiValuedCookies) { + if (typeof obj[key] === 'string') { + obj[key] = [obj[key], tryDecode(val, dec)]; + } else { + obj[key] = obj[key].push(tryDecode(val, dec)); + } } } diff --git a/test/parse.js b/test/parse.js index a48a12e..2144cba 100644 --- a/test/parse.js +++ b/test/parse.js @@ -70,3 +70,18 @@ test('assign only once', function() { assert.deepEqual({ foo: '', bar: 'bar' }, cookie.parse('foo=;bar=bar;foo=boo')); }); + +test('multiValuedCookies flag', function () { + assert.deepEqual( + { foo: ["%1", "boo"], bar: "bar" }, + cookie.parse("foo=%1;bar=bar;foo=boo", { + multiValuedCookies: true + }) + ); + assert.deepEqual( + { foo: ["", "boo"], bar: "bar" }, + cookie.parse("foo=;bar=bar;foo=boo", { + multiValuedCookies: true, + }) + ); +});