-
Notifications
You must be signed in to change notification settings - Fork 4
/
cluster-store.js
113 lines (98 loc) · 3.68 KB
/
cluster-store.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
49
50
51
52
53
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright IBM Corp. 2013,2015. All Rights Reserved.
// Node module: strong-cluster-tls-store
// This file is licensed under the Artistic License 2.0.
// License text available at https://opensource.org/licenses/Artistic-2.0
var NativeStore = require('strong-store-cluster');
module.exports = installSessionHandler;
module.exports.setup = setup;
var collection = NativeStore.collection('strong-cluster-tls-session-store');
collection.configure({
expireKeys: 300 // 300 seconds is the default value used by openssl
});
var namespaceRegistry = {};
/**
* Enable TLS session resumption by installing listeners
* for events related to TLS sessions.
* @param {tls.Server} tlsServer Instance of node's TLS server,
* e.g. `https.Server`.
* @param {String} namespace Optional namespace to distinguish between multiple TLS servers. The namespace must be unique within the application and same across all worker processes.
*/
function installSessionHandler(tlsServer, namespace) {
if (namespace == null) namespace = '';
if (namespaceRegistry[namespace]) {
throw new Error('Cannot share TLS sessions between multiple servers. ' +
'Set a unique namespace in the session-sharing initialization.');
}
tlsServer.on('newSession', function(sessionId, sessionData, callback) {
onNewSession(namespace, sessionId, sessionData, callback);
});
tlsServer.on('resumeSession', function(sessionId, callback) {
onResumeSession(namespace, sessionId, callback);
});
namespaceRegistry[namespace] = true;
}
/**
* Save a new session into the store.
* @param {String} namespace The namespace used to store the session data.
* @param {Buffer} sessionId The id used to identify the session.
* @param {Buffer} sessionData The data describing the session state.
* @param {Function} callback Callback, only for node >= 0.12, must be called.
* @private
*/
function onNewSession(namespace, sessionId, sessionData, callback) {
var key = createKey(namespace, sessionId);
var value = encode(sessionData);
collection.set(key, value, callback);
}
/**
* Try to resume a session if it exists.
* @param {String} namespace The namespace where the session data exists.
* @param {Buffer} sessionId The id of the session.
* @param {Function} callback A callback of type function(Error, Buffer)
* @private
*/
function onResumeSession(namespace, sessionId, callback) {
collection.get(createKey(namespace, sessionId), handleGetResponse);
function handleGetResponse(err, value) {
var sessionData = null;
if (!err && value != null) {
sessionData = decode(value);
}
callback(null, sessionData);
}
}
/**
* Creates a key for a given sessionId and namespace.
* @param {String} namespace The namespace where the session resides.
* @param {Buffer} sessionId The id used to refer to the session.
* @return {String} The identifying key for the session.
* @private
*/
function createKey(namespace, sessionId) {
return namespace + '.' + encode(sessionId);
}
/**
* Encodes a Buffer into a value acceptable by NativeStore.
* @param {Buffer} buffer A Node.js Buffer holding session information.
* @return {String} A string representation of the Buffer.
* @private
*/
function encode(buffer) {
return buffer.toString('binary');
}
/**
* Encode a string encode into a Buffer.
* @param {string} string A string to place into a buffer.
* @returns {Buffer} A buffer with the string encoded into it.
* @private
*/
function decode(string) {
return new Buffer(string, 'binary');
}
/**
* Documentation marker for explicit setup of the shared-state server
* in the master process. The initialization happens when this module
* is required, thus calling this function is entirely optional.
*/
function setup() {
}