UNPKG

4.78 kBJavaScriptView Raw
1var urllib = require("url");
2
3module.exports.CookieJar = CookieJar;
4
5function CookieJar(options){
6 this.options = options || {};
7 this.options.sessionTimeout = this.options.sessionTimeout || 1800; // 30min
8
9 this.cookies = {};
10}
11
12CookieJar.prototype.addCookie = function(cookie){
13
14 if(!cookie || !cookie.name) return;
15
16 var lcookie;
17
18 if(!this.cookies[cookie.name]){
19 this.cookies[cookie.name] = [];
20 }
21
22 // overwrite if has same params
23 for(var i=0, len=this.cookies[cookie.name].length; i<len; i++){
24 lcookie = this.cookies[cookie.name][i];
25 if(
26 lcookie.path == cookie.path &&
27 lcookie.domain == cookie.domain &&
28 lcookie.secure == cookie.secure &&
29 lcookie.httponly == cookie.httponly
30 ){
31 this.cookies[cookie.name][i] = cookie;
32 return;
33 }
34 }
35
36 this.cookies[cookie.name].push(cookie);
37}
38
39CookieJar.prototype.getCookies = function(url){
40 var keys = Object.keys(this.cookies),
41 cookie, cookies = [];
42
43 for(var i=0, len = keys.length; i<len; i++){
44 if(Array.isArray(this.cookies[keys[i]])){
45 for(var j=0, lenj = this.cookies[keys[i]].length; j<lenj; j++){
46 cookie = this.cookies[keys[i]][j];
47 if(this.matchCookie(cookie, url)){
48 cookies.push(cookie.name +"="+cookie.value);
49 }
50 }
51 }
52 }
53 return cookies.join("; ");
54}
55
56CookieJar.prototype.matchCookie = function(cookie, url){
57 var urlparts = urllib.parse(url || "", false, true),
58 path;
59
60 // check expire
61 if(cookie.expire){
62 if(cookie.expire.getTime() < Date.now()){
63 return;
64 }
65 }
66
67 // check if hostname matches
68 if(urlparts.hostname && cookie._domain){
69 if(!(urlparts.hostname == cookie._domain || urlparts.hostname.substr(-(cookie._domain.length+1)) == "."+cookie._domain)){
70 return false;
71 }
72 }
73
74 // check if path matches
75 if(cookie.path && urlparts.pathname){
76
77 path = (urlparts.pathname || "/").split("/");
78 path.pop();
79 path = path.join("/").trim();
80 if(path.substr(0,1)!="/"){
81 path = "/" + path;
82 }
83 if(path.substr(-1)!="/"){
84 path += "/";
85 }
86
87 if(path.substr(0, cookie.path.length) != cookie.path){
88 return false;
89 }
90 }
91
92 // check secure
93 if(cookie.secure && urlparts.protocol){
94 if(urlparts.protocol != "https:"){
95 return false;
96 }
97 }
98
99 // check httponly
100 if(cookie.httponly && urlparts.protocol){
101 if(urlparts.protocol != "http:"){
102 return false;
103 }
104 }
105
106 return true;
107}
108
109CookieJar.prototype.setCookie = function(cookie_str, url){
110 var parts = (cookie_str || "").split(";"),
111 cookie = {},
112 urlparts = urllib.parse(url || "", false, true),
113 path;
114
115 parts.forEach((function(part){
116 var key, val;
117 part = part.split("=");
118 key = part.shift().trim();
119 val = part.join("=").trim();
120
121 if(!key)return;
122
123 switch(key.toLowerCase()){
124
125 case "expires":
126
127 cookie.expires = new Date(val);
128 break;
129
130 case "path":
131 cookie.path = val.trim();
132 break;
133
134 case "domain":
135 cookie.domain = val.toLowerCase();
136 break;
137
138 case "max-age":
139 cookie.expires = new Date(Date.now() + (Number(val) || 0)*1000);
140 break;
141
142 case "secure":
143 cookie.secure = true;
144 break;
145
146 case "httponly":
147 cookie.httponly = true;
148 break;
149
150 default:
151 if(!cookie.name){
152 cookie.name = key;
153 cookie.value = val;
154 }
155 }
156 }).bind(this));
157
158 // use current path when path is not specified
159 if(!cookie.path){
160 path = (urlparts.pathname || "/").split("/");
161 path.pop();
162 cookie.path = path.join("/").trim();
163 if(cookie.path.substr(0,1)!="/"){
164 cookie.path = "/" + cookie.path;
165 }
166 if(cookie.path.substr(-1)!="/"){
167 cookie.path += "/";
168 }
169 }
170
171 // if no expire date, then use sessionTimeout value
172 if(!cookie.expires){
173 cookie._expires = new Date(Date.now() + (Number(this.options.sessionTimeout) || 0)*1000);
174 }else{
175 cookie._expires = cookie.expires;
176 }
177
178 if(!cookie.domain){
179 if(urlparts.hostname){
180 cookie._domain = urlparts.hostname;
181 }
182 }else{
183 cookie._domain = cookie.domain;
184 }
185
186 this.addCookie(cookie);
187}
\No newline at end of file