@depup/primus 8.0.9-depup.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/LICENSE +22 -0
- package/README.md +36 -0
- package/changes.json +30 -0
- package/dist/primus.js +3663 -0
- package/errors.js +51 -0
- package/index.js +1153 -0
- package/middleware/access-control.js +20 -0
- package/middleware/authorization.js +57 -0
- package/middleware/error.js +41 -0
- package/middleware/forwarded.js +18 -0
- package/middleware/no-cache.js +25 -0
- package/middleware/primus.js +47 -0
- package/middleware/spec.js +36 -0
- package/middleware/xss.js +28 -0
- package/package.json +140 -0
- package/parsers/binary.js +54 -0
- package/parsers/ejson.js +41 -0
- package/parsers/json.js +35 -0
- package/parsers/msgpack.js +55 -0
- package/parsers.json +12 -0
- package/primus.js +1158 -0
- package/spark.js +515 -0
- package/transformer.js +237 -0
- package/transformers/browserchannel/client.js +92 -0
- package/transformers/browserchannel/index.js +19 -0
- package/transformers/browserchannel/server.js +64 -0
- package/transformers/engine.io/README.md +34 -0
- package/transformers/engine.io/client.js +111 -0
- package/transformers/engine.io/index.js +15 -0
- package/transformers/engine.io/library.js +2273 -0
- package/transformers/engine.io/server.js +63 -0
- package/transformers/faye/client.js +103 -0
- package/transformers/faye/index.js +12 -0
- package/transformers/faye/server.js +85 -0
- package/transformers/sockjs/README.md +31 -0
- package/transformers/sockjs/client.js +86 -0
- package/transformers/sockjs/index.js +15 -0
- package/transformers/sockjs/library.js +4201 -0
- package/transformers/sockjs/server.js +108 -0
- package/transformers/uws/index.js +12 -0
- package/transformers/uws/server.js +131 -0
- package/transformers/websockets/client.js +112 -0
- package/transformers/websockets/index.js +12 -0
- package/transformers/websockets/server.js +77 -0
- package/transformers.json +26 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const engine = require('engine.io');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Minimum viable Engine.IO server for Node.js that works through the primus
|
|
7
|
+
* interface.
|
|
8
|
+
*
|
|
9
|
+
* @runat server
|
|
10
|
+
* @api private
|
|
11
|
+
*/
|
|
12
|
+
module.exports = function server() {
|
|
13
|
+
this.service = new engine.Server(Object.assign({
|
|
14
|
+
perMessageDeflate: !!this.primus.options.compression,
|
|
15
|
+
httpCompression: !!this.primus.options.compression,
|
|
16
|
+
maxHttpBufferSize: this.primus.options.maxLength
|
|
17
|
+
}, this.primus.options.transport));
|
|
18
|
+
|
|
19
|
+
//
|
|
20
|
+
// We've received a new connection, create a new Spark. The Spark will
|
|
21
|
+
// automatically announce it self as a new connection once it's created (after
|
|
22
|
+
// the next tick).
|
|
23
|
+
//
|
|
24
|
+
this.service.on('connection', (socket) => {
|
|
25
|
+
const spark = new this.Spark(
|
|
26
|
+
socket.request.headers // HTTP request headers.
|
|
27
|
+
, socket.request.primus // IP Address location.
|
|
28
|
+
, socket.request.query // Optional query string.
|
|
29
|
+
, socket.id // Unique connection id.
|
|
30
|
+
, socket.request // Reference to the HTTP req.
|
|
31
|
+
, socket // Reference to the Engine.IO socket.
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
spark.on('outgoing::end', () => socket && socket.close());
|
|
35
|
+
spark.on('outgoing::data', (data) => socket.write(data));
|
|
36
|
+
|
|
37
|
+
socket.on('error', spark.emits('incoming::error'));
|
|
38
|
+
socket.on('data', spark.emits('incoming::data'));
|
|
39
|
+
socket.on('close', spark.emits('incoming::end', (next) => {
|
|
40
|
+
socket.removeAllListeners();
|
|
41
|
+
socket = null;
|
|
42
|
+
next();
|
|
43
|
+
}));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
//
|
|
47
|
+
// Listen to upgrade requests.
|
|
48
|
+
//
|
|
49
|
+
this.on('upgrade', (req, socket, head) => {
|
|
50
|
+
this.service.handleUpgrade(req, socket, head);
|
|
51
|
+
}).on('request', (req, res) => {
|
|
52
|
+
//
|
|
53
|
+
// Engine.IO closes the handshake socket before we receive a `connection`
|
|
54
|
+
// event. And as the socket is already answered it can be undefined.
|
|
55
|
+
//
|
|
56
|
+
req.primus = {
|
|
57
|
+
remoteAddress: req.socket.remoteAddress,
|
|
58
|
+
remotePort: req.socket.remotePort
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
this.service.handleRequest(req, res);
|
|
62
|
+
}).once('close', () => this.service.close());
|
|
63
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*globals MozWebSocket */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimum viable Faye-WebSocket client. This function is stringified and
|
|
6
|
+
* added in our client-side library.
|
|
7
|
+
*
|
|
8
|
+
* @runat client
|
|
9
|
+
* @api private
|
|
10
|
+
*/
|
|
11
|
+
module.exports = function client() {
|
|
12
|
+
var primus = this
|
|
13
|
+
, socket;
|
|
14
|
+
|
|
15
|
+
//
|
|
16
|
+
// Select an available Faye-WebSocket factory.
|
|
17
|
+
//
|
|
18
|
+
var Factory = (function factory() {
|
|
19
|
+
if ('undefined' !== typeof WebSocket) return WebSocket;
|
|
20
|
+
if ('undefined' !== typeof MozWebSocket) return MozWebSocket;
|
|
21
|
+
|
|
22
|
+
try { return Primus.requires('faye-websocket').Client; }
|
|
23
|
+
catch (e) {}
|
|
24
|
+
|
|
25
|
+
return undefined;
|
|
26
|
+
})();
|
|
27
|
+
|
|
28
|
+
if (!Factory) return primus.critical(new Error(
|
|
29
|
+
'Missing required `faye-websocket` module. ' +
|
|
30
|
+
'Please run `npm install --save faye-websocket`'
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
//
|
|
34
|
+
// Connect to the given URL.
|
|
35
|
+
//
|
|
36
|
+
primus.on('outgoing::open', function opening() {
|
|
37
|
+
primus.emit('outgoing::end');
|
|
38
|
+
|
|
39
|
+
//
|
|
40
|
+
// FireFox will throw an error when we try to establish a connection from
|
|
41
|
+
// a secure page to an unsecured WebSocket connection. This is inconsistent
|
|
42
|
+
// behaviour between different browsers. This should ideally be solved in
|
|
43
|
+
// Primus when we connect.
|
|
44
|
+
//
|
|
45
|
+
try {
|
|
46
|
+
//
|
|
47
|
+
// Only allow primus.transport object in Node.js, it will throw in
|
|
48
|
+
// browsers with a TypeError if we supply to much arguments.
|
|
49
|
+
//
|
|
50
|
+
if (Factory.length === 3) {
|
|
51
|
+
primus.socket = socket = new Factory(
|
|
52
|
+
primus.uri({ protocol: 'ws:', query: true }), // URL
|
|
53
|
+
[], // Sub protocols
|
|
54
|
+
primus.transport // options.
|
|
55
|
+
);
|
|
56
|
+
} else {
|
|
57
|
+
primus.socket = socket = new Factory(primus.uri({
|
|
58
|
+
protocol: 'ws:',
|
|
59
|
+
query: true
|
|
60
|
+
}));
|
|
61
|
+
socket.binaryType = 'arraybuffer';
|
|
62
|
+
}
|
|
63
|
+
} catch (e) { return primus.emit('error', e); }
|
|
64
|
+
|
|
65
|
+
//
|
|
66
|
+
// Setup the Event handlers.
|
|
67
|
+
//
|
|
68
|
+
socket.onopen = primus.emits('incoming::open');
|
|
69
|
+
socket.onerror = primus.emits('incoming::error');
|
|
70
|
+
socket.onclose = primus.emits('incoming::end');
|
|
71
|
+
socket.onmessage = primus.emits('incoming::data', function parse(next, evt) {
|
|
72
|
+
next(undefined, evt.data);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
//
|
|
77
|
+
// We need to write a new message to the socket.
|
|
78
|
+
//
|
|
79
|
+
primus.on('outgoing::data', function write(message) {
|
|
80
|
+
if (!socket || socket.readyState !== 1) return;
|
|
81
|
+
|
|
82
|
+
try { socket.send(message); }
|
|
83
|
+
catch (e) { primus.emit('incoming::error', e); }
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
//
|
|
87
|
+
// Attempt to reconnect the socket.
|
|
88
|
+
//
|
|
89
|
+
primus.on('outgoing::reconnect', function reconnect() {
|
|
90
|
+
primus.emit('outgoing::open');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
//
|
|
94
|
+
// We need to close the socket.
|
|
95
|
+
//
|
|
96
|
+
primus.on('outgoing::end', function close() {
|
|
97
|
+
if (!socket) return;
|
|
98
|
+
|
|
99
|
+
socket.onerror = socket.onopen = socket.onclose = socket.onmessage = function () {};
|
|
100
|
+
socket.close();
|
|
101
|
+
socket = null;
|
|
102
|
+
});
|
|
103
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
// Expose the module as new Transformer instance.
|
|
5
|
+
//
|
|
6
|
+
module.exports = require('../../transformer').extend({
|
|
7
|
+
// Creating a new real-time server.
|
|
8
|
+
server: require('./server'),
|
|
9
|
+
|
|
10
|
+
// The client-logic to connect with the server.
|
|
11
|
+
client: require('./client')
|
|
12
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Faye = require('faye-websocket');
|
|
4
|
+
const http = require('http');
|
|
5
|
+
const url = require('url');
|
|
6
|
+
|
|
7
|
+
const PrimusError = require('../../errors').PrimusError;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Minimum viable WebSocket server that works through the Primus interface.
|
|
11
|
+
*
|
|
12
|
+
* @runat server
|
|
13
|
+
* @api private
|
|
14
|
+
*/
|
|
15
|
+
module.exports = function server() {
|
|
16
|
+
let options = { maxLength: this.primus.options.maxLength };
|
|
17
|
+
|
|
18
|
+
if (this.primus.options.compression) {
|
|
19
|
+
try {
|
|
20
|
+
options.extensions = [ require('permessage-deflate') ];
|
|
21
|
+
} catch (e) {
|
|
22
|
+
[
|
|
23
|
+
'',
|
|
24
|
+
'Missing required npm dependency for faye',
|
|
25
|
+
'To use the permessage-deflate extension with the faye transformer, ',
|
|
26
|
+
'you have to install an additional dependency.',
|
|
27
|
+
'Please run the following command and try again:',
|
|
28
|
+
'',
|
|
29
|
+
' npm install --save permessage-deflate',
|
|
30
|
+
''
|
|
31
|
+
].forEach((line) => console.error(`Primus: ${line}`));
|
|
32
|
+
|
|
33
|
+
throw new PrimusError(
|
|
34
|
+
'Missing dependencies for transformer: "faye"',
|
|
35
|
+
this.primus
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
options = Object.assign(options, this.primus.options.transport);
|
|
41
|
+
|
|
42
|
+
//
|
|
43
|
+
// Listen to upgrade requests.
|
|
44
|
+
//
|
|
45
|
+
this.on('upgrade', (req, socket, head) => {
|
|
46
|
+
if (!Faye.isWebSocket(req)) return socket.destroy();
|
|
47
|
+
|
|
48
|
+
let websocket = new Faye(req, socket, head, null, options);
|
|
49
|
+
|
|
50
|
+
//
|
|
51
|
+
// The WebSocket handshake is complete only when the `open` event is fired.
|
|
52
|
+
//
|
|
53
|
+
websocket.on('open', () => {
|
|
54
|
+
const spark = new this.Spark(
|
|
55
|
+
req.headers // HTTP request headers.
|
|
56
|
+
, req // IP address location.
|
|
57
|
+
, url.parse(req.url).query // Optional query string.
|
|
58
|
+
, null // We don't have an unique id.
|
|
59
|
+
, req // Reference to the HTTP req.
|
|
60
|
+
, websocket // Reference to the WebSocket.
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
spark.on('outgoing::end', () => websocket && websocket.close());
|
|
64
|
+
spark.on('outgoing::data', (data) => websocket.send(data));
|
|
65
|
+
|
|
66
|
+
websocket.on('error', spark.emits('incoming::error'));
|
|
67
|
+
websocket.on('message', spark.emits('incoming::data', (next, evt) => {
|
|
68
|
+
next(undefined, evt.data);
|
|
69
|
+
}));
|
|
70
|
+
websocket.on('close', spark.emits('incoming::end', (next) => {
|
|
71
|
+
websocket.removeAllListeners();
|
|
72
|
+
websocket = null;
|
|
73
|
+
next();
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
//
|
|
79
|
+
// Listen to non-upgrade requests.
|
|
80
|
+
//
|
|
81
|
+
this.on('request', (req, res) => {
|
|
82
|
+
res.writeHead(426, { 'content-type': 'text/plain' });
|
|
83
|
+
res.end(http.STATUS_CODES[426]);
|
|
84
|
+
});
|
|
85
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Transformer: SockJS
|
|
2
|
+
|
|
3
|
+
A transformer abstraction for the SockJS framework. To enable this
|
|
4
|
+
transformer inside of `Primus` you need to add `sockjs` to your package.json:
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
npm install sockjs --save
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
And tell primus to use `sockjs` as transformer.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
var Primus = require('primus');
|
|
14
|
+
|
|
15
|
+
var primus = new Primus(server, { transformer: 'sockjs' });
|
|
16
|
+
|
|
17
|
+
primus.on('connection', function connection(spark) {
|
|
18
|
+
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
# Compiling the SockJS library
|
|
23
|
+
|
|
24
|
+
To build the library use the `update.sh` utility. The steps required are the
|
|
25
|
+
following:
|
|
26
|
+
|
|
27
|
+
1. Fork or clone Primus
|
|
28
|
+
2. cd in the directory and run `npm install`
|
|
29
|
+
3. cd in the directory `transformers/sockjs/` and run `./update.sh`
|
|
30
|
+
4. Commit the changes to the Primus main repository
|
|
31
|
+
5. Profit
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*globals SockJS*/
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimum viable SockJS client. This function is stringified and added
|
|
6
|
+
* in our client-side library.
|
|
7
|
+
*
|
|
8
|
+
* @runat client
|
|
9
|
+
* @api private
|
|
10
|
+
*/
|
|
11
|
+
module.exports = function client() {
|
|
12
|
+
var primus = this
|
|
13
|
+
, socket;
|
|
14
|
+
|
|
15
|
+
//
|
|
16
|
+
// Select an available SockJS factory.
|
|
17
|
+
//
|
|
18
|
+
var Factory = (function Factory() {
|
|
19
|
+
if ('undefined' !== typeof SockJS) return SockJS;
|
|
20
|
+
|
|
21
|
+
try { return Primus.requires('sockjs-client'); }
|
|
22
|
+
catch (e) {}
|
|
23
|
+
|
|
24
|
+
return undefined;
|
|
25
|
+
})();
|
|
26
|
+
|
|
27
|
+
if (!Factory) return primus.critical(new Error(
|
|
28
|
+
'Missing required `sockjs-client` module. ' +
|
|
29
|
+
'Please run `npm install --save sockjs-client`'
|
|
30
|
+
));
|
|
31
|
+
|
|
32
|
+
//
|
|
33
|
+
// Connect to the given URL.
|
|
34
|
+
//
|
|
35
|
+
primus.on('outgoing::open', function opening() {
|
|
36
|
+
primus.emit('outgoing::end');
|
|
37
|
+
|
|
38
|
+
primus.socket = socket = new Factory(
|
|
39
|
+
primus.uri({ protocol: 'http:', query: true }),
|
|
40
|
+
null,
|
|
41
|
+
primus.merge(primus.transport, {
|
|
42
|
+
info: {
|
|
43
|
+
websocket: !primus.AVOID_WEBSOCKETS, // Prevent WebSocket crashes
|
|
44
|
+
cookie_needed: true // Disables xdomainrequest bugs
|
|
45
|
+
}
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
//
|
|
49
|
+
// Setup the Event handlers.
|
|
50
|
+
//
|
|
51
|
+
socket.onopen = primus.emits('incoming::open');
|
|
52
|
+
socket.onerror = primus.emits('incoming::error');
|
|
53
|
+
socket.onclose = function (e) {
|
|
54
|
+
if (e && e.code > 1000) primus.emit('incoming::error', e);
|
|
55
|
+
primus.emit('incoming::end');
|
|
56
|
+
};
|
|
57
|
+
socket.onmessage = primus.emits('incoming::data', function parse(next, evt) {
|
|
58
|
+
next(undefined, evt.data);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
//
|
|
63
|
+
// We need to write a new message to the socket.
|
|
64
|
+
//
|
|
65
|
+
primus.on('outgoing::data', function write(message) {
|
|
66
|
+
if (socket) socket.send(message);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
//
|
|
70
|
+
// Attempt to reconnect the socket.
|
|
71
|
+
//
|
|
72
|
+
primus.on('outgoing::reconnect', function reconnect() {
|
|
73
|
+
primus.emit('outgoing::open');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
//
|
|
77
|
+
// We need to close the socket.
|
|
78
|
+
//
|
|
79
|
+
primus.on('outgoing::end', function close() {
|
|
80
|
+
if (!socket) return;
|
|
81
|
+
|
|
82
|
+
socket.onerror = socket.onopen = socket.onclose = socket.onmessage = function () {};
|
|
83
|
+
socket.close();
|
|
84
|
+
socket = null;
|
|
85
|
+
});
|
|
86
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
// Expose the module as new Transformer instance.
|
|
5
|
+
//
|
|
6
|
+
module.exports = require('../../transformer').extend({
|
|
7
|
+
// Creating a new real-time server.
|
|
8
|
+
server: require('./server'),
|
|
9
|
+
|
|
10
|
+
// The client-logic to connect with the a server.
|
|
11
|
+
client: require('./client'),
|
|
12
|
+
|
|
13
|
+
// The client-side library of sockjs.
|
|
14
|
+
library: require('fs').readFileSync(__dirname + '/library.js', 'utf-8')
|
|
15
|
+
});
|