connect-memcached 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +41 -27
- package/lib/connect-memcached.js +212 -191
- package/package.json +23 -10
- package/tests/test.js +27 -25
- package/tests/test_encrypt.js +27 -25
package/Readme.md
CHANGED
|
@@ -1,59 +1,73 @@
|
|
|
1
1
|
# connect-memcached
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Memcached session store, using [node-memcached](http://github.com/3rd-Eden/node-memcached) for communication with cache server.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
via npm:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
$ npm install connect-memcached
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Example
|
|
14
|
+
|
|
14
15
|
```javascript
|
|
15
|
-
var express
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
var express = require("express"),
|
|
17
|
+
session = require("express-session"),
|
|
18
|
+
cookieParser = require("cookie-parser"),
|
|
19
|
+
http = require("http"),
|
|
20
|
+
app = express(),
|
|
21
|
+
MemcachedStore = require("connect-memcached")(session);
|
|
21
22
|
|
|
22
23
|
app.use(cookieParser());
|
|
23
|
-
app.use(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
app.use(
|
|
25
|
+
session({
|
|
26
|
+
secret: "CatOnKeyboard",
|
|
27
|
+
key: "test",
|
|
28
|
+
proxy: "true",
|
|
29
|
+
resave: false,
|
|
30
|
+
saveUninitialized: false,
|
|
31
|
+
store: new MemcachedStore({
|
|
32
|
+
hosts: ["127.0.0.1:11211"],
|
|
33
|
+
secret: "123, easy as ABC. ABC, easy as 123" // Optionally use transparent encryption for memcache session data
|
|
30
34
|
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
})
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
app.get("/", function(req, res) {
|
|
39
|
+
if (req.session.views) {
|
|
40
|
+
++req.session.views;
|
|
41
|
+
} else {
|
|
42
|
+
req.session.views = 1;
|
|
43
|
+
}
|
|
44
|
+
res.send("Viewed <strong>" + req.session.views + "</strong> times.");
|
|
40
45
|
});
|
|
41
46
|
|
|
42
47
|
http.createServer(app).listen(9341, function() {
|
|
43
|
-
|
|
48
|
+
console.log("Listening on %d", this.address().port);
|
|
44
49
|
});
|
|
45
50
|
```
|
|
46
51
|
|
|
47
52
|
## Options
|
|
53
|
+
|
|
48
54
|
- `hosts` Memcached servers locations, can be string, array, hash.
|
|
49
55
|
- `prefix` An optional prefix for each memcache key, in case you are sharing your memcached servers with something generating its own keys.
|
|
50
|
-
- `ttl` An optional parameter used for setting the default TTL
|
|
56
|
+
- `ttl` An optional parameter used for setting the default TTL (in seconds)
|
|
51
57
|
- `secret` An optional secret can be used to encrypt/decrypt session contents.
|
|
52
58
|
- `algorithm` An optional algorithm parameter may be used, but must be valid based on returned `crypto.getCiphers()`. The current default is `aes-256-ctr` and was chosen based on the following [information](http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html)
|
|
53
|
-
- ...
|
|
59
|
+
- ... Rest of given option will be passed directly to the node-memcached constructor.
|
|
54
60
|
|
|
55
61
|
For details see [node-memcached](http://github.com/3rd-Eden/node-memcached).
|
|
56
62
|
|
|
63
|
+
## Upgrading from v0.x.x -> v1.x.x
|
|
64
|
+
|
|
65
|
+
If You're upgrading from the pre v1.0.0 version of this library and use encryption for session data be sure to **remove all session entries created with previous version**.
|
|
66
|
+
|
|
67
|
+
Upgrading library without taking appropriate action will result in `SyntaxError` exceptions during JSON parsing of decoded entries.
|
|
68
|
+
|
|
69
|
+
Sessions without encryption are not affected.
|
|
70
|
+
|
|
57
71
|
## Contributors
|
|
58
72
|
|
|
59
73
|
Big thanks for the contributors! See the actual list [here](https://github.com/balor/connect-memcached/graphs/contributors)!
|
package/lib/connect-memcached.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
* connect-memcached
|
|
3
3
|
* MIT Licensed
|
|
4
4
|
*/
|
|
5
|
+
const bufferFrom = require('buffer-from');
|
|
5
6
|
|
|
6
|
-
var Memcached = require(
|
|
7
|
+
var Memcached = require("memcached");
|
|
7
8
|
var oneDay = 86400;
|
|
9
|
+
|
|
8
10
|
function ensureCallback(fn) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
return function() {
|
|
12
|
+
fn && fn.apply(null, arguments);
|
|
13
|
+
};
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -19,202 +21,221 @@ function ensureCallback(fn) {
|
|
|
19
21
|
* @api public
|
|
20
22
|
*/
|
|
21
23
|
module.exports = function(session) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
options.client = new Memcached(options.hosts, options);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
this.client = options.client;
|
|
24
|
+
var Store = session.Store;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Initialize MemcachedStore with the given `options`.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} options
|
|
30
|
+
* @api public
|
|
31
|
+
*/
|
|
32
|
+
function MemcachedStore(options) {
|
|
33
|
+
options = options || {};
|
|
34
|
+
Store.call(this, options);
|
|
35
|
+
|
|
36
|
+
this.prefix = options.prefix || "";
|
|
37
|
+
this.ttl = options.ttl;
|
|
38
|
+
if (!options.client) {
|
|
39
|
+
if (!options.hosts) {
|
|
40
|
+
options.hosts = "127.0.0.1:11211";
|
|
41
|
+
}
|
|
42
|
+
if (options.secret) {
|
|
43
|
+
(this.crypto = require("crypto")), (this.secret = options.secret);
|
|
44
|
+
}
|
|
45
|
+
if (options.algorithm) {
|
|
46
|
+
this.algorithm = options.algorithm;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
options.client = new Memcached(options.hosts, options);
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
parseable_string = data.toString();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
fn(null, JSON.parse(parseable_string));
|
|
92
|
-
} catch (e) {
|
|
93
|
-
fn(e);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Commit the given `sess` object associated with the given `sid`.
|
|
100
|
-
*
|
|
101
|
-
* @param {String} sid
|
|
102
|
-
* @param {Session} sess
|
|
103
|
-
* @param {Function} fn
|
|
104
|
-
* @api public
|
|
105
|
-
*/
|
|
106
|
-
MemcachedStore.prototype.set = function(sid, sess, fn) {
|
|
107
|
-
sid = this.getKey(sid);
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
var maxAge = sess.cookie.maxAge;
|
|
111
|
-
var ttl = this.ttl || ('number' == typeof maxAge ? maxAge / 1000 | 0 : oneDay);
|
|
112
|
-
var sess = JSON.stringify((this.secret) ?
|
|
113
|
-
encryptData.call(this, JSON.stringify(sess),
|
|
114
|
-
this.secret, this.algorithm) :
|
|
115
|
-
sess);
|
|
116
|
-
|
|
117
|
-
this.client.set(sid, sess, ttl, ensureCallback(fn));
|
|
118
|
-
} catch (err) {
|
|
119
|
-
fn && fn(err);
|
|
52
|
+
this.client = options.client;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
MemcachedStore.prototype.__proto__ = Store.prototype;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Translates the given `sid` into a memcached key, optionally with prefix.
|
|
59
|
+
*
|
|
60
|
+
* @param {String} sid
|
|
61
|
+
* @api private
|
|
62
|
+
*/
|
|
63
|
+
MemcachedStore.prototype.getKey = function getKey(sid) {
|
|
64
|
+
return this.prefix + sid;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Attempt to fetch session by the given `sid`.
|
|
69
|
+
*
|
|
70
|
+
* @param {String} sid
|
|
71
|
+
* @param {Function} fn
|
|
72
|
+
* @api public
|
|
73
|
+
*/
|
|
74
|
+
MemcachedStore.prototype.get = function(sid, fn) {
|
|
75
|
+
(secret = this.secret), (self = this), (sid = this.getKey(sid));
|
|
76
|
+
|
|
77
|
+
this.client.get(sid, function(err, data) {
|
|
78
|
+
if (err) {
|
|
79
|
+
return fn(err, {});
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
if (!data) {
|
|
83
|
+
return fn();
|
|
120
84
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
*
|
|
126
|
-
* @param {String} sid
|
|
127
|
-
* @param {Function} fn
|
|
128
|
-
* @api public
|
|
129
|
-
*/
|
|
130
|
-
MemcachedStore.prototype.destroy = function(sid, fn) {
|
|
131
|
-
sid = this.getKey(sid);
|
|
132
|
-
this.client.del(sid, ensureCallback(fn));
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Fetch number of sessions.
|
|
137
|
-
*
|
|
138
|
-
* @param {Function} fn
|
|
139
|
-
* @api public
|
|
140
|
-
*/
|
|
141
|
-
MemcachedStore.prototype.length = function(fn) {
|
|
142
|
-
this.client.items(ensureCallback(fn));
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Clear all sessions.
|
|
147
|
-
*
|
|
148
|
-
* @param {Function} fn
|
|
149
|
-
* @api public
|
|
150
|
-
*/
|
|
151
|
-
MemcachedStore.prototype.clear = function(fn) {
|
|
152
|
-
this.client.flush(ensureCallback(fn));
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Refresh the time-to-live for the session with the given `sid`.
|
|
157
|
-
*
|
|
158
|
-
* @param {String} sid
|
|
159
|
-
* @param {Session} sess
|
|
160
|
-
* @param {Function} fn
|
|
161
|
-
* @api public
|
|
162
|
-
*/
|
|
163
|
-
|
|
164
|
-
MemcachedStore.prototype.touch = function (sid, sess, fn) {
|
|
165
|
-
this.set(sid, sess, fn);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
function encryptData(plaintext){
|
|
170
|
-
var pt = encrypt.call(this, this.secret, plaintext, this.algo)
|
|
171
|
-
, hmac = digest.call(this, this.secret, pt);
|
|
172
|
-
|
|
173
|
-
return {
|
|
174
|
-
ct: pt,
|
|
175
|
-
mac: hmac
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function decryptData(ciphertext){
|
|
180
|
-
ciphertext = JSON.parse(ciphertext)
|
|
181
|
-
var hmac = digest.call(this, this.secret, ciphertext.ct);
|
|
182
|
-
|
|
183
|
-
if (hmac != ciphertext.mac) {
|
|
184
|
-
throw 'Encrypted session was tampered with!';
|
|
85
|
+
if (secret) {
|
|
86
|
+
parseable_string = decryptData.call(self, data.toString());
|
|
87
|
+
} else {
|
|
88
|
+
parseable_string = data.toString();
|
|
185
89
|
}
|
|
186
90
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
91
|
+
fn(null, JSON.parse(parseable_string));
|
|
92
|
+
} catch (e) {
|
|
93
|
+
fn(e);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Commit the given `sess` object associated with the given `sid`.
|
|
100
|
+
*
|
|
101
|
+
* @param {String} sid
|
|
102
|
+
* @param {Session} sess
|
|
103
|
+
* @param {Function} fn
|
|
104
|
+
* @api public
|
|
105
|
+
*/
|
|
106
|
+
MemcachedStore.prototype.set = function(sid, sess, fn) {
|
|
107
|
+
sid = this.getKey(sid);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
var maxAge = sess.cookie.maxAge;
|
|
111
|
+
var ttl =
|
|
112
|
+
this.ttl || ("number" == typeof maxAge ? (maxAge / 1000) | 0 : oneDay);
|
|
113
|
+
var sess = JSON.stringify(
|
|
114
|
+
this.secret
|
|
115
|
+
? encryptData.call(
|
|
116
|
+
this,
|
|
117
|
+
JSON.stringify(sess),
|
|
118
|
+
this.secret,
|
|
119
|
+
this.algorithm
|
|
120
|
+
)
|
|
121
|
+
: sess
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
this.client.set(sid, sess, ttl, ensureCallback(fn));
|
|
125
|
+
} catch (err) {
|
|
126
|
+
fn && fn(err);
|
|
207
127
|
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Destroy the session associated with the given `sid`.
|
|
132
|
+
*
|
|
133
|
+
* @param {String} sid
|
|
134
|
+
* @param {Function} fn
|
|
135
|
+
* @api public
|
|
136
|
+
*/
|
|
137
|
+
MemcachedStore.prototype.destroy = function(sid, fn) {
|
|
138
|
+
sid = this.getKey(sid);
|
|
139
|
+
this.client.del(sid, ensureCallback(fn));
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Fetch number of sessions.
|
|
144
|
+
*
|
|
145
|
+
* @param {Function} fn
|
|
146
|
+
* @api public
|
|
147
|
+
*/
|
|
148
|
+
MemcachedStore.prototype.length = function(fn) {
|
|
149
|
+
this.client.items(ensureCallback(fn));
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Clear all sessions.
|
|
154
|
+
*
|
|
155
|
+
* @param {Function} fn
|
|
156
|
+
* @api public
|
|
157
|
+
*/
|
|
158
|
+
MemcachedStore.prototype.clear = function(fn) {
|
|
159
|
+
this.client.flush(ensureCallback(fn));
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Refresh the time-to-live for the session with the given `sid`.
|
|
164
|
+
*
|
|
165
|
+
* @param {String} sid
|
|
166
|
+
* @param {Session} sess
|
|
167
|
+
* @param {Function} fn
|
|
168
|
+
* @api public
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
MemcachedStore.prototype.touch = function(sid, sess, fn) {
|
|
172
|
+
this.set(sid, sess, fn);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
function encryptData(plaintext) {
|
|
176
|
+
var pt = encrypt.call(this, this.secret, plaintext, this.algo),
|
|
177
|
+
hmac = digest.call(this, this.secret, pt);
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
ct: pt,
|
|
181
|
+
mac: hmac
|
|
182
|
+
};
|
|
183
|
+
}
|
|
208
184
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
var cipher = this.crypto.createDecipher(algo, key), pt = [];
|
|
185
|
+
function decryptData(ciphertext) {
|
|
186
|
+
ciphertext = JSON.parse(ciphertext);
|
|
212
187
|
|
|
213
|
-
|
|
214
|
-
pt.push(cipher.final('utf8'));
|
|
188
|
+
var hmac = digest.call(this, this.secret, ciphertext.ct);
|
|
215
189
|
|
|
216
|
-
|
|
190
|
+
if (hmac != ciphertext.mac) {
|
|
191
|
+
throw "Encrypted session was tampered with!";
|
|
217
192
|
}
|
|
218
193
|
|
|
219
|
-
return
|
|
194
|
+
return decrypt.call(this, this.secret, ciphertext.ct, this.algo);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function digest(key, obj) {
|
|
198
|
+
var hmac = this.crypto.createHmac("sha512", key);
|
|
199
|
+
hmac.setEncoding("hex");
|
|
200
|
+
hmac.write(obj);
|
|
201
|
+
hmac.end();
|
|
202
|
+
return hmac.read();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function encrypt(key, pt, algo) {
|
|
206
|
+
algo = algo || "aes-256-ctr";
|
|
207
|
+
pt = Buffer.isBuffer(pt) ? pt : new bufferFrom(pt);
|
|
208
|
+
var iv = this.crypto.randomBytes(16);
|
|
209
|
+
var hashedKey = this.crypto
|
|
210
|
+
.createHash("sha256")
|
|
211
|
+
.update(key)
|
|
212
|
+
.digest();
|
|
213
|
+
var cipher = this.crypto.createCipheriv(algo, hashedKey, iv),
|
|
214
|
+
ct = [];
|
|
215
|
+
ct.push(iv.toString("hex"));
|
|
216
|
+
ct.push(cipher.update(pt, "buffer", "hex"));
|
|
217
|
+
ct.push(cipher.final("hex"));
|
|
218
|
+
|
|
219
|
+
return ct.join("");
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function decrypt(key, ct, algo) {
|
|
223
|
+
algo = algo || "aes-256-ctr";
|
|
224
|
+
var dataBuffer = bufferFrom(ct, "hex");
|
|
225
|
+
var iv = dataBuffer.slice(0, 16);
|
|
226
|
+
var hashedKey = this.crypto
|
|
227
|
+
.createHash("sha256")
|
|
228
|
+
.update(key)
|
|
229
|
+
.digest();
|
|
230
|
+
|
|
231
|
+
var cipher = this.crypto.createDecipheriv(algo, hashedKey, iv),
|
|
232
|
+
pt = [];
|
|
233
|
+
|
|
234
|
+
pt.push(cipher.update(dataBuffer.slice(16), "hex", "utf8"));
|
|
235
|
+
pt.push(cipher.final("utf8"));
|
|
236
|
+
|
|
237
|
+
return pt.join("");
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return MemcachedStore;
|
|
220
241
|
};
|
package/package.json
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"name": "connect-memcached",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Memcached session store for Connect",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"memcached",
|
|
7
|
+
"connection",
|
|
8
|
+
"session",
|
|
9
|
+
"store",
|
|
10
|
+
"cache"
|
|
11
|
+
],
|
|
12
|
+
"author": "Michał Thoma <me@balor.pl>",
|
|
13
|
+
"repository": {
|
|
8
14
|
"type": "git",
|
|
9
15
|
"url": "https://github.com/balor/connect-memcached"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"buffer-from": "1.1.0",
|
|
19
|
+
"memcached": "2.2.x"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">= 0.10.0"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"directories": {
|
|
26
|
+
"lib": "./lib"
|
|
10
27
|
}
|
|
11
|
-
, "dependencies": { "memcached": "2.2.x" }
|
|
12
|
-
, "engines": { "node": ">=0.4.7" }
|
|
13
|
-
, "license": "MIT"
|
|
14
|
-
, "directories": { "lib": "./lib" }
|
|
15
28
|
}
|
package/tests/test.js
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
var express
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
var express = require("express"),
|
|
2
|
+
session = require("express-session"),
|
|
3
|
+
cookieParser = require("cookie-parser"),
|
|
4
|
+
http = require("http"),
|
|
5
|
+
app = express(),
|
|
6
|
+
MemcachedStore = require("../lib/connect-memcached")(session);
|
|
7
7
|
|
|
8
8
|
app.use(cookieParser());
|
|
9
|
-
app.use(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
app.use(
|
|
10
|
+
session({
|
|
11
|
+
secret: "TestSecret",
|
|
12
|
+
key: "test",
|
|
13
|
+
proxy: "true",
|
|
14
|
+
resave: false,
|
|
15
|
+
saveUninitialized: false,
|
|
16
|
+
store: new MemcachedStore({
|
|
17
|
+
hosts: ["127.0.0.1:11211"],
|
|
18
|
+
prefix: "testapp_"
|
|
16
19
|
})
|
|
17
|
-
})
|
|
20
|
+
})
|
|
21
|
+
);
|
|
18
22
|
|
|
19
|
-
app.get(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
app.get("/", function(req, res) {
|
|
24
|
+
if (req.session.views) {
|
|
25
|
+
++req.session.views;
|
|
26
|
+
} else {
|
|
27
|
+
req.session.views = 1;
|
|
28
|
+
}
|
|
29
|
+
res.send("Viewed <strong>" + req.session.views + "</strong> times.");
|
|
26
30
|
});
|
|
27
31
|
|
|
28
32
|
http.createServer(app).listen(9341, function() {
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
console.log("Listening on %d", this.address().port);
|
|
34
|
+
});
|
package/tests/test_encrypt.js
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
var express
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
var express = require("express"),
|
|
2
|
+
session = require("express-session"),
|
|
3
|
+
cookieParser = require("cookie-parser"),
|
|
4
|
+
http = require("http"),
|
|
5
|
+
app = express(),
|
|
6
|
+
MemcachedStore = require("../lib/connect-memcached")(session);
|
|
7
7
|
|
|
8
8
|
app.use(cookieParser());
|
|
9
|
-
app.use(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
app.use(
|
|
10
|
+
session({
|
|
11
|
+
secret: "TestEncryptSecret",
|
|
12
|
+
key: "test_encrypt",
|
|
13
|
+
proxy: "true",
|
|
14
|
+
resave: false,
|
|
15
|
+
saveUninitialized: false,
|
|
16
|
+
store: new MemcachedStore({
|
|
17
|
+
hosts: ["127.0.0.1:11211"],
|
|
18
|
+
secret: "Hello there stranger!",
|
|
19
|
+
prefix: "testapp_encrypt_"
|
|
17
20
|
})
|
|
18
|
-
})
|
|
21
|
+
})
|
|
22
|
+
);
|
|
19
23
|
|
|
20
|
-
app.get(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
app.get("/", function(req, res) {
|
|
25
|
+
if (req.session.views) {
|
|
26
|
+
++req.session.views;
|
|
27
|
+
} else {
|
|
28
|
+
req.session.views = 1;
|
|
29
|
+
}
|
|
30
|
+
res.send("Viewed <strong>" + req.session.views + "</strong> times.");
|
|
27
31
|
});
|
|
28
32
|
|
|
29
33
|
http.createServer(app).listen(9341, function() {
|
|
30
|
-
|
|
34
|
+
console.log("Listening on %d", this.address().port);
|
|
31
35
|
});
|
|
32
|
-
|
|
33
|
-
|