Cookie.js
237 lines
| 6.7 KiB
| application/javascript
|
JavascriptLexer
|
|
r0 | /** | |
| * | |||
| */ | |||
| define(["dojo/_base/declare", "dojo/_base/lang", "implab/safe"], function (declare, lang, safe) { | |||
| var formats = { | |||
| "base64+json": { | |||
| encode: function (data) { | |||
| return new Buffer(JSON.stringify(data)).toString('base64'); | |||
| }, | |||
| decode: function (data) { | |||
| try { | |||
| return JSON.parse(new Buffer(data, 'base64').toString()); | |||
| } catch (err) { | |||
| return null; | |||
| } | |||
| } | |||
| }, | |||
| "base64": { | |||
| encode: function (data) { | |||
| if (!safe.isPrimitive(data)) | |||
| throw new Error("Can'n serialize a complex data"); | |||
| return new Buffer(data).toString('base64'); | |||
| }, | |||
| decode: function (data) { | |||
| return new Buffer(data, 'base64').toString(); | |||
| }, | |||
| }, | |||
| "simple": { | |||
| encode: function (data) { | |||
| if (!safe.isPrimitive(data)) | |||
| throw new Error("Can'n serialize a complex data"); | |||
| return safe.isNull(data) ? "" : data.toString(); | |||
| }, | |||
| decode: function (data) { | |||
| return data; | |||
| } | |||
| } | |||
| }; | |||
| let args = { | |||
| secure: false, | |||
| httpOnly: false, | |||
| path: null, | |||
| domain: null, | |||
| maxAge: null, | |||
| expires: null, | |||
| extension: null, | |||
| format: null | |||
| }; | |||
| let Cookie = declare(null, { | |||
| secure: false, | |||
| httpOnly: false, | |||
| path: null, | |||
| name: null, | |||
| domain: null, | |||
| maxAge: null, | |||
| expires: null, | |||
| extension: null, | |||
| value: null, | |||
| format: "base64+json", | |||
| _createTime: null, | |||
| constructor: function (name, value, opts) { | |||
| safe.argumentNotEmptyString(name, "name"); | |||
| if (opts) { | |||
| for (let i in opts) | |||
| if (i in args) | |||
| this[i] = opts[i]; | |||
| } | |||
| this.name = name; | |||
| this.value = value; | |||
| this._createTime = new Date(); | |||
| }, | |||
| isExpired: function () { | |||
| let expires; | |||
| if (this.maxAge) { | |||
| let dt = this.getNormalMaxAge(); | |||
| expires = new Date(this._createTime.getTime() + dt * 1000); | |||
| } else if (this.expires) { | |||
| expires = new Date(this.expires); | |||
| } | |||
| return (expires && new Date() > expires); | |||
| }, | |||
| getNormalMaxAge: function () { | |||
| if (safe.isNull(this.maxAge)) | |||
| return null; | |||
| if (safe.isNumber(this.maxAge)) | |||
| return Math.round(this.maxAge); | |||
| let norm = Number(this.maxAge); | |||
| if (norm == this.maxAge) | |||
| return Math.round(norm); | |||
| let parts = this.maxAge.toString().match("^(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$"); | |||
| if (parts) { | |||
| let factor = [0, 86400, 3600, 60, 1]; | |||
| norm = 0; | |||
| for (let i = 1; i < parts.length; i++) { | |||
| norm += factor[i] * (Number(parts[i]) || 0); | |||
| } | |||
| } else { | |||
| norm = null; | |||
| } | |||
| return norm; | |||
| }, | |||
| toString: function () { | |||
| let data = []; | |||
| let pair = function (name, value, enc) { | |||
| if (!safe.isNullOrEmptyString(value)) | |||
| data.push([name, enc ? enc(value) : value].join('=')); | |||
| }; | |||
| let flag = function (name, isSet) { | |||
| if (isSet) | |||
| data.push(name); | |||
| }; | |||
| pair(this.name, this.value, this.format ? Cookie.formats[this.format].encode : null); | |||
| pair("Expires", this.expires, function (d) { | |||
| return new Date(d).toUTCString(); | |||
| }); | |||
| pair("Max-Age", this.getNormalMaxAge()); | |||
| pair("Domain", this.domain); | |||
| pair("Path", this.path); | |||
| flag("Secure", this.secure); | |||
| flag("HttpOnly", this.httpOnly); | |||
| flag(this.extension, this.extension); | |||
| return data.join('; '); | |||
| } | |||
| }); | |||
| /** | |||
| * Парсит строку с печеньками из HTTP заголока Cookies | |||
| * | |||
| * @return возвращает коллекцию печенек в виде { "cookie-name" : { | |||
| * value='raw%20data', decode : function(format) {} } } | |||
| * | |||
| */ | |||
| Cookie.parseHeaderValue = function (str) { | |||
| safe.argumentNotEmptyString(str, "str"); | |||
| let pairs = str.split(/;\s*/); | |||
| let cookies = {}; | |||
| for (let i in pairs) { | |||
| let pair = pairs[i]; | |||
| let idx = pair.indexOf('='); | |||
| if (idx >= 0) { | |||
| cookies[pair.substring(0, idx)] = { | |||
| value: pair.substring(idx + 1), | |||
| decode: function (format) { | |||
| if (!format) | |||
| format = "simple"; | |||
| if (!formats[format]) | |||
| throw new Error("The specified format '" + format + "' is unsupported"); | |||
| let decode = formats[format].decode; | |||
| return decode(this.value); | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| return cookies; | |||
| }; | |||
| Cookie.formats = formats; | |||
| Cookie.parse = function (str, format) { | |||
| safe.argumentNotEmptyString(str, "str"); | |||
| if (!format) | |||
| format = "simple"; | |||
| if (!formats[format]) | |||
| throw new Error("The specified format '" + format + "' is unsupported"); | |||
| let pairs = str.split(/;\s*/); | |||
| let options = { | |||
| format: format | |||
| }; | |||
| let cookieName, cookieValue, first = true; | |||
| let map = { | |||
| "Expires": "expires", | |||
| "Max-Age": "maxAge", | |||
| "Domain": "domain", | |||
| "Path": "path", | |||
| "Secure": "secure", | |||
| "HttpOnly": "httpOnly" | |||
| }; | |||
| for (let i in pairs) { | |||
| let pair = pairs[i]; | |||
| let idx = pair.indexOf('='); | |||
| if (idx >= 0) { | |||
| let name = pair.substring(0, idx); | |||
| let value = pair.substring(idx + 1); | |||
| if (first) { | |||
| cookieName = name; | |||
| cookieValue = value; | |||
| first = false; | |||
| } else { | |||
| if (name in map) | |||
| options[map[name]] = value; | |||
| } | |||
| } else { | |||
| if (pair in map) | |||
| options[map[pair]] = true; | |||
| else | |||
| options.extension = pair; | |||
| } | |||
| } | |||
| return new Cookie(cookieName, cookieValue, options); | |||
| }; | |||
| return Cookie; | |||
| }); |
