connect-memcached 0.0.3 → 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/.npmignore CHANGED
@@ -1,4 +1,2 @@
1
- support
2
- test
3
- examples
4
- *.sock
1
+ .idea
2
+ node_modules
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2011-2014 Michał Thoma <michal@balor.pl>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/Readme.md CHANGED
@@ -1,71 +1,81 @@
1
-
2
1
  # connect-memcached
3
2
 
4
- Memcached session store, using [node-memcached](http://github.com/3rd-Eden/node-memcached) for communication with cache server.
3
+ Memcached session store, using [node-memcached](http://github.com/3rd-Eden/node-memcached) for communication with cache server.
5
4
 
6
5
  ## Installation
7
6
 
8
- via npm:
7
+ via npm:
9
8
 
10
- $ npm install connect-memcached
9
+ ```bash
10
+ $ npm install connect-memcached
11
+ ```
11
12
 
12
13
  ## Example
13
14
 
14
- /**
15
- * Module dependencies.
16
- */
17
-
18
- var express = require('express');
19
-
20
- // pass the express to the connect memcached module
21
- // allowing it to inherit from express.session.Store
22
- var MemcachedStore = require('connect-memcached')(express);
23
-
24
- var app = express.createServer();
15
+ ```javascript
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);
22
+
23
+ app.use(cookieParser());
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
34
+ })
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.");
45
+ });
46
+
47
+ http.createServer(app).listen(9341, function() {
48
+ console.log("Listening on %d", this.address().port);
49
+ });
50
+ ```
25
51
 
26
- app.use(express.favicon());
27
-
28
- // request logging
29
- app.use(express.logger());
52
+ ## Options
30
53
 
31
- // required to parse the session cookie
32
- app.use(express.cookieParser());
54
+ - `hosts` Memcached servers locations, can be string, array, hash.
55
+ - `prefix` An optional prefix for each memcache key, in case you are sharing your memcached servers with something generating its own keys.
56
+ - `ttl` An optional parameter used for setting the default TTL (in seconds)
57
+ - `secret` An optional secret can be used to encrypt/decrypt session contents.
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)
59
+ - ... Rest of given option will be passed directly to the node-memcached constructor.
33
60
 
34
- // Populates:
35
- // - req.session
36
- // - req.sessionStore
37
- // - req.sessionID (or req.session.id)
61
+ For details see [node-memcached](http://github.com/3rd-Eden/node-memcached).
38
62
 
39
- app.use(express.session({
40
- secret: 'CatOnTheKeyboard',
41
- store: new MemcachedStore
42
- }));
63
+ ## Upgrading from v0.x.x -> v1.x.x
43
64
 
44
- app.get('/', function(req, res){
45
- if (req.session.views) {
46
- ++req.session.views;
47
- } else {
48
- req.session.views = 1;
49
- }
50
- res.send('Viewed <strong>' + req.session.views + '</strong> times.');
51
- });
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**.
52
66
 
53
- app.listen(3000);
54
- console.log('Express app started on port 3000');
67
+ Upgrading library without taking appropriate action will result in `SyntaxError` exceptions during JSON parsing of decoded entries.
55
68
 
56
- ## Options
69
+ Sessions without encryption are not affected.
57
70
 
58
- - `hosts` Memcached servers locations, can by string, array, hash.
59
- - ... Rest of given option will be passed directly to the node-memcached constructor.
71
+ ## Contributors
60
72
 
61
- For details see [node-memcached](http://github.com/3rd-Eden/node-memcached).
73
+ Big thanks for the contributors! See the actual list [here](https://github.com/balor/connect-memcached/graphs/contributors)!
62
74
 
63
- ## License
75
+ ## License
64
76
 
65
77
  (The MIT License)
66
78
 
67
- Copyright (c) 2011 Michał Thoma &lt;michal@balor.pl&gt;
68
-
69
79
  Permission is hereby granted, free of charge, to any person obtaining
70
80
  a copy of this software and associated documentation files (the
71
81
  'Software'), to deal in the Software without restriction, including
@@ -1,46 +1,27 @@
1
-
2
1
  /*!
3
2
  * connect-memcached
4
- * Copyright(c) 2012 Michał Thoma <michal@balor.pl>
5
3
  * MIT Licensed
6
4
  */
5
+ const bufferFrom = require('buffer-from');
7
6
 
8
- /**
9
- * Library version.
10
- */
11
-
12
- exports.version = '0.0.3';
13
-
14
-
15
- /**
16
- * Module dependencies.
17
- */
18
-
19
- var Memcached = require('memcached');
20
-
21
- /**
22
- * One day in seconds.
23
- */
24
-
7
+ var Memcached = require("memcached");
25
8
  var oneDay = 86400;
26
9
 
27
-
10
+ function ensureCallback(fn) {
11
+ return function() {
12
+ fn && fn.apply(null, arguments);
13
+ };
14
+ }
28
15
 
29
16
  /**
30
17
  * Return the `MemcachedStore` extending `connect`'s session Store.
31
- *
32
- * @param {object} connect
18
+ *
19
+ * @param {object} session
33
20
  * @return {Function}
34
21
  * @api public
35
22
  */
36
-
37
- module.exports = function(connect){
38
-
39
- /**
40
- * Connect's Store.
41
- */
42
-
43
- var Store = connect.session.Store;
23
+ module.exports = function(session) {
24
+ var Store = session.Store;
44
25
 
45
26
  /**
46
27
  * Initialize MemcachedStore with the given `options`.
@@ -48,47 +29,70 @@ module.exports = function(connect){
48
29
  * @param {Object} options
49
30
  * @api public
50
31
  */
51
-
52
32
  function MemcachedStore(options) {
53
33
  options = options || {};
54
34
  Store.call(this, options);
55
- if (!options.hosts) {
56
- options.hosts = '127.0.0.1:11211';
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);
57
50
  }
58
- this.client = new Memcached(options.hosts, options);
59
- console.log("MemcachedStore initialized for servers: " + options.hosts);
60
51
 
61
- this.client.on("issue", function(issue) {
62
- console.log("MemcachedStore::Issue @ " + issue.server + ": " +
63
- issue.messages + ", " + issue.retries + " attempts left");
64
- });
65
- };
52
+ this.client = options.client;
53
+ }
54
+
55
+ MemcachedStore.prototype.__proto__ = Store.prototype;
66
56
 
67
57
  /**
68
- * Inherit from `Store`.
58
+ * Translates the given `sid` into a memcached key, optionally with prefix.
59
+ *
60
+ * @param {String} sid
61
+ * @api private
69
62
  */
70
-
71
- MemcachedStore.prototype.__proto__ = Store.prototype;
63
+ MemcachedStore.prototype.getKey = function getKey(sid) {
64
+ return this.prefix + sid;
65
+ };
72
66
 
73
67
  /**
74
68
  * Attempt to fetch session by the given `sid`.
75
- *
69
+ *
76
70
  * @param {String} sid
77
71
  * @param {Function} fn
78
72
  * @api public
79
73
  */
80
-
81
74
  MemcachedStore.prototype.get = function(sid, fn) {
82
- this.client.get(sid, function(err, data) {
83
- try {
84
- if (!data) {
85
- return fn();
86
- }
87
- fn(null, JSON.parse(data.toString()));
88
- } catch (err) {
89
- fn(err);
90
- }
91
- });
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();
84
+ }
85
+ if (secret) {
86
+ parseable_string = decryptData.call(self, data.toString());
87
+ } else {
88
+ parseable_string = data.toString();
89
+ }
90
+
91
+ fn(null, JSON.parse(parseable_string));
92
+ } catch (e) {
93
+ fn(e);
94
+ }
95
+ });
92
96
  };
93
97
 
94
98
  /**
@@ -99,30 +103,40 @@ module.exports = function(connect){
99
103
  * @param {Function} fn
100
104
  * @api public
101
105
  */
102
-
103
106
  MemcachedStore.prototype.set = function(sid, sess, fn) {
104
- try {
105
- var maxAge = sess.cookie.maxAge
106
- var ttl = 'number' == typeof maxAge ? maxAge / 1000 | 0 : oneDay
107
- var sess = JSON.stringify(sess);
108
-
109
- this.client.set(sid, sess, ttl, function() {
110
- fn && fn.apply(this, arguments);
111
- });
112
- } catch (err) {
113
- fn && fn(err);
114
- }
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);
127
+ }
115
128
  };
116
129
 
117
130
  /**
118
131
  * Destroy the session associated with the given `sid`.
119
- *
132
+ *
120
133
  * @param {String} sid
134
+ * @param {Function} fn
121
135
  * @api public
122
136
  */
123
-
124
137
  MemcachedStore.prototype.destroy = function(sid, fn) {
125
- this.client.del(sid, fn);
138
+ sid = this.getKey(sid);
139
+ this.client.del(sid, ensureCallback(fn));
126
140
  };
127
141
 
128
142
  /**
@@ -131,21 +145,97 @@ module.exports = function(connect){
131
145
  * @param {Function} fn
132
146
  * @api public
133
147
  */
134
-
135
148
  MemcachedStore.prototype.length = function(fn) {
136
- this.client.items(fn);
149
+ this.client.items(ensureCallback(fn));
137
150
  };
138
151
 
139
152
  /**
140
153
  * Clear all sessions.
141
- *
154
+ *
142
155
  * @param {Function} fn
143
156
  * @api public
144
- */
145
-
157
+ */
146
158
  MemcachedStore.prototype.clear = function(fn) {
147
- this.client.flush(fn);
159
+ this.client.flush(ensureCallback(fn));
148
160
  };
149
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
+ }
184
+
185
+ function decryptData(ciphertext) {
186
+ ciphertext = JSON.parse(ciphertext);
187
+
188
+ var hmac = digest.call(this, this.secret, ciphertext.ct);
189
+
190
+ if (hmac != ciphertext.mac) {
191
+ throw "Encrypted session was tampered with!";
192
+ }
193
+
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
+
150
240
  return MemcachedStore;
151
241
  };
package/package.json CHANGED
@@ -1,16 +1,28 @@
1
1
  {
2
- "name": "connect-memcached"
3
- , "version": "0.0.3"
4
- , "description": "Memcached session store for Connect"
5
- , "keywords": ["memcached", "connection", "session", "store", "cache"]
6
- , "author": "Michał Thoma <michal@balor.pl>"
7
- , "repository": {
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": ">= 0.0.1" }
12
- , "devDependencies": { "connect": ">= 1.4.x" }
13
- , "main": "index"
14
- , "engines": { "node": ">=0.4.7" }
15
- , "directories": { "lib": "./lib" }
16
28
  }
package/tests/test.js ADDED
@@ -0,0 +1,34 @@
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
+
8
+ app.use(cookieParser());
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_"
19
+ })
20
+ })
21
+ );
22
+
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.");
30
+ });
31
+
32
+ http.createServer(app).listen(9341, function() {
33
+ console.log("Listening on %d", this.address().port);
34
+ });
@@ -0,0 +1,35 @@
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
+
8
+ app.use(cookieParser());
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_"
20
+ })
21
+ })
22
+ );
23
+
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.");
31
+ });
32
+
33
+ http.createServer(app).listen(9341, function() {
34
+ console.log("Listening on %d", this.address().port);
35
+ });
package/History.md DELETED
@@ -1,14 +0,0 @@
1
- 0.0.3 / 2012-03-06
2
- ==================
3
-
4
- * Rewritten the module due to npm 1.x changes (we now need to pass connect to the function connect-memcached exports in order to extend connect.session.Store:
5
-
6
- 0.0.2 / 2010-01-03
7
- ==================
8
-
9
- * Created basic version that actually works
10
-
11
- 0.0.1 / 2010-01-03
12
- ==================
13
-
14
- * Initial release
package/Makefile DELETED
@@ -1,2 +0,0 @@
1
- doc.json: lib/connect-memcached.js
2
- dox < $< > $@
package/doc.json DELETED
@@ -1,333 +0,0 @@
1
- [
2
- {
3
- "tags": [],
4
- "description": {
5
- "full": "<p>connect-memcached<br />Copyright(c) 2012 Michał Thoma <a href=\"&#109;&#x61;&#x69;l&#116;o:&#x6D;&#105;&#x63;&#104;&#97;&#108;&#64;&#x62;&#97;&#108;&#111;&#114;&#x2E;&#112;&#x6C;\">&#x6D;&#105;&#x63;&#104;&#97;&#108;&#64;&#x62;&#97;&#108;&#111;&#114;&#x2E;&#112;&#x6C;</a><br />MIT Licensed</p>",
6
- "summary": "<p>connect-memcached<br />Copyright(c) 2012 Michał Thoma <a href=\"&#109;&#97;&#x69;l&#116;&#x6F;:&#x6D;&#105;&#99;&#104;&#x61;&#x6C;&#x40;&#98;&#97;&#108;&#111;&#x72;&#46;&#x70;&#x6C;\">&#x6D;&#105;&#99;&#104;&#x61;&#x6C;&#x40;&#98;&#97;&#108;&#111;&#x72;&#46;&#x70;&#x6C;</a><br />MIT Licensed</p>",
7
- "body": ""
8
- },
9
- "ignore": true
10
- },
11
- {
12
- "tags": [],
13
- "description": {
14
- "full": "<p>Library version.</p>",
15
- "summary": "<p>Library version.</p>",
16
- "body": ""
17
- },
18
- "ignore": false,
19
- "code": "exports.version = '0.0.3';",
20
- "ctx": {
21
- "type": "property",
22
- "receiver": "exports",
23
- "name": "version",
24
- "value": "'0.0.3'",
25
- "string": "exports.version"
26
- }
27
- },
28
- {
29
- "tags": [],
30
- "description": {
31
- "full": "<p>Module dependencies.</p>",
32
- "summary": "<p>Module dependencies.</p>",
33
- "body": ""
34
- },
35
- "ignore": false,
36
- "code": "var Memcached = require('memcached');",
37
- "ctx": {
38
- "type": "declaration",
39
- "name": "Memcached",
40
- "value": "require('memcached')",
41
- "string": "Memcached"
42
- }
43
- },
44
- {
45
- "tags": [],
46
- "description": {
47
- "full": "<p>One day in seconds.</p>",
48
- "summary": "<p>One day in seconds.</p>",
49
- "body": ""
50
- },
51
- "ignore": false,
52
- "code": "var oneDay = 86400;",
53
- "ctx": {
54
- "type": "declaration",
55
- "name": "oneDay",
56
- "value": "86400",
57
- "string": "oneDay"
58
- }
59
- },
60
- {
61
- "tags": [
62
- {
63
- "type": "param",
64
- "types": [
65
- "object"
66
- ],
67
- "name": "connect",
68
- "description": ""
69
- },
70
- {
71
- "type": "return",
72
- "types": [
73
- "Function"
74
- ],
75
- "description": ""
76
- },
77
- {
78
- "type": "api",
79
- "visibility": "public"
80
- }
81
- ],
82
- "description": {
83
- "full": "<p>Return the <code>MemcachedStore</code> extending <code>connect</code>'s session Store.</p>",
84
- "summary": "<p>Return the <code>MemcachedStore</code> extending <code>connect</code>'s session Store.</p>",
85
- "body": ""
86
- },
87
- "isPrivate": false,
88
- "ignore": false,
89
- "code": "module.exports = function(connect){",
90
- "ctx": {
91
- "type": "method",
92
- "receiver": "module",
93
- "name": "exports",
94
- "string": "module.exports()"
95
- }
96
- },
97
- {
98
- "tags": [],
99
- "description": {
100
- "full": "<p>Connect's Store.</p>",
101
- "summary": "<p>Connect's Store.</p>",
102
- "body": ""
103
- },
104
- "ignore": false,
105
- "code": "var Store = connect.session.Store;",
106
- "ctx": {
107
- "type": "declaration",
108
- "name": "Store",
109
- "value": "connect.session.Store",
110
- "string": "Store"
111
- }
112
- },
113
- {
114
- "tags": [
115
- {
116
- "type": "param",
117
- "types": [
118
- "Object"
119
- ],
120
- "name": "options",
121
- "description": ""
122
- },
123
- {
124
- "type": "api",
125
- "visibility": "public"
126
- }
127
- ],
128
- "description": {
129
- "full": "<p>Initialize MemcachedStore with the given <code>options</code>.</p>",
130
- "summary": "<p>Initialize MemcachedStore with the given <code>options</code>.</p>",
131
- "body": ""
132
- },
133
- "isPrivate": false,
134
- "ignore": false,
135
- "code": "function MemcachedStore(options) {\n options = options || {};\n Store.call(this, options);\n if (!options.hosts) {\n options.hosts = '127.0.0.1:11211';\n }\n this.client = new Memcached(options.hosts, options);\n console.log(\"MemcachedStore initialized for servers: \" + options.hosts);\n\n this.client.on(\"issue\", function(issue) {\n console.log(\"MemcachedStore::Issue @ \" + issue.server + \": \" + \n issue.messages + \", \" + issue.retries + \" attempts left\");\n });\n };",
136
- "ctx": {
137
- "type": "function",
138
- "name": "MemcachedStore",
139
- "string": "MemcachedStore()"
140
- }
141
- },
142
- {
143
- "tags": [],
144
- "description": {
145
- "full": "<p>Inherit from <code>Store</code>.</p>",
146
- "summary": "<p>Inherit from <code>Store</code>.</p>",
147
- "body": ""
148
- },
149
- "ignore": false,
150
- "code": "MemcachedStore.prototype.__proto__ = Store.prototype;",
151
- "ctx": {
152
- "type": "property",
153
- "constructor": "MemcachedStore",
154
- "name": "__proto__",
155
- "value": "Store.prototype",
156
- "string": "MemcachedStore.prototype__proto__"
157
- }
158
- },
159
- {
160
- "tags": [
161
- {
162
- "type": "param",
163
- "types": [
164
- "String"
165
- ],
166
- "name": "sid",
167
- "description": ""
168
- },
169
- {
170
- "type": "param",
171
- "types": [
172
- "Function"
173
- ],
174
- "name": "fn",
175
- "description": ""
176
- },
177
- {
178
- "type": "api",
179
- "visibility": "public"
180
- }
181
- ],
182
- "description": {
183
- "full": "<p>Attempt to fetch session by the given <code>sid</code>.</p>",
184
- "summary": "<p>Attempt to fetch session by the given <code>sid</code>.</p>",
185
- "body": ""
186
- },
187
- "isPrivate": false,
188
- "ignore": false,
189
- "code": "MemcachedStore.prototype.get = function(sid, fn) {\n this.client.get(sid, function(err, data) {\n try {\n if (!data) {\n return fn();\n }\n fn(null, JSON.parse(data.toString()));\n } catch (err) {\n fn(err);\n } \n });\n };",
190
- "ctx": {
191
- "type": "method",
192
- "constructor": "MemcachedStore",
193
- "name": "get",
194
- "string": "MemcachedStore.prototype.get()"
195
- }
196
- },
197
- {
198
- "tags": [
199
- {
200
- "type": "param",
201
- "types": [
202
- "String"
203
- ],
204
- "name": "sid",
205
- "description": ""
206
- },
207
- {
208
- "type": "param",
209
- "types": [
210
- "Session"
211
- ],
212
- "name": "sess",
213
- "description": ""
214
- },
215
- {
216
- "type": "param",
217
- "types": [
218
- "Function"
219
- ],
220
- "name": "fn",
221
- "description": ""
222
- },
223
- {
224
- "type": "api",
225
- "visibility": "public"
226
- }
227
- ],
228
- "description": {
229
- "full": "<p>Commit the given <code>sess</code> object associated with the given <code>sid</code>.</p>",
230
- "summary": "<p>Commit the given <code>sess</code> object associated with the given <code>sid</code>.</p>",
231
- "body": ""
232
- },
233
- "isPrivate": false,
234
- "ignore": false,
235
- "code": "MemcachedStore.prototype.set = function(sid, sess, fn) {\n try {\n var maxAge = sess.cookie.maxAge\n var ttl = 'number' == typeof maxAge ? maxAge / 1000 | 0 : oneDay\n var sess = JSON.stringify(sess);\n\n this.client.set(sid, sess, ttl, function() {\n fn && fn.apply(this, arguments);\n });\n } catch (err) {\n fn && fn(err);\n } \n };",
236
- "ctx": {
237
- "type": "method",
238
- "constructor": "MemcachedStore",
239
- "name": "set",
240
- "string": "MemcachedStore.prototype.set()"
241
- }
242
- },
243
- {
244
- "tags": [
245
- {
246
- "type": "param",
247
- "types": [
248
- "String"
249
- ],
250
- "name": "sid",
251
- "description": ""
252
- },
253
- {
254
- "type": "api",
255
- "visibility": "public"
256
- }
257
- ],
258
- "description": {
259
- "full": "<p>Destroy the session associated with the given <code>sid</code>.</p>",
260
- "summary": "<p>Destroy the session associated with the given <code>sid</code>.</p>",
261
- "body": ""
262
- },
263
- "isPrivate": false,
264
- "ignore": false,
265
- "code": "MemcachedStore.prototype.destroy = function(sid, fn) {\n this.client.del(sid, fn);\n };",
266
- "ctx": {
267
- "type": "method",
268
- "constructor": "MemcachedStore",
269
- "name": "destroy",
270
- "string": "MemcachedStore.prototype.destroy()"
271
- }
272
- },
273
- {
274
- "tags": [
275
- {
276
- "type": "param",
277
- "types": [
278
- "Function"
279
- ],
280
- "name": "fn",
281
- "description": ""
282
- },
283
- {
284
- "type": "api",
285
- "visibility": "public"
286
- }
287
- ],
288
- "description": {
289
- "full": "<p>Fetch number of sessions.</p>",
290
- "summary": "<p>Fetch number of sessions.</p>",
291
- "body": ""
292
- },
293
- "isPrivate": false,
294
- "ignore": false,
295
- "code": "MemcachedStore.prototype.length = function(fn) {\n this.client.items(fn);\n };",
296
- "ctx": {
297
- "type": "method",
298
- "constructor": "MemcachedStore",
299
- "name": "length",
300
- "string": "MemcachedStore.prototype.length()"
301
- }
302
- },
303
- {
304
- "tags": [
305
- {
306
- "type": "param",
307
- "types": [
308
- "Function"
309
- ],
310
- "name": "fn",
311
- "description": ""
312
- },
313
- {
314
- "type": "api",
315
- "visibility": "public"
316
- }
317
- ],
318
- "description": {
319
- "full": "<p>Clear all sessions.</p>",
320
- "summary": "<p>Clear all sessions.</p>",
321
- "body": ""
322
- },
323
- "isPrivate": false,
324
- "ignore": false,
325
- "code": "MemcachedStore.prototype.clear = function(fn) {\n this.client.flush(fn);\n };\n\n return MemcachedStore;\n};",
326
- "ctx": {
327
- "type": "method",
328
- "constructor": "MemcachedStore",
329
- "name": "clear",
330
- "string": "MemcachedStore.prototype.clear()"
331
- }
332
- }
333
- ]
@@ -1,133 +0,0 @@
1
-
2
- /*!
3
- * connect-memcached
4
- * Copyright(c) 2011 Michał Thoma <michal@balor.pl>
5
- * MIT Licensed
6
- */
7
-
8
- /**
9
- * Library version.
10
- */
11
-
12
- exports.version = '0.0.3';
13
-
14
-
15
- /**
16
- * Module dependencies.
17
- */
18
-
19
- var Store = require('connect').session.Store;
20
- var Memcached = require('memcached');
21
-
22
- /**
23
- * One day in seconds.
24
- */
25
-
26
- var oneDay = 86400;
27
-
28
-
29
-
30
- /**
31
- * Initialize MemcachedStore with the given `options`.
32
- *
33
- * @param {Object} options
34
- * @api public
35
- */
36
-
37
- var MemcachedStore = module.exports = function MemcachedStore(options) {
38
- options = options || {};
39
- Store.call(this, options);
40
- if (!options.hosts) {
41
- options.hosts = '127.0.0.1:11211';
42
- }
43
- this.client = new Memcached(options.hosts, options);
44
- console.log("MemcachedStore initialized for servers: " + options.hosts);
45
-
46
- this.client.on("issue", function(issue) {
47
- console.log("MemcachedStore::Issue @ " + issue.server + ": " +
48
- issue.messages + ", " + issue.retries + " attempts left");
49
- });
50
- };
51
-
52
- /**
53
- * Inherit from `Store`.
54
- */
55
-
56
- MemcachedStore.prototype.__proto__ = Store.prototype;
57
-
58
- /**
59
- * Attempt to fetch session by the given `sid`.
60
- *
61
- * @param {String} sid
62
- * @param {Function} fn
63
- * @api public
64
- */
65
-
66
- MemcachedStore.prototype.get = function(sid, fn) {
67
- this.client.get(sid, function(err, data) {
68
- try {
69
- if (!data) {
70
- return fn();
71
- }
72
- fn(null, JSON.parse(data.toString()));
73
- } catch (err) {
74
- fn(err);
75
- }
76
- });
77
- };
78
-
79
- /**
80
- * Commit the given `sess` object associated with the given `sid`.
81
- *
82
- * @param {String} sid
83
- * @param {Session} sess
84
- * @param {Function} fn
85
- * @api public
86
- */
87
-
88
- MemcachedStore.prototype.set = function(sid, sess, fn) {
89
- try {
90
- var maxAge = sess.cookie.maxAge
91
- var ttl = 'number' == typeof maxAge ? maxAge / 1000 | 0 : oneDay
92
- var sess = JSON.stringify(sess);
93
-
94
- this.client.set(sid, sess, ttl, function() {
95
- fn && fn.apply(this, arguments);
96
- });
97
- } catch (err) {
98
- fn && fn(err);
99
- }
100
- };
101
-
102
- /**
103
- * Destroy the session associated with the given `sid`.
104
- *
105
- * @param {String} sid
106
- * @api public
107
- */
108
-
109
- MemcachedStore.prototype.destroy = function(sid, fn) {
110
- this.client.del(sid, fn);
111
- };
112
-
113
- /**
114
- * Fetch number of sessions.
115
- *
116
- * @param {Function} fn
117
- * @api public
118
- */
119
-
120
- MemcachedStore.prototype.length = function(fn) {
121
- this.client.items(fn);
122
- };
123
-
124
- /**
125
- * Clear all sessions.
126
- *
127
- * @param {Function} fn
128
- * @api public
129
- */
130
-
131
- MemcachedStore.prototype.clear = function(fn) {
132
- this.client.flush(fn);
133
- };