@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.
Files changed (45) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +36 -0
  3. package/changes.json +30 -0
  4. package/dist/primus.js +3663 -0
  5. package/errors.js +51 -0
  6. package/index.js +1153 -0
  7. package/middleware/access-control.js +20 -0
  8. package/middleware/authorization.js +57 -0
  9. package/middleware/error.js +41 -0
  10. package/middleware/forwarded.js +18 -0
  11. package/middleware/no-cache.js +25 -0
  12. package/middleware/primus.js +47 -0
  13. package/middleware/spec.js +36 -0
  14. package/middleware/xss.js +28 -0
  15. package/package.json +140 -0
  16. package/parsers/binary.js +54 -0
  17. package/parsers/ejson.js +41 -0
  18. package/parsers/json.js +35 -0
  19. package/parsers/msgpack.js +55 -0
  20. package/parsers.json +12 -0
  21. package/primus.js +1158 -0
  22. package/spark.js +515 -0
  23. package/transformer.js +237 -0
  24. package/transformers/browserchannel/client.js +92 -0
  25. package/transformers/browserchannel/index.js +19 -0
  26. package/transformers/browserchannel/server.js +64 -0
  27. package/transformers/engine.io/README.md +34 -0
  28. package/transformers/engine.io/client.js +111 -0
  29. package/transformers/engine.io/index.js +15 -0
  30. package/transformers/engine.io/library.js +2273 -0
  31. package/transformers/engine.io/server.js +63 -0
  32. package/transformers/faye/client.js +103 -0
  33. package/transformers/faye/index.js +12 -0
  34. package/transformers/faye/server.js +85 -0
  35. package/transformers/sockjs/README.md +31 -0
  36. package/transformers/sockjs/client.js +86 -0
  37. package/transformers/sockjs/index.js +15 -0
  38. package/transformers/sockjs/library.js +4201 -0
  39. package/transformers/sockjs/server.js +108 -0
  40. package/transformers/uws/index.js +12 -0
  41. package/transformers/uws/server.js +131 -0
  42. package/transformers/websockets/client.js +112 -0
  43. package/transformers/websockets/index.js +12 -0
  44. package/transformers/websockets/server.js +77 -0
  45. 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
+ });