/*! * cookie * Copyright(c) 2012-2014 Roman Shtylman * MIT Licensed */ /** * Module exports. * @public */ exports.parse = parse; exports.serialize = serialize; /** * Module variables. * @private */ var decode = decodeURIComponent; var encode = encodeURIComponent; /** * Parse a cookie header. * * Parse the given cookie header string into an object * The object has the various cookies as keys(names) => values * * @param {string} str * @param {object} [options] * @return {string} * @public */ function parse(str, options) { var obj = {} var opt = options || {}; var pairs = str.split(/; */); var dec = opt.decode || decode; pairs.forEach(function(pair) { var eq_idx = pair.indexOf('=') // skip things that don't look like key=value if (eq_idx < 0) { return; } var key = pair.substr(0, eq_idx).trim() var val = pair.substr(++eq_idx, pair.length).trim(); // quoted values if ('"' == val[0]) { val = val.slice(1, -1); } // only assign once if (undefined == obj[key]) { obj[key] = tryDecode(val, dec); } }); return obj; } /** * Serialize data into a cookie header. * * Serialize the a name value pair into a cookie string suitable for * http headers. An optional options object specified cookie parameters. * * serialize('foo', 'bar', { httpOnly: true }) * => "foo=bar; httpOnly" * * @param {string} name * @param {string} val * @param {object} [options] * @return {string} * @public */ function serialize(name, val, options) { var opt = options || {}; var enc = opt.encode || encode; var pairs = [name + '=' + enc(val)]; if (null != opt.maxAge) { var maxAge = opt.maxAge - 0; if (isNaN(maxAge)) throw new Error('maxAge should be a Number'); pairs.push('Max-Age=' + maxAge); } if (opt.domain) pairs.push('Domain=' + opt.domain); if (opt.path) pairs.push('Path=' + opt.path); if (opt.expires) pairs.push('Expires=' + opt.expires.toUTCString()); if (opt.httpOnly) pairs.push('HttpOnly'); if (opt.secure) pairs.push('Secure'); return pairs.join('; '); } /** * Try decoding a string using a decoding function. * * @param {string} str * @param {function} decode * @private */ function tryDecode(str, decode) { try { return decode(str); } catch (e) { return str; } }