aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ws
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ws')
-rw-r--r--node_modules/ws/.npmignore11
-rw-r--r--node_modules/ws/.travis.yml15
-rw-r--r--node_modules/ws/Makefile45
-rw-r--r--node_modules/ws/README.md235
-rw-r--r--node_modules/ws/SECURITY.md33
-rw-r--r--node_modules/ws/index.js49
-rw-r--r--node_modules/ws/lib/BufferPool.js63
-rw-r--r--node_modules/ws/lib/BufferUtil.fallback.js47
-rw-r--r--node_modules/ws/lib/BufferUtil.js13
-rw-r--r--node_modules/ws/lib/ErrorCodes.js24
-rw-r--r--node_modules/ws/lib/Extensions.js70
-rw-r--r--node_modules/ws/lib/PerMessageDeflate.js337
-rw-r--r--node_modules/ws/lib/Receiver.hixie.js194
-rw-r--r--node_modules/ws/lib/Receiver.js793
-rw-r--r--node_modules/ws/lib/Sender.hixie.js124
-rw-r--r--node_modules/ws/lib/Sender.js324
-rw-r--r--node_modules/ws/lib/Validation.fallback.js11
-rw-r--r--node_modules/ws/lib/Validation.js13
-rw-r--r--node_modules/ws/lib/WebSocket.js987
-rw-r--r--node_modules/ws/lib/WebSocketServer.js554
-rw-r--r--node_modules/ws/package.json40
21 files changed, 0 insertions, 3982 deletions
diff --git a/node_modules/ws/.npmignore b/node_modules/ws/.npmignore
deleted file mode 100644
index 1eba800f8..000000000
--- a/node_modules/ws/.npmignore
+++ /dev/null
@@ -1,11 +0,0 @@
-npm-debug.log
-node_modules
-.*.swp
-.lock-*
-build
-
-bench
-doc
-examples
-test
-
diff --git a/node_modules/ws/.travis.yml b/node_modules/ws/.travis.yml
deleted file mode 100644
index 5002b4984..000000000
--- a/node_modules/ws/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: node_js
-sudo: false
-node_js:
- - "5"
- - "4"
- - "0.12"
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - gcc-4.9
- - g++-4.9
-before_install:
- - export CC="gcc-4.9" CXX="g++-4.9"
diff --git a/node_modules/ws/Makefile b/node_modules/ws/Makefile
deleted file mode 100644
index 94612c5ce..000000000
--- a/node_modules/ws/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-ALL_TESTS = $(shell find test/ -name '*.test.js')
-ALL_INTEGRATION = $(shell find test/ -name '*.integration.js')
-
-run-tests:
- @./node_modules/.bin/mocha \
- -t 5000 \
- -s 2400 \
- $(TESTFLAGS) \
- $(TESTS)
-
-run-integrationtests:
- @./node_modules/.bin/mocha \
- -t 5000 \
- -s 6000 \
- $(TESTFLAGS) \
- $(TESTS)
-
-run-coverage:
- @./node_modules/.bin/istanbul cover --report html \
- ./node_modules/.bin/_mocha -- \
- -t 5000 \
- -s 6000 \
- $(TESTFLAGS) \
- $(TESTS)
-
-test:
- @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests
-
-integrationtest:
- @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_INTEGRATION)" run-integrationtests
-
-coverage:
- @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_TESTS)" run-coverage
-
-benchmark:
- @node bench/sender.benchmark.js
- @node bench/parser.benchmark.js
-
-autobahn:
- @NODE_PATH=lib node test/autobahn.js
-
-autobahn-server:
- @NODE_PATH=lib node test/autobahn-server.js
-
-.PHONY: test coverage
diff --git a/node_modules/ws/README.md b/node_modules/ws/README.md
deleted file mode 100644
index 93106d7a3..000000000
--- a/node_modules/ws/README.md
+++ /dev/null
@@ -1,235 +0,0 @@
-# ws: a node.js websocket library
-
-[![Build Status](https://travis-ci.org/websockets/ws.svg?branch=master)](https://travis-ci.org/websockets/ws)
-
-`ws` is a simple to use WebSocket implementation, up-to-date against RFC-6455,
-and [probably the fastest WebSocket library for node.js][archive].
-
-Passes the quite extensive Autobahn test suite. See http://websockets.github.com/ws
-for the full reports.
-
-## Protocol support
-
-* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera.
- Added to ws version 0.4.2, but server only. Can be disabled by setting the
- `disableHixie` option to true.)
-* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`)
-* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`)
-
-### Installing
-
-```
-npm install --save ws
-```
-
-### Opt-in for performance
-
-There are 2 optional modules that can be installed along side with the `ws`
-module. These modules are binary addons which improve certain operations, but as
-they are binary addons they require compilation which can fail if no c++
-compiler is installed on the host system.
-
-- `npm install --save bufferutil`: Improves internal buffer operations which
- allows for faster processing of masked WebSocket frames and general buffer
- operations.
-- `npm install --save utf-8-validate`: The specification requires validation of
- invalid UTF-8 chars, some of these validations could not be done in JavaScript
- hence the need for a binary addon. In most cases you will already be
- validating the input that you receive for security purposes leading to double
- validation. But if you want to be 100% spec-conforming and have fast
- validation of UTF-8 then this module is a must.
-
-### Sending and receiving text data
-
-```js
-var WebSocket = require('ws');
-var ws = new WebSocket('ws://www.host.com/path');
-
-ws.on('open', function open() {
- ws.send('something');
-});
-
-ws.on('message', function(data, flags) {
- // flags.binary will be set if a binary data is received.
- // flags.masked will be set if the data was masked.
-});
-```
-
-### Sending binary data
-
-```js
-var WebSocket = require('ws');
-var ws = new WebSocket('ws://www.host.com/path');
-
-ws.on('open', function open() {
- var array = new Float32Array(5);
-
- for (var i = 0; i < array.length; ++i) {
- array[i] = i / 2;
- }
-
- ws.send(array, { binary: true, mask: true });
-});
-```
-
-Setting `mask`, as done for the send options above, will cause the data to be
-masked according to the WebSocket protocol. The same option applies for text
-data.
-
-### Server example
-
-```js
-var WebSocketServer = require('ws').Server
- , wss = new WebSocketServer({ port: 8080 });
-
-wss.on('connection', function connection(ws) {
- ws.on('message', function incoming(message) {
- console.log('received: %s', message);
- });
-
- ws.send('something');
-});
-```
-
-### ExpressJS example
-
-```js
-var server = require('http').createServer()
- , url = require('url')
- , WebSocketServer = require('ws').Server
- , wss = new WebSocketServer({ server: server })
- , express = require('express')
- , app = express()
- , port = 4080;
-
-app.use(function (req, res) {
- res.send({ msg: "hello" });
-});
-
-wss.on('connection', function connection(ws) {
- var location = url.parse(ws.upgradeReq.url, true);
- // you might use location.query.access_token to authenticate or share sessions
- // or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312)
-
- ws.on('message', function incoming(message) {
- console.log('received: %s', message);
- });
-
- ws.send('something');
-});
-
-server.on('request', app);
-server.listen(port, function () { console.log('Listening on ' + server.address().port) });
-```
-
-### Server sending broadcast data
-
-```js
-var WebSocketServer = require('ws').Server
- , wss = new WebSocketServer({ port: 8080 });
-
-wss.broadcast = function broadcast(data) {
- wss.clients.forEach(function each(client) {
- client.send(data);
- });
-};
-```
-
-### Error handling best practices
-
-```js
-// If the WebSocket is closed before the following send is attempted
-ws.send('something');
-
-// Errors (both immediate and async write errors) can be detected in an optional
-// callback. The callback is also the only way of being notified that data has
-// actually been sent.
-ws.send('something', function ack(error) {
- // if error is not defined, the send has been completed,
- // otherwise the error object will indicate what failed.
-});
-
-// Immediate errors can also be handled with try/catch-blocks, but **note** that
-// since sends are inherently asynchronous, socket write failures will *not* be
-// captured when this technique is used.
-try { ws.send('something'); }
-catch (e) { /* handle error */ }
-```
-
-### echo.websocket.org demo
-
-```js
-var WebSocket = require('ws');
-var ws = new WebSocket('ws://echo.websocket.org/', {
- protocolVersion: 8,
- origin: 'http://websocket.org'
-});
-
-ws.on('open', function open() {
- console.log('connected');
- ws.send(Date.now().toString(), {mask: true});
-});
-
-ws.on('close', function close() {
- console.log('disconnected');
-});
-
-ws.on('message', function message(data, flags) {
- console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags);
-
- setTimeout(function timeout() {
- ws.send(Date.now().toString(), {mask: true});
- }, 500);
-});
-```
-
-### Other examples
-
-For a full example with a browser client communicating with a ws server, see the
-examples folder.
-
-Note that the usage together with Express 3.0 is quite different from Express
-2.x. The difference is expressed in the two different serverstats-examples.
-
-Otherwise, see the test cases.
-
-### Running the tests
-
-```
-make test
-```
-
-## API Docs
-
-See [`/doc/ws.md`](https://github.com/websockets/ws/blob/master/doc/ws.md) for Node.js-like docs for the ws classes.
-
-## Changelog
-
-We're using the GitHub [`releases`](https://github.com/websockets/ws/releases) for changelog entries.
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2011 Einar Otto Stangvik &lt;einaros@gmail.com&gt;
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-[archive]: http://web.archive.org/web/20130314230536/http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs
diff --git a/node_modules/ws/SECURITY.md b/node_modules/ws/SECURITY.md
deleted file mode 100644
index fd8e07bc5..000000000
--- a/node_modules/ws/SECURITY.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Security Guidelines
-
-Please contact us directly at **security@3rd-Eden.com** for any bug that might
-impact the security of this project. Please prefix the subject of your email
-with `[security]` in lowercase and square brackets. Our email filters will
-automatically prevent these messages from being moved to our spam box.
-
-You will receive an acknowledgement of your report within **24 hours**.
-
-All emails that do not include security vulnerabilities will be removed and
-blocked instantly.
-
-## Exceptions
-
-If you do not receive an acknowledgement within the said time frame please give
-us the benefit of the doubt as it's possible that we haven't seen it yet. In
-this case please send us a message **without details** using one of the
-following methods:
-
-- Contact the lead developers of this project on their personal e-mails. You
- can find the e-mails in the git logs, for example using the following command:
- `git --no-pager show -s --format='%an <%ae>' <gitsha>` where `<gitsha>` is the
- SHA1 of their latest commit in the project.
-- Create a GitHub issue stating contact details and the severity of the issue.
-
-Once we have acknowledged receipt of your report and confirmed the bug
-ourselves we will work with you to fix the vulnerability and publicly acknowledge
-your responsible disclosure, if you wish. In addition to that we will report
-all vulnerabilities to the [Node Security Project](https://nodesecurity.io/).
-
-## History
-
-04 Jan 2016: [Buffer vulnerablity](https://github.com/websockets/ws/releases/tag/1.0.1)
diff --git a/node_modules/ws/index.js b/node_modules/ws/index.js
deleted file mode 100644
index a7e8644b9..000000000
--- a/node_modules/ws/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-'use strict';
-
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var WS = module.exports = require('./lib/WebSocket');
-
-WS.Server = require('./lib/WebSocketServer');
-WS.Sender = require('./lib/Sender');
-WS.Receiver = require('./lib/Receiver');
-
-/**
- * Create a new WebSocket server.
- *
- * @param {Object} options Server options
- * @param {Function} fn Optional connection listener.
- * @returns {WS.Server}
- * @api public
- */
-WS.createServer = function createServer(options, fn) {
- var server = new WS.Server(options);
-
- if (typeof fn === 'function') {
- server.on('connection', fn);
- }
-
- return server;
-};
-
-/**
- * Create a new WebSocket connection.
- *
- * @param {String} address The URL/address we need to connect to.
- * @param {Function} fn Open listener.
- * @returns {WS}
- * @api public
- */
-WS.connect = WS.createConnection = function connect(address, fn) {
- var client = new WS(address);
-
- if (typeof fn === 'function') {
- client.on('open', fn);
- }
-
- return client;
-};
diff --git a/node_modules/ws/lib/BufferPool.js b/node_modules/ws/lib/BufferPool.js
deleted file mode 100644
index 8ee599057..000000000
--- a/node_modules/ws/lib/BufferPool.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var util = require('util');
-
-function BufferPool(initialSize, growStrategy, shrinkStrategy) {
- if (this instanceof BufferPool === false) {
- throw new TypeError("Classes can't be function-called");
- }
-
- if (typeof initialSize === 'function') {
- shrinkStrategy = growStrategy;
- growStrategy = initialSize;
- initialSize = 0;
- }
- else if (typeof initialSize === 'undefined') {
- initialSize = 0;
- }
- this._growStrategy = (growStrategy || function(db, size) {
- return db.used + size;
- }).bind(null, this);
- this._shrinkStrategy = (shrinkStrategy || function(db) {
- return initialSize;
- }).bind(null, this);
- this._buffer = initialSize ? new Buffer(initialSize) : null;
- this._offset = 0;
- this._used = 0;
- this._changeFactor = 0;
- this.__defineGetter__('size', function(){
- return this._buffer == null ? 0 : this._buffer.length;
- });
- this.__defineGetter__('used', function(){
- return this._used;
- });
-}
-
-BufferPool.prototype.get = function(length) {
- if (this._buffer == null || this._offset + length > this._buffer.length) {
- var newBuf = new Buffer(this._growStrategy(length));
- this._buffer = newBuf;
- this._offset = 0;
- }
- this._used += length;
- var buf = this._buffer.slice(this._offset, this._offset + length);
- this._offset += length;
- return buf;
-}
-
-BufferPool.prototype.reset = function(forceNewBuffer) {
- var len = this._shrinkStrategy();
- if (len < this.size) this._changeFactor -= 1;
- if (forceNewBuffer || this._changeFactor < -2) {
- this._changeFactor = 0;
- this._buffer = len ? new Buffer(len) : null;
- }
- this._offset = 0;
- this._used = 0;
-}
-
-module.exports = BufferPool;
diff --git a/node_modules/ws/lib/BufferUtil.fallback.js b/node_modules/ws/lib/BufferUtil.fallback.js
deleted file mode 100644
index 7abd0d8a6..000000000
--- a/node_modules/ws/lib/BufferUtil.fallback.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-exports.BufferUtil = {
- merge: function(mergedBuffer, buffers) {
- var offset = 0;
- for (var i = 0, l = buffers.length; i < l; ++i) {
- var buf = buffers[i];
- buf.copy(mergedBuffer, offset);
- offset += buf.length;
- }
- },
- mask: function(source, mask, output, offset, length) {
- var maskNum = mask.readUInt32LE(0, true);
- var i = 0;
- for (; i < length - 3; i += 4) {
- var num = maskNum ^ source.readUInt32LE(i, true);
- if (num < 0) num = 4294967296 + num;
- output.writeUInt32LE(num, offset + i, true);
- }
- switch (length % 4) {
- case 3: output[offset + i + 2] = source[i + 2] ^ mask[2];
- case 2: output[offset + i + 1] = source[i + 1] ^ mask[1];
- case 1: output[offset + i] = source[i] ^ mask[0];
- case 0:;
- }
- },
- unmask: function(data, mask) {
- var maskNum = mask.readUInt32LE(0, true);
- var length = data.length;
- var i = 0;
- for (; i < length - 3; i += 4) {
- var num = maskNum ^ data.readUInt32LE(i, true);
- if (num < 0) num = 4294967296 + num;
- data.writeUInt32LE(num, i, true);
- }
- switch (length % 4) {
- case 3: data[i + 2] = data[i + 2] ^ mask[2];
- case 2: data[i + 1] = data[i + 1] ^ mask[1];
- case 1: data[i] = data[i] ^ mask[0];
- case 0:;
- }
- }
-}
diff --git a/node_modules/ws/lib/BufferUtil.js b/node_modules/ws/lib/BufferUtil.js
deleted file mode 100644
index 18c699894..000000000
--- a/node_modules/ws/lib/BufferUtil.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-try {
- module.exports = require('bufferutil');
-} catch (e) {
- module.exports = require('./BufferUtil.fallback');
-}
diff --git a/node_modules/ws/lib/ErrorCodes.js b/node_modules/ws/lib/ErrorCodes.js
deleted file mode 100644
index 55ebd529b..000000000
--- a/node_modules/ws/lib/ErrorCodes.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-module.exports = {
- isValidErrorCode: function(code) {
- return (code >= 1000 && code <= 1011 && code != 1004 && code != 1005 && code != 1006) ||
- (code >= 3000 && code <= 4999);
- },
- 1000: 'normal',
- 1001: 'going away',
- 1002: 'protocol error',
- 1003: 'unsupported data',
- 1004: 'reserved',
- 1005: 'reserved for extensions',
- 1006: 'reserved for extensions',
- 1007: 'inconsistent or invalid data',
- 1008: 'policy violation',
- 1009: 'message too big',
- 1010: 'extension handshake missing',
- 1011: 'an unexpected condition prevented the request from being fulfilled',
-}; \ No newline at end of file
diff --git a/node_modules/ws/lib/Extensions.js b/node_modules/ws/lib/Extensions.js
deleted file mode 100644
index a465ace2b..000000000
--- a/node_modules/ws/lib/Extensions.js
+++ /dev/null
@@ -1,70 +0,0 @@
-
-var util = require('util');
-
-/**
- * Module exports.
- */
-
-exports.parse = parse;
-exports.format = format;
-
-/**
- * Parse extensions header value
- */
-
-function parse(value) {
- value = value || '';
-
- var extensions = {};
-
- value.split(',').forEach(function(v) {
- var params = v.split(';');
- var token = params.shift().trim();
- var paramsList = extensions[token] = extensions[token] || [];
- var parsedParams = {};
-
- params.forEach(function(param) {
- var parts = param.trim().split('=');
- var key = parts[0];
- var value = parts[1];
- if (typeof value === 'undefined') {
- value = true;
- } else {
- // unquote value
- if (value[0] === '"') {
- value = value.slice(1);
- }
- if (value[value.length - 1] === '"') {
- value = value.slice(0, value.length - 1);
- }
- }
- (parsedParams[key] = parsedParams[key] || []).push(value);
- });
-
- paramsList.push(parsedParams);
- });
-
- return extensions;
-}
-
-/**
- * Format extensions header value
- */
-
-function format(value) {
- return Object.keys(value).map(function(token) {
- var paramsList = value[token];
- if (!util.isArray(paramsList)) {
- paramsList = [paramsList];
- }
- return paramsList.map(function(params) {
- return [token].concat(Object.keys(params).map(function(k) {
- var p = params[k];
- if (!util.isArray(p)) p = [p];
- return p.map(function(v) {
- return v === true ? k : k + '=' + v;
- }).join('; ');
- })).join('; ');
- }).join(', ');
- }).join(', ');
-}
diff --git a/node_modules/ws/lib/PerMessageDeflate.js b/node_modules/ws/lib/PerMessageDeflate.js
deleted file mode 100644
index 00a6ea62a..000000000
--- a/node_modules/ws/lib/PerMessageDeflate.js
+++ /dev/null
@@ -1,337 +0,0 @@
-
-var zlib = require('zlib');
-
-var AVAILABLE_WINDOW_BITS = [8, 9, 10, 11, 12, 13, 14, 15];
-var DEFAULT_WINDOW_BITS = 15;
-var DEFAULT_MEM_LEVEL = 8;
-
-PerMessageDeflate.extensionName = 'permessage-deflate';
-
-/**
- * Per-message Compression Extensions implementation
- */
-
-function PerMessageDeflate(options, isServer,maxPayload) {
- if (this instanceof PerMessageDeflate === false) {
- throw new TypeError("Classes can't be function-called");
- }
-
- this._options = options || {};
- this._isServer = !!isServer;
- this._inflate = null;
- this._deflate = null;
- this.params = null;
- this._maxPayload = maxPayload || 0;
-}
-
-/**
- * Create extension parameters offer
- *
- * @api public
- */
-
-PerMessageDeflate.prototype.offer = function() {
- var params = {};
- if (this._options.serverNoContextTakeover) {
- params.server_no_context_takeover = true;
- }
- if (this._options.clientNoContextTakeover) {
- params.client_no_context_takeover = true;
- }
- if (this._options.serverMaxWindowBits) {
- params.server_max_window_bits = this._options.serverMaxWindowBits;
- }
- if (this._options.clientMaxWindowBits) {
- params.client_max_window_bits = this._options.clientMaxWindowBits;
- } else if (this._options.clientMaxWindowBits == null) {
- params.client_max_window_bits = true;
- }
- return params;
-};
-
-/**
- * Accept extension offer
- *
- * @api public
- */
-
-PerMessageDeflate.prototype.accept = function(paramsList) {
- paramsList = this.normalizeParams(paramsList);
-
- var params;
- if (this._isServer) {
- params = this.acceptAsServer(paramsList);
- } else {
- params = this.acceptAsClient(paramsList);
- }
-
- this.params = params;
- return params;
-};
-
-/**
- * Releases all resources used by the extension
- *
- * @api public
- */
-
-PerMessageDeflate.prototype.cleanup = function() {
- if (this._inflate) {
- if (this._inflate.writeInProgress) {
- this._inflate.pendingClose = true;
- } else {
- if (this._inflate.close) this._inflate.close();
- this._inflate = null;
- }
- }
- if (this._deflate) {
- if (this._deflate.writeInProgress) {
- this._deflate.pendingClose = true;
- } else {
- if (this._deflate.close) this._deflate.close();
- this._deflate = null;
- }
- }
-};
-
-/**
- * Accept extension offer from client
- *
- * @api private
- */
-
-PerMessageDeflate.prototype.acceptAsServer = function(paramsList) {
- var accepted = {};
- var result = paramsList.some(function(params) {
- accepted = {};
- if (this._options.serverNoContextTakeover === false && params.server_no_context_takeover) {
- return;
- }
- if (this._options.serverMaxWindowBits === false && params.server_max_window_bits) {
- return;
- }
- if (typeof this._options.serverMaxWindowBits === 'number' &&
- typeof params.server_max_window_bits === 'number' &&
- this._options.serverMaxWindowBits > params.server_max_window_bits) {
- return;
- }
- if (typeof this._options.clientMaxWindowBits === 'number' && !params.client_max_window_bits) {
- return;
- }
-
- if (this._options.serverNoContextTakeover || params.server_no_context_takeover) {
- accepted.server_no_context_takeover = true;
- }
- if (this._options.clientNoContextTakeover) {
- accepted.client_no_context_takeover = true;
- }
- if (this._options.clientNoContextTakeover !== false && params.client_no_context_takeover) {
- accepted.client_no_context_takeover = true;
- }
- if (typeof this._options.serverMaxWindowBits === 'number') {
- accepted.server_max_window_bits = this._options.serverMaxWindowBits;
- } else if (typeof params.server_max_window_bits === 'number') {
- accepted.server_max_window_bits = params.server_max_window_bits;
- }
- if (typeof this._options.clientMaxWindowBits === 'number') {
- accepted.client_max_window_bits = this._options.clientMaxWindowBits;
- } else if (this._options.clientMaxWindowBits !== false && typeof params.client_max_window_bits === 'number') {
- accepted.client_max_window_bits = params.client_max_window_bits;
- }
- return true;
- }, this);
-
- if (!result) {
- throw new Error('Doesn\'t support the offered configuration');
- }
-
- return accepted;
-};
-
-/**
- * Accept extension response from server
- *
- * @api privaye
- */
-
-PerMessageDeflate.prototype.acceptAsClient = function(paramsList) {
- var params = paramsList[0];
- if (this._options.clientNoContextTakeover != null) {
- if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) {
- throw new Error('Invalid value for "client_no_context_takeover"');
- }
- }
- if (this._options.clientMaxWindowBits != null) {
- if (this._options.clientMaxWindowBits === false && params.client_max_window_bits) {
- throw new Error('Invalid value for "client_max_window_bits"');
- }
- if (typeof this._options.clientMaxWindowBits === 'number' &&
- (!params.client_max_window_bits || params.client_max_window_bits > this._options.clientMaxWindowBits)) {
- throw new Error('Invalid value for "client_max_window_bits"');
- }
- }
- return params;
-};
-
-/**
- * Normalize extensions parameters
- *
- * @api private
- */
-
-PerMessageDeflate.prototype.normalizeParams = function(paramsList) {
- return paramsList.map(function(params) {
- Object.keys(params).forEach(function(key) {
- var value = params[key];
- if (value.length > 1) {
- throw new Error('Multiple extension parameters for ' + key);
- }
-
- value = value[0];
-
- switch (key) {
- case 'server_no_context_takeover':
- case 'client_no_context_takeover':
- if (value !== true) {
- throw new Error('invalid extension parameter value for ' + key + ' (' + value + ')');
- }
- params[key] = true;
- break;
- case 'server_max_window_bits':
- case 'client_max_window_bits':
- if (typeof value === 'string') {
- value = parseInt(value, 10);
- if (!~AVAILABLE_WINDOW_BITS.indexOf(value)) {
- throw new Error('invalid extension parameter value for ' + key + ' (' + value + ')');
- }
- }
- if (!this._isServer && value === true) {
- throw new Error('Missing extension parameter value for ' + key);
- }
- params[key] = value;
- break;
- default:
- throw new Error('Not defined extension parameter (' + key + ')');
- }
- }, this);
- return params;
- }, this);
-};
-
-/**
- * Decompress message
- *
- * @api public
- */
-
-PerMessageDeflate.prototype.decompress = function (data, fin, callback) {
- var endpoint = this._isServer ? 'client' : 'server';
-
- if (!this._inflate) {
- var maxWindowBits = this.params[endpoint + '_max_window_bits'];
- this._inflate = zlib.createInflateRaw({
- windowBits: 'number' === typeof maxWindowBits ? maxWindowBits : DEFAULT_WINDOW_BITS
- });
- }
- this._inflate.writeInProgress = true;
-
- var self = this;
- var buffers = [];
- var cumulativeBufferLength=0;
-
- this._inflate.on('error', onError).on('data', onData);
- this._inflate.write(data);
- if (fin) {
- this._inflate.write(new Buffer([0x00, 0x00, 0xff, 0xff]));
- }
- this._inflate.flush(function() {
- cleanup();
- callback(null, Buffer.concat(buffers));
- });
-
- function onError(err) {
- cleanup();
- callback(err);
- }
-
- function onData(data) {
- if(self._maxPayload!==undefined && self._maxPayload!==null && self._maxPayload>0){
- cumulativeBufferLength+=data.length;
- if(cumulativeBufferLength>self._maxPayload){
- buffers=[];
- cleanup();
- var err={type:1009};
- callback(err);
- return;
- }
- }
- buffers.push(data);
- }
-
- function cleanup() {
- if (!self._inflate) return;
- self._inflate.removeListener('error', onError);
- self._inflate.removeListener('data', onData);
- self._inflate.writeInProgress = false;
- if ((fin && self.params[endpoint + '_no_context_takeover']) || self._inflate.pendingClose) {
- if (self._inflate.close) self._inflate.close();
- self._inflate = null;
- }
- }
-};
-
-/**
- * Compress message
- *
- * @api public
- */
-
-PerMessageDeflate.prototype.compress = function (data, fin, callback) {
- var endpoint = this._isServer ? 'server' : 'client';
-
- if (!this._deflate) {
- var maxWindowBits = this.params[endpoint + '_max_window_bits'];
- this._deflate = zlib.createDeflateRaw({
- flush: zlib.Z_SYNC_FLUSH,
- windowBits: 'number' === typeof maxWindowBits ? maxWindowBits : DEFAULT_WINDOW_BITS,
- memLevel: this._options.memLevel || DEFAULT_MEM_LEVEL
- });
- }
- this._deflate.writeInProgress = true;
-
- var self = this;
- var buffers = [];
-
- this._deflate.on('error', onError).on('data', onData);
- this._deflate.write(data);
- this._deflate.flush(function() {
- cleanup();
- var data = Buffer.concat(buffers);
- if (fin) {
- data = data.slice(0, data.length - 4);
- }
- callback(null, data);
- });
-
- function onError(err) {
- cleanup();
- callback(err);
- }
-
- function onData(data) {
- buffers.push(data);
- }
-
- function cleanup() {
- if (!self._deflate) return;
- self._deflate.removeListener('error', onError);
- self._deflate.removeListener('data', onData);
- self._deflate.writeInProgress = false;
- if ((fin && self.params[endpoint + '_no_context_takeover']) || self._deflate.pendingClose) {
- if (self._deflate.close) self._deflate.close();
- self._deflate = null;
- }
- }
-};
-
-module.exports = PerMessageDeflate;
diff --git a/node_modules/ws/lib/Receiver.hixie.js b/node_modules/ws/lib/Receiver.hixie.js
deleted file mode 100644
index 598ccbdaf..000000000
--- a/node_modules/ws/lib/Receiver.hixie.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var util = require('util');
-
-/**
- * State constants
- */
-
-var EMPTY = 0
- , BODY = 1;
-var BINARYLENGTH = 2
- , BINARYBODY = 3;
-
-/**
- * Hixie Receiver implementation
- */
-
-function Receiver () {
- if (this instanceof Receiver === false) {
- throw new TypeError("Classes can't be function-called");
- }
-
- this.state = EMPTY;
- this.buffers = [];
- this.messageEnd = -1;
- this.spanLength = 0;
- this.dead = false;
-
- this.onerror = function() {};
- this.ontext = function() {};
- this.onbinary = function() {};
- this.onclose = function() {};
- this.onping = function() {};
- this.onpong = function() {};
-}
-
-module.exports = Receiver;
-
-/**
- * Add new data to the parser.
- *
- * @api public
- */
-
-Receiver.prototype.add = function(data) {
- if (this.dead) return;
- var self = this;
- function doAdd() {
- if (self.state === EMPTY) {
- if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) {
- self.reset();
- self.onclose();
- return;
- }
- if (data[0] === 0x80) {
- self.messageEnd = 0;
- self.state = BINARYLENGTH;
- data = data.slice(1);
- } else {
-
- if (data[0] !== 0x00) {
- self.error('payload must start with 0x00 byte', true);
- return;
- }
- data = data.slice(1);
- self.state = BODY;
-
- }
- }
- if (self.state === BINARYLENGTH) {
- var i = 0;
- while ((i < data.length) && (data[i] & 0x80)) {
- self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f);
- ++i;
- }
- if (i < data.length) {
- self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f);
- self.state = BINARYBODY;
- ++i;
- }
- if (i > 0)
- data = data.slice(i);
- }
- if (self.state === BINARYBODY) {
- var dataleft = self.messageEnd - self.spanLength;
- if (data.length >= dataleft) {
- // consume the whole buffer to finish the frame
- self.buffers.push(data);
- self.spanLength += dataleft;
- self.messageEnd = dataleft;
- return self.parse();
- }
- // frame's not done even if we consume it all
- self.buffers.push(data);
- self.spanLength += data.length;
- return;
- }
- self.buffers.push(data);
- if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) {
- self.spanLength += self.messageEnd;
- return self.parse();
- }
- else self.spanLength += data.length;
- }
- while(data) data = doAdd();
-};
-
-/**
- * Releases all resources used by the receiver.
- *
- * @api public
- */
-
-Receiver.prototype.cleanup = function() {
- this.dead = true;
- this.state = EMPTY;
- this.buffers = [];
-};
-
-/**
- * Process buffered data.
- *
- * @api public
- */
-
-Receiver.prototype.parse = function() {
- var output = new Buffer(this.spanLength);
- var outputIndex = 0;
- for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) {
- var buffer = this.buffers[bi];
- buffer.copy(output, outputIndex);
- outputIndex += buffer.length;
- }
- var lastBuffer = this.buffers[this.buffers.length - 1];
- if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd);
- if (this.state !== BODY) --this.messageEnd;
- var tail = null;
- if (this.messageEnd < lastBuffer.length - 1) {
- tail = lastBuffer.slice(this.messageEnd + 1);
- }
- this.reset();
- this.ontext(output.toString('utf8'));
- return tail;
-};
-
-/**
- * Handles an error
- *
- * @api private
- */
-
-Receiver.prototype.error = function (reason, terminate) {
- if (this.dead) return;
- this.reset();
- if(typeof reason == 'string'){
- this.onerror(new Error(reason), terminate);
- }
- else if(reason.constructor == Error){
- this.onerror(reason, terminate);
- }
- else{
- this.onerror(new Error("An error occured"),terminate);
- }
- return this;
-};
-
-/**
- * Reset parser state
- *
- * @api private
- */
-
-Receiver.prototype.reset = function (reason) {
- if (this.dead) return;
- this.state = EMPTY;
- this.buffers = [];
- this.messageEnd = -1;
- this.spanLength = 0;
-};
-
-/**
- * Internal api
- */
-
-function bufferIndex(buffer, byte) {
- for (var i = 0, l = buffer.length; i < l; ++i) {
- if (buffer[i] === byte) return i;
- }
- return -1;
-}
diff --git a/node_modules/ws/lib/Receiver.js b/node_modules/ws/lib/Receiver.js
deleted file mode 100644
index 0bf29d800..000000000
--- a/node_modules/ws/lib/Receiver.js
+++ /dev/null
@@ -1,793 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var util = require('util')
- , Validation = require('./Validation').Validation
- , ErrorCodes = require('./ErrorCodes')
- , BufferPool = require('./BufferPool')
- , bufferUtil = require('./BufferUtil').BufferUtil
- , PerMessageDeflate = require('./PerMessageDeflate');
-
-/**
- * HyBi Receiver implementation
- */
-
-function Receiver (extensions,maxPayload) {
- if (this instanceof Receiver === false) {
- throw new TypeError("Classes can't be function-called");
- }
- if(typeof extensions==='number'){
- maxPayload=extensions;
- extensions={};
- }
-
-
- // memory pool for fragmented messages
- var fragmentedPoolPrevUsed = -1;
- this.fragmentedBufferPool = new BufferPool(1024, function(db, length) {
- return db.used + length;
- }, function(db) {
- return fragmentedPoolPrevUsed = fragmentedPoolPrevUsed >= 0 ?
- Math.ceil((fragmentedPoolPrevUsed + db.used) / 2) :
- db.used;
- });
-
- // memory pool for unfragmented messages
- var unfragmentedPoolPrevUsed = -1;
- this.unfragmentedBufferPool = new BufferPool(1024, function(db, length) {
- return db.used + length;
- }, function(db) {
- return unfragmentedPoolPrevUsed = unfragmentedPoolPrevUsed >= 0 ?
- Math.ceil((unfragmentedPoolPrevUsed + db.used) / 2) :
- db.used;
- });
- this.extensions = extensions || {};
- this.maxPayload = maxPayload || 0;
- this.currentPayloadLength = 0;
- this.state = {
- activeFragmentedOperation: null,
- lastFragment: false,
- masked: false,
- opcode: 0,
- fragmentedOperation: false
- };
- this.overflow = [];
- this.headerBuffer = new Buffer(10);
- this.expectOffset = 0;
- this.expectBuffer = null;
- this.expectHandler = null;
- this.currentMessage = [];
- this.currentMessageLength = 0;
- this.messageHandlers = [];
- this.expectHeader(2, this.processPacket);
- this.dead = false;
- this.processing = false;
-
- this.onerror = function() {};
- this.ontext = function() {};
- this.onbinary = function() {};
- this.onclose = function() {};
- this.onping = function() {};
- this.onpong = function() {};
-}
-
-module.exports = Receiver;
-
-/**
- * Add new data to the parser.
- *
- * @api public
- */
-
-Receiver.prototype.add = function(data) {
- if (this.dead) return;
- var dataLength = data.length;
- if (dataLength == 0) return;
- if (this.expectBuffer == null) {
- this.overflow.push(data);
- return;
- }
- var toRead = Math.min(dataLength, this.expectBuffer.length - this.expectOffset);
- fastCopy(toRead, data, this.expectBuffer, this.expectOffset);
- this.expectOffset += toRead;
- if (toRead < dataLength) {
- this.overflow.push(data.slice(toRead));
- }
- while (this.expectBuffer && this.expectOffset == this.expectBuffer.length) {
- var bufferForHandler = this.expectBuffer;
- this.expectBuffer = null;
- this.expectOffset = 0;
- this.expectHandler.call(this, bufferForHandler);
- }
-};
-
-/**
- * Releases all resources used by the receiver.
- *
- * @api public
- */
-
-Receiver.prototype.cleanup = function() {
- this.dead = true;
- this.overflow = null;
- this.headerBuffer = null;
- this.expectBuffer = null;
- this.expectHandler = null;
- this.unfragmentedBufferPool = null;
- this.fragmentedBufferPool = null;
- this.state = null;
- this.currentMessage = null;
- this.onerror = null;
- this.ontext = null;
- this.onbinary = null;
- this.onclose = null;
- this.onping = null;
- this.onpong = null;
-};
-
-/**
- * Waits for a certain amount of header bytes to be available, then fires a callback.
- *
- * @api private
- */
-
-Receiver.prototype.expectHeader = function(length, handler) {
- if (length == 0) {
- handler(null);
- return;
- }
- this.expectBuffer = this.headerBuffer.slice(this.expectOffset, this.expectOffset + length);
- this.expectHandler = handler;
- var toRead = length;
- while (toRead > 0 && this.overflow.length > 0) {
- var fromOverflow = this.overflow.pop();
- if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead));
- var read = Math.min(fromOverflow.length, toRead);
- fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset);
- this.expectOffset += read;
- toRead -= read;
- }
-};
-
-/**
- * Waits for a certain amount of data bytes to be available, then fires a callback.
- *
- * @api private
- */
-
-Receiver.prototype.expectData = function(length, handler) {
- if (length == 0) {
- handler(null);
- return;
- }
- this.expectBuffer = this.allocateFromPool(length, this.state.fragmentedOperation);
- this.expectHandler = handler;
- var toRead = length;
- while (toRead > 0 && this.overflow.length > 0) {
- var fromOverflow = this.overflow.pop();
- if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead));
- var read = Math.min(fromOverflow.length, toRead);
- fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset);
- this.expectOffset += read;
- toRead -= read;
- }
-};
-
-/**
- * Allocates memory from the buffer pool.
- *
- * @api private
- */
-
-Receiver.prototype.allocateFromPool = function(length, isFragmented) {
- return (isFragmented ? this.fragmentedBufferPool : this.unfragmentedBufferPool).get(length);
-};
-
-/**
- * Start processing a new packet.
- *
- * @api private
- */
-
-Receiver.prototype.processPacket = function (data) {
- if (this.extensions[PerMessageDeflate.extensionName]) {
- if ((data[0] & 0x30) != 0) {
- this.error('reserved fields (2, 3) must be empty', 1002);
- return;
- }
- } else {
- if ((data[0] & 0x70) != 0) {
- this.error('reserved fields must be empty', 1002);
- return;
- }
- }
- this.state.lastFragment = (data[0] & 0x80) == 0x80;
- this.state.masked = (data[1] & 0x80) == 0x80;
- var compressed = (data[0] & 0x40) == 0x40;
- var opcode = data[0] & 0xf;
- if (opcode === 0) {
- if (compressed) {
- this.error('continuation frame cannot have the Per-message Compressed bits', 1002);
- return;
- }
- // continuation frame
- this.state.fragmentedOperation = true;
- this.state.opcode = this.state.activeFragmentedOperation;
- if (!(this.state.opcode == 1 || this.state.opcode == 2)) {
- this.error('continuation frame cannot follow current opcode', 1002);
- return;
- }
- }
- else {
- if (opcode < 3 && this.state.activeFragmentedOperation != null) {
- this.error('data frames after the initial data frame must have opcode 0', 1002);
- return;
- }
- if (opcode >= 8 && compressed) {
- this.error('control frames cannot have the Per-message Compressed bits', 1002);
- return;
- }
- this.state.compressed = compressed;
- this.state.opcode = opcode;
- if (this.state.lastFragment === false) {
- this.state.fragmentedOperation = true;
- this.state.activeFragmentedOperation = opcode;
- }
- else this.state.fragmentedOperation = false;
- }
- var handler = opcodes[this.state.opcode];
- if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode, 1002);
- else {
- handler.start.call(this, data);
- }
-};
-
-/**
- * Endprocessing a packet.
- *
- * @api private
- */
-
-Receiver.prototype.endPacket = function() {
- if (this.dead) return;
- if (!this.state.fragmentedOperation) this.unfragmentedBufferPool.reset(true);
- else if (this.state.lastFragment) this.fragmentedBufferPool.reset(true);
- this.expectOffset = 0;
- this.expectBuffer = null;
- this.expectHandler = null;
- if (this.state.lastFragment && this.state.opcode === this.state.activeFragmentedOperation) {
- // end current fragmented operation
- this.state.activeFragmentedOperation = null;
- }
- this.currentPayloadLength = 0;
- this.state.lastFragment = false;
- this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0;
- this.state.masked = false;
- this.expectHeader(2, this.processPacket);
-};
-
-/**
- * Reset the parser state.
- *
- * @api private
- */
-
-Receiver.prototype.reset = function() {
- if (this.dead) return;
- this.state = {
- activeFragmentedOperation: null,
- lastFragment: false,
- masked: false,
- opcode: 0,
- fragmentedOperation: false
- };
- this.fragmentedBufferPool.reset(true);
- this.unfragmentedBufferPool.reset(true);
- this.expectOffset = 0;
- this.expectBuffer = null;
- this.expectHandler = null;
- this.overflow = [];
- this.currentMessage = [];
- this.currentMessageLength = 0;
- this.messageHandlers = [];
- this.currentPayloadLength = 0;
-};
-
-/**
- * Unmask received data.
- *
- * @api private
- */
-
-Receiver.prototype.unmask = function (mask, buf, binary) {
- if (mask != null && buf != null) bufferUtil.unmask(buf, mask);
- if (binary) return buf;
- return buf != null ? buf.toString('utf8') : '';
-};
-
-/**
- * Handles an error
- *
- * @api private
- */
-
-Receiver.prototype.error = function (reason, protocolErrorCode) {
- if (this.dead) return;
- this.reset();
- if(typeof reason == 'string'){
- this.onerror(new Error(reason), protocolErrorCode);
- }
- else if(reason.constructor == Error){
- this.onerror(reason, protocolErrorCode);
- }
- else{
- this.onerror(new Error("An error occured"),protocolErrorCode);
- }
- return this;
-};
-
-/**
- * Execute message handler buffers
- *
- * @api private
- */
-
-Receiver.prototype.flush = function() {
- if (this.processing || this.dead) return;
-
- var handler = this.messageHandlers.shift();
- if (!handler) return;
-
- this.processing = true;
- var self = this;
-
- handler(function() {
- self.processing = false;
- self.flush();
- });
-};
-
-/**
- * Apply extensions to message
- *
- * @api private
- */
-
-Receiver.prototype.applyExtensions = function(messageBuffer, fin, compressed, callback) {
- var self = this;
- if (compressed) {
- this.extensions[PerMessageDeflate.extensionName].decompress(messageBuffer, fin, function(err, buffer) {
- if (self.dead) return;
- if (err) {
- callback(new Error('invalid compressed data'));
- return;
- }
- callback(null, buffer);
- });
- } else {
- callback(null, messageBuffer);
- }
-};
-
-/**
-* Checks payload size, disconnects socket when it exceeds maxPayload
-*
-* @api private
-*/
-Receiver.prototype.maxPayloadExceeded = function(length) {
- if (this.maxPayload=== undefined || this.maxPayload === null || this.maxPayload < 1) {
- return false;
- }
- var fullLength = this.currentPayloadLength + length;
- if (fullLength < this.maxPayload) {
- this.currentPayloadLength = fullLength;
- return false;
- }
- this.error('payload cannot exceed ' + this.maxPayload + ' bytes', 1009);
- this.messageBuffer=[];
- this.cleanup();
-
- return true;
-};
-
-/**
- * Buffer utilities
- */
-
-function readUInt16BE(start) {
- return (this[start]<<8) +
- this[start+1];
-}
-
-function readUInt32BE(start) {
- return (this[start]<<24) +
- (this[start+1]<<16) +
- (this[start+2]<<8) +
- this[start+3];
-}
-
-function fastCopy(length, srcBuffer, dstBuffer, dstOffset) {
- switch (length) {
- default: srcBuffer.copy(dstBuffer, dstOffset, 0, length); break;
- case 16: dstBuffer[dstOffset+15] = srcBuffer[15];
- case 15: dstBuffer[dstOffset+14] = srcBuffer[14];
- case 14: dstBuffer[dstOffset+13] = srcBuffer[13];
- case 13: dstBuffer[dstOffset+12] = srcBuffer[12];
- case 12: dstBuffer[dstOffset+11] = srcBuffer[11];
- case 11: dstBuffer[dstOffset+10] = srcBuffer[10];
- case 10: dstBuffer[dstOffset+9] = srcBuffer[9];
- case 9: dstBuffer[dstOffset+8] = srcBuffer[8];
- case 8: dstBuffer[dstOffset+7] = srcBuffer[7];
- case 7: dstBuffer[dstOffset+6] = srcBuffer[6];
- case 6: dstBuffer[dstOffset+5] = srcBuffer[5];
- case 5: dstBuffer[dstOffset+4] = srcBuffer[4];
- case 4: dstBuffer[dstOffset+3] = srcBuffer[3];
- case 3: dstBuffer[dstOffset+2] = srcBuffer[2];
- case 2: dstBuffer[dstOffset+1] = srcBuffer[1];
- case 1: dstBuffer[dstOffset] = srcBuffer[0];
- }
-}
-
-function clone(obj) {
- var cloned = {};
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- cloned[k] = obj[k];
- }
- }
- return cloned;
-}
-
-/**
- * Opcode handlers
- */
-
-var opcodes = {
- // text
- '1': {
- start: function(data) {
- var self = this;
- // decode length
- var firstLength = data[1] & 0x7f;
- if (firstLength < 126) {
- if (self.maxPayloadExceeded(firstLength)){
- self.error('Maximumpayload exceeded in compressed text message. Aborting...', 1009);
- return;
- }
- opcodes['1'].getData.call(self, firstLength);
- }
- else if (firstLength == 126) {
- self.expectHeader(2, function(data) {
- var length = readUInt16BE.call(data, 0);
- if (self.maxPayloadExceeded(length)){
- self.error('Maximumpayload exceeded in compressed text message. Aborting...', 1009);
- return;
- }
- opcodes['1'].getData.call(self, length);
- });
- }
- else if (firstLength == 127) {
- self.expectHeader(8, function(data) {
- if (readUInt32BE.call(data, 0) != 0) {
- self.error('packets with length spanning more than 32 bit is currently not supported', 1008);
- return;
- }
- var length = readUInt32BE.call(data, 4);
- if (self.maxPayloadExceeded(length)){
- self.error('Maximumpayload exceeded in compressed text message. Aborting...', 1009);
- return;
- }
- opcodes['1'].getData.call(self, readUInt32BE.call(data, 4));
- });
- }
- },
- getData: function(length) {
- var self = this;
- if (self.state.masked) {
- self.expectHeader(4, function(data) {
- var mask = data;
- self.expectData(length, function(data) {
- opcodes['1'].finish.call(self, mask, data);
- });
- });
- }
- else {
- self.expectData(length, function(data) {
- opcodes['1'].finish.call(self, null, data);
- });
- }
- },
- finish: function(mask, data) {
- var self = this;
- var packet = this.unmask(mask, data, true) || new Buffer(0);
- var state = clone(this.state);
- this.messageHandlers.push(function(callback) {
- self.applyExtensions(packet, state.lastFragment, state.compressed, function(err, buffer) {
- if (err) {
- if(err.type===1009){
- return self.error('Maximumpayload exceeded in compressed text message. Aborting...', 1009);
- }
- return self.error(err.message, 1007);
- }
- if (buffer != null) {
- if( self.maxPayload==0 || (self.maxPayload > 0 && (self.currentMessageLength + buffer.length) < self.maxPayload) ){
- self.currentMessage.push(buffer);
- }
- else{
- self.currentMessage=null;
- self.currentMessage = [];
- self.currentMessageLength = 0;
- self.error(new Error('Maximum payload exceeded. maxPayload: '+self.maxPayload), 1009);
- return;
- }
- self.currentMessageLength += buffer.length;
- }
- if (state.lastFragment) {
- var messageBuffer = Buffer.concat(self.currentMessage);
- self.currentMessage = [];
- self.currentMessageLength = 0;
- if (!Validation.isValidUTF8(messageBuffer)) {
- self.error('invalid utf8 sequence', 1007);
- return;
- }
- self.ontext(messageBuffer.toString('utf8'), {masked: state.masked, buffer: messageBuffer});
- }
- callback();
- });
- });
- this.flush();
- this.endPacket();
- }
- },
- // binary
- '2': {
- start: function(data) {
- var self = this;
- // decode length
- var firstLength = data[1] & 0x7f;
- if (firstLength < 126) {
- if (self.maxPayloadExceeded(firstLength)){
- self.error('Max payload exceeded in compressed text message. Aborting...', 1009);
- return;
- }
- opcodes['2'].getData.call(self, firstLength);
- }
- else if (firstLength == 126) {
- self.expectHeader(2, function(data) {
- var length = readUInt16BE.call(data, 0);
- if (self.maxPayloadExceeded(length)){
- self.error('Max payload exceeded in compressed text message. Aborting...', 1009);
- return;
- }
- opcodes['2'].getData.call(self, length);
- });
- }
- else if (firstLength == 127) {
- self.expectHeader(8, function(data) {
- if (readUInt32BE.call(data, 0) != 0) {
- self.error('packets with length spanning more than 32 bit is currently not supported', 1008);
- return;
- }
- var length = readUInt32BE.call(data, 4, true);
- if (self.maxPayloadExceeded(length)){
- self.error('Max payload exceeded in compressed text message. Aborting...', 1009);
- return;
- }
- opcodes['2'].getData.call(self, length);
- });
- }
- },
- getData: function(length) {
- var self = this;
- if (self.state.masked) {
- self.expectHeader(4, function(data) {
- var mask = data;
- self.expectData(length, function(data) {
- opcodes['2'].finish.call(self, mask, data);
- });
- });
- }
- else {
- self.expectData(length, function(data) {
- opcodes['2'].finish.call(self, null, data);
- });
- }
- },
- finish: function(mask, data) {
- var self = this;
- var packet = this.unmask(mask, data, true) || new Buffer(0);
- var state = clone(this.state);
- this.messageHandlers.push(function(callback) {
- self.applyExtensions(packet, state.lastFragment, state.compressed, function(err, buffer) {
- if (err) {
- if(err.type===1009){
- return self.error('Max payload exceeded in compressed binary message. Aborting...', 1009);
- }
- return self.error(err.message, 1007);
- }
- if (buffer != null) {
- if( self.maxPayload==0 || (self.maxPayload > 0 && (self.currentMessageLength + buffer.length) < self.maxPayload) ){
- self.currentMessage.push(buffer);
- }
- else{
- self.currentMessage=null;
- self.currentMessage = [];
- self.currentMessageLength = 0;
- self.error(new Error('Maximum payload exceeded'), 1009);
- return;
- }
- self.currentMessageLength += buffer.length;
- }
- if (state.lastFragment) {
- var messageBuffer = Buffer.concat(self.currentMessage);
- self.currentMessage = [];
- self.currentMessageLength = 0;
- self.onbinary(messageBuffer, {masked: state.masked, buffer: messageBuffer});
- }
- callback();
- });
- });
- this.flush();
- this.endPacket();
- }
- },
- // close
- '8': {
- start: function(data) {
- var self = this;
- if (self.state.lastFragment == false) {
- self.error('fragmented close is not supported', 1002);
- return;
- }
-
- // decode length
- var firstLength = data[1] & 0x7f;
- if (firstLength < 126) {
- opcodes['8'].getData.call(self, firstLength);
- }
- else {
- self.error('control frames cannot have more than 125 bytes of data', 1002);
- }
- },
- getData: function(length) {
- var self = this;
- if (self.state.masked) {
- self.expectHeader(4, function(data) {
- var mask = data;
- self.expectData(length, function(data) {
- opcodes['8'].finish.call(self, mask, data);
- });
- });
- }
- else {
- self.expectData(length, function(data) {
- opcodes['8'].finish.call(self, null, data);
- });
- }
- },
- finish: function(mask, data) {
- var self = this;
- data = self.unmask(mask, data, true);
-
- var state = clone(this.state);
- this.messageHandlers.push(function() {
- if (data && data.length == 1) {
- self.error('close packets with data must be at least two bytes long', 1002);
- return;
- }
- var code = data && data.length > 1 ? readUInt16BE.call(data, 0) : 1000;
- if (!ErrorCodes.isValidErrorCode(code)) {
- self.error('invalid error code', 1002);
- return;
- }
- var message = '';
- if (data && data.length > 2) {
- var messageBuffer = data.slice(2);
- if (!Validation.isValidUTF8(messageBuffer)) {
- self.error('invalid utf8 sequence', 1007);
- return;
- }
- message = messageBuffer.toString('utf8');
- }
- self.onclose(code, message, {masked: state.masked});
- self.reset();
- });
- this.flush();
- },
- },
- // ping
- '9': {
- start: function(data) {
- var self = this;
- if (self.state.lastFragment == false) {
- self.error('fragmented ping is not supported', 1002);
- return;
- }
-
- // decode length
- var firstLength = data[1] & 0x7f;
- if (firstLength < 126) {
- opcodes['9'].getData.call(self, firstLength);
- }
- else {
- self.error('control frames cannot have more than 125 bytes of data', 1002);
- }
- },
- getData: function(length) {
- var self = this;
- if (self.state.masked) {
- self.expectHeader(4, function(data) {
- var mask = data;
- self.expectData(length, function(data) {
- opcodes['9'].finish.call(self, mask, data);
- });
- });
- }
- else {
- self.expectData(length, function(data) {
- opcodes['9'].finish.call(self, null, data);
- });
- }
- },
- finish: function(mask, data) {
- var self = this;
- data = this.unmask(mask, data, true);
- var state = clone(this.state);
- this.messageHandlers.push(function(callback) {
- self.onping(data, {masked: state.masked, binary: true});
- callback();
- });
- this.flush();
- this.endPacket();
- }
- },
- // pong
- '10': {
- start: function(data) {
- var self = this;
- if (self.state.lastFragment == false) {
- self.error('fragmented pong is not supported', 1002);
- return;
- }
-
- // decode length
- var firstLength = data[1] & 0x7f;
- if (firstLength < 126) {
- opcodes['10'].getData.call(self, firstLength);
- }
- else {
- self.error('control frames cannot have more than 125 bytes of data', 1002);
- }
- },
- getData: function(length) {
- var self = this;
- if (this.state.masked) {
- this.expectHeader(4, function(data) {
- var mask = data;
- self.expectData(length, function(data) {
- opcodes['10'].finish.call(self, mask, data);
- });
- });
- }
- else {
- this.expectData(length, function(data) {
- opcodes['10'].finish.call(self, null, data);
- });
- }
- },
- finish: function(mask, data) {
- var self = this;
- data = self.unmask(mask, data, true);
- var state = clone(this.state);
- this.messageHandlers.push(function(callback) {
- self.onpong(data, {masked: state.masked, binary: true});
- callback();
- });
- this.flush();
- this.endPacket();
- }
- }
-}
diff --git a/node_modules/ws/lib/Sender.hixie.js b/node_modules/ws/lib/Sender.hixie.js
deleted file mode 100644
index b87d9dd93..000000000
--- a/node_modules/ws/lib/Sender.hixie.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var events = require('events')
- , util = require('util')
- , EventEmitter = events.EventEmitter;
-
-/**
- * Hixie Sender implementation
- */
-
-function Sender(socket) {
- if (this instanceof Sender === false) {
- throw new TypeError("Classes can't be function-called");
- }
-
- events.EventEmitter.call(this);
-
- this.socket = socket;
- this.continuationFrame = false;
- this.isClosed = false;
-}
-
-module.exports = Sender;
-
-/**
- * Inherits from EventEmitter.
- */
-
-util.inherits(Sender, events.EventEmitter);
-
-/**
- * Frames and writes data.
- *
- * @api public
- */
-
-Sender.prototype.send = function(data, options, cb) {
- if (this.isClosed) return;
-
- var isString = typeof data == 'string'
- , length = isString ? Buffer.byteLength(data) : data.length
- , lengthbytes = (length > 127) ? 2 : 1 // assume less than 2**14 bytes
- , writeStartMarker = this.continuationFrame == false
- , writeEndMarker = !options || !(typeof options.fin != 'undefined' && !options.fin)
- , buffer = new Buffer((writeStartMarker ? ((options && options.binary) ? (1 + lengthbytes) : 1) : 0) + length + ((writeEndMarker && !(options && options.binary)) ? 1 : 0))
- , offset = writeStartMarker ? 1 : 0;
-
- if (writeStartMarker) {
- if (options && options.binary) {
- buffer.write('\x80', 'binary');
- // assume length less than 2**14 bytes
- if (lengthbytes > 1)
- buffer.write(String.fromCharCode(128+length/128), offset++, 'binary');
- buffer.write(String.fromCharCode(length&0x7f), offset++, 'binary');
- } else
- buffer.write('\x00', 'binary');
- }
-
- if (isString) buffer.write(data, offset, 'utf8');
- else data.copy(buffer, offset, 0);
-
- if (writeEndMarker) {
- if (options && options.binary) {
- // sending binary, not writing end marker
- } else
- buffer.write('\xff', offset + length, 'binary');
- this.continuationFrame = false;
- }
- else this.continuationFrame = true;
-
- try {
- this.socket.write(buffer, 'binary', cb);
- } catch (e) {
- this.error(e.toString());
- }
-};
-
-/**
- * Sends a close instruction to the remote party.
- *
- * @api public
- */
-
-Sender.prototype.close = function(code, data, mask, cb) {
- if (this.isClosed) return;
- this.isClosed = true;
- try {
- if (this.continuationFrame) this.socket.write(new Buffer([0xff], 'binary'));
- this.socket.write(new Buffer([0xff, 0x00]), 'binary', cb);
- } catch (e) {
- this.error(e.toString());
- }
-};
-
-/**
- * Sends a ping message to the remote party. Not available for hixie.
- *
- * @api public
- */
-
-Sender.prototype.ping = function(data, options) {};
-
-/**
- * Sends a pong message to the remote party. Not available for hixie.
- *
- * @api public
- */
-
-Sender.prototype.pong = function(data, options) {};
-
-/**
- * Handles an error
- *
- * @api private
- */
-
-Sender.prototype.error = function (reason) {
- this.emit('error', reason);
- return this;
-};
diff --git a/node_modules/ws/lib/Sender.js b/node_modules/ws/lib/Sender.js
deleted file mode 100644
index 6ef2ea271..000000000
--- a/node_modules/ws/lib/Sender.js
+++ /dev/null
@@ -1,324 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var events = require('events')
- , util = require('util')
- , EventEmitter = events.EventEmitter
- , ErrorCodes = require('./ErrorCodes')
- , bufferUtil = require('./BufferUtil').BufferUtil
- , PerMessageDeflate = require('./PerMessageDeflate');
-
-/**
- * HyBi Sender implementation
- */
-
-function Sender(socket, extensions) {
- if (this instanceof Sender === false) {
- throw new TypeError("Classes can't be function-called");
- }
-
- events.EventEmitter.call(this);
-
- this._socket = socket;
- this.extensions = extensions || {};
- this.firstFragment = true;
- this.compress = false;
- this.messageHandlers = [];
- this.processing = false;
-}
-
-/**
- * Inherits from EventEmitter.
- */
-
-util.inherits(Sender, events.EventEmitter);
-
-/**
- * Sends a close instruction to the remote party.
- *
- * @api public
- */
-
-Sender.prototype.close = function(code, data, mask, cb) {
- if (typeof code !== 'undefined') {
- if (typeof code !== 'number' ||
- !ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number');
- }
- code = code || 1000;
- var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0));
- writeUInt16BE.call(dataBuffer, code, 0);
- if (dataBuffer.length > 2) dataBuffer.write(data, 2);
-
- var self = this;
- this.messageHandlers.push(function(callback) {
- self.frameAndSend(0x8, dataBuffer, true, mask);
- callback();
- if (typeof cb == 'function') cb();
- });
- this.flush();
-};
-
-/**
- * Sends a ping message to the remote party.
- *
- * @api public
- */
-
-Sender.prototype.ping = function(data, options) {
- var mask = options && options.mask;
- var self = this;
- this.messageHandlers.push(function(callback) {
- self.frameAndSend(0x9, data || '', true, mask);
- callback();
- });
- this.flush();
-};
-
-/**
- * Sends a pong message to the remote party.
- *
- * @api public
- */
-
-Sender.prototype.pong = function(data, options) {
- var mask = options && options.mask;
- var self = this;
- this.messageHandlers.push(function(callback) {
- self.frameAndSend(0xa, data || '', true, mask);
- callback();
- });
- this.flush();
-};
-
-/**
- * Sends text or binary data to the remote party.
- *
- * @api public
- */
-
-Sender.prototype.send = function(data, options, cb) {
- var finalFragment = options && options.fin === false ? false : true;
- var mask = options && options.mask;
- var compress = options && options.compress;
- var opcode = options && options.binary ? 2 : 1;
- if (this.firstFragment === false) {
- opcode = 0;
- compress = false;
- } else {
- this.firstFragment = false;
- this.compress = compress;
- }
- if (finalFragment) this.firstFragment = true
-
- var compressFragment = this.compress;
-
- var self = this;
- this.messageHandlers.push(function(callback) {
- self.applyExtensions(data, finalFragment, compressFragment, function(err, data) {
- if (err) {
- if (typeof cb == 'function') cb(err);
- else self.emit('error', err);
- return;
- }
- self.frameAndSend(opcode, data, finalFragment, mask, compress, cb);
- callback();
- });
- });
- this.flush();
-};
-
-/**
- * Frames and sends a piece of data according to the HyBi WebSocket protocol.
- *
- * @api private
- */
-
-Sender.prototype.frameAndSend = function(opcode, data, finalFragment, maskData, compressed, cb) {
- var canModifyData = false;
-
- if (!data) {
- try {
- this._socket.write(new Buffer([opcode | (finalFragment ? 0x80 : 0), 0 | (maskData ? 0x80 : 0)].concat(maskData ? [0, 0, 0, 0] : [])), 'binary', cb);
- }
- catch (e) {
- if (typeof cb == 'function') cb(e);
- else this.emit('error', e);
- }
- return;
- }
-
- if (!Buffer.isBuffer(data)) {
- canModifyData = true;
- if (data && (typeof data.byteLength !== 'undefined' || typeof data.buffer !== 'undefined')) {
- data = getArrayBuffer(data);
- } else {
- //
- // If people want to send a number, this would allocate the number in
- // bytes as memory size instead of storing the number as buffer value. So
- // we need to transform it to string in order to prevent possible
- // vulnerabilities / memory attacks.
- //
- if (typeof data === 'number') data = data.toString();
-
- data = new Buffer(data);
- }
- }
-
- var dataLength = data.length
- , dataOffset = maskData ? 6 : 2
- , secondByte = dataLength;
-
- if (dataLength >= 65536) {
- dataOffset += 8;
- secondByte = 127;
- }
- else if (dataLength > 125) {
- dataOffset += 2;
- secondByte = 126;
- }
-
- var mergeBuffers = dataLength < 32768 || (maskData && !canModifyData);
- var totalLength = mergeBuffers ? dataLength + dataOffset : dataOffset;
- var outputBuffer = new Buffer(totalLength);
- outputBuffer[0] = finalFragment ? opcode | 0x80 : opcode;
- if (compressed) outputBuffer[0] |= 0x40;
-
- switch (secondByte) {
- case 126:
- writeUInt16BE.call(outputBuffer, dataLength, 2);
- break;
- case 127:
- writeUInt32BE.call(outputBuffer, 0, 2);
- writeUInt32BE.call(outputBuffer, dataLength, 6);
- }
-
- if (maskData) {
- outputBuffer[1] = secondByte | 0x80;
- var mask = getRandomMask();
- outputBuffer[dataOffset - 4] = mask[0];
- outputBuffer[dataOffset - 3] = mask[1];
- outputBuffer[dataOffset - 2] = mask[2];
- outputBuffer[dataOffset - 1] = mask[3];
- if (mergeBuffers) {
- bufferUtil.mask(data, mask, outputBuffer, dataOffset, dataLength);
- try {
- this._socket.write(outputBuffer, 'binary', cb);
- }
- catch (e) {
- if (typeof cb == 'function') cb(e);
- else this.emit('error', e);
- }
- }
- else {
- bufferUtil.mask(data, mask, data, 0, dataLength);
- try {
- this._socket.write(outputBuffer, 'binary');
- this._socket.write(data, 'binary', cb);
- }
- catch (e) {
- if (typeof cb == 'function') cb(e);
- else this.emit('error', e);
- }
- }
- }
- else {
- outputBuffer[1] = secondByte;
- if (mergeBuffers) {
- data.copy(outputBuffer, dataOffset);
- try {
- this._socket.write(outputBuffer, 'binary', cb);
- }
- catch (e) {
- if (typeof cb == 'function') cb(e);
- else this.emit('error', e);
- }
- }
- else {
- try {
- this._socket.write(outputBuffer, 'binary');
- this._socket.write(data, 'binary', cb);
- }
- catch (e) {
- if (typeof cb == 'function') cb(e);
- else this.emit('error', e);
- }
- }
- }
-};
-
-/**
- * Execute message handler buffers
- *
- * @api private
- */
-
-Sender.prototype.flush = function() {
- if (this.processing) return;
-
- var handler = this.messageHandlers.shift();
- if (!handler) return;
-
- this.processing = true;
-
- var self = this;
-
- handler(function() {
- self.processing = false;
- self.flush();
- });
-};
-
-/**
- * Apply extensions to message
- *
- * @api private
- */
-
-Sender.prototype.applyExtensions = function(data, fin, compress, callback) {
- if (compress && data) {
- if ((data.buffer || data) instanceof ArrayBuffer) {
- data = getArrayBuffer(data);
- }
- this.extensions[PerMessageDeflate.extensionName].compress(data, fin, callback);
- } else {
- callback(null, data);
- }
-};
-
-module.exports = Sender;
-
-function writeUInt16BE(value, offset) {
- this[offset] = (value & 0xff00)>>8;
- this[offset+1] = value & 0xff;
-}
-
-function writeUInt32BE(value, offset) {
- this[offset] = (value & 0xff000000)>>24;
- this[offset+1] = (value & 0xff0000)>>16;
- this[offset+2] = (value & 0xff00)>>8;
- this[offset+3] = value & 0xff;
-}
-
-function getArrayBuffer(data) {
- // data is either an ArrayBuffer or ArrayBufferView.
- var array = new Uint8Array(data.buffer || data)
- , l = data.byteLength || data.length
- , o = data.byteOffset || 0
- , buffer = new Buffer(l);
- for (var i = 0; i < l; ++i) {
- buffer[i] = array[o+i];
- }
- return buffer;
-}
-
-function getRandomMask() {
- return new Buffer([
- ~~(Math.random() * 255),
- ~~(Math.random() * 255),
- ~~(Math.random() * 255),
- ~~(Math.random() * 255)
- ]);
-}
diff --git a/node_modules/ws/lib/Validation.fallback.js b/node_modules/ws/lib/Validation.fallback.js
deleted file mode 100644
index 639b0d316..000000000
--- a/node_modules/ws/lib/Validation.fallback.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-exports.Validation = {
- isValidUTF8: function(buffer) {
- return true;
- }
-};
diff --git a/node_modules/ws/lib/Validation.js b/node_modules/ws/lib/Validation.js
deleted file mode 100644
index 0795fb7f0..000000000
--- a/node_modules/ws/lib/Validation.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-try {
- module.exports = require('utf-8-validate');
-} catch (e) {
- module.exports = require('./Validation.fallback');
-}
diff --git a/node_modules/ws/lib/WebSocket.js b/node_modules/ws/lib/WebSocket.js
deleted file mode 100644
index bb09e851b..000000000
--- a/node_modules/ws/lib/WebSocket.js
+++ /dev/null
@@ -1,987 +0,0 @@
-'use strict';
-
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var url = require('url')
- , util = require('util')
- , http = require('http')
- , https = require('https')
- , crypto = require('crypto')
- , stream = require('stream')
- , Ultron = require('ultron')
- , Options = require('options')
- , Sender = require('./Sender')
- , Receiver = require('./Receiver')
- , SenderHixie = require('./Sender.hixie')
- , ReceiverHixie = require('./Receiver.hixie')
- , Extensions = require('./Extensions')
- , PerMessageDeflate = require('./PerMessageDeflate')
- , EventEmitter = require('events').EventEmitter;
-
-/**
- * Constants
- */
-
-// Default protocol version
-
-var protocolVersion = 13;
-
-// Close timeout
-
-var closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly
-
-/**
- * WebSocket implementation
- *
- * @constructor
- * @param {String} address Connection address.
- * @param {String|Array} protocols WebSocket protocols.
- * @param {Object} options Additional connection options.
- * @api public
- */
-function WebSocket(address, protocols, options) {
- if (this instanceof WebSocket === false) {
- return new WebSocket(address, protocols, options);
- }
-
- EventEmitter.call(this);
-
- if (protocols && !Array.isArray(protocols) && 'object' === typeof protocols) {
- // accept the "options" Object as the 2nd argument
- options = protocols;
- protocols = null;
- }
-
- if ('string' === typeof protocols) {
- protocols = [ protocols ];
- }
-
- if (!Array.isArray(protocols)) {
- protocols = [];
- }
-
- this._socket = null;
- this._ultron = null;
- this._closeReceived = false;
- this.bytesReceived = 0;
- this.readyState = null;
- this.supports = {};
- this.extensions = {};
- this._binaryType = 'nodebuffer';
-
- if (Array.isArray(address)) {
- initAsServerClient.apply(this, address.concat(options));
- } else {
- initAsClient.apply(this, [address, protocols, options]);
- }
-}
-
-/**
- * Inherits from EventEmitter.
- */
-util.inherits(WebSocket, EventEmitter);
-
-/**
- * Ready States
- */
-["CONNECTING", "OPEN", "CLOSING", "CLOSED"].forEach(function each(state, index) {
- WebSocket.prototype[state] = WebSocket[state] = index;
-});
-
-/**
- * Gracefully closes the connection, after sending a description message to the server
- *
- * @param {Object} data to be sent to the server
- * @api public
- */
-WebSocket.prototype.close = function close(code, data) {
- if (this.readyState === WebSocket.CLOSED) return;
-
- if (this.readyState === WebSocket.CONNECTING) {
- this.readyState = WebSocket.CLOSED;
- return;
- }
-
- if (this.readyState === WebSocket.CLOSING) {
- if (this._closeReceived && this._isServer) {
- this.terminate();
- }
- return;
- }
-
- var self = this;
- try {
- this.readyState = WebSocket.CLOSING;
- this._closeCode = code;
- this._closeMessage = data;
- var mask = !this._isServer;
- this._sender.close(code, data, mask, function(err) {
- if (err) self.emit('error', err);
-
- if (self._closeReceived && self._isServer) {
- self.terminate();
- } else {
- // ensure that the connection is cleaned up even when no response of closing handshake.
- clearTimeout(self._closeTimer);
- self._closeTimer = setTimeout(cleanupWebsocketResources.bind(self, true), closeTimeout);
- }
- });
- } catch (e) {
- this.emit('error', e);
- }
-};
-
-/**
- * Pause the client stream
- *
- * @api public
- */
-WebSocket.prototype.pause = function pauser() {
- if (this.readyState !== WebSocket.OPEN) throw new Error('not opened');
-
- return this._socket.pause();
-};
-
-/**
- * Sends a ping
- *
- * @param {Object} data to be sent to the server
- * @param {Object} Members - mask: boolean, binary: boolean
- * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open
- * @api public
- */
-WebSocket.prototype.ping = function ping(data, options, dontFailWhenClosed) {
- if (this.readyState !== WebSocket.OPEN) {
- if (dontFailWhenClosed === true) return;
- throw new Error('not opened');
- }
-
- options = options || {};
-
- if (typeof options.mask === 'undefined') options.mask = !this._isServer;
-
- this._sender.ping(data, options);
-};
-
-/**
- * Sends a pong
- *
- * @param {Object} data to be sent to the server
- * @param {Object} Members - mask: boolean, binary: boolean
- * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open
- * @api public
- */
-WebSocket.prototype.pong = function(data, options, dontFailWhenClosed) {
- if (this.readyState !== WebSocket.OPEN) {
- if (dontFailWhenClosed === true) return;
- throw new Error('not opened');
- }
-
- options = options || {};
-
- if (typeof options.mask === 'undefined') options.mask = !this._isServer;
-
- this._sender.pong(data, options);
-};
-
-/**
- * Resume the client stream
- *
- * @api public
- */
-WebSocket.prototype.resume = function resume() {
- if (this.readyState !== WebSocket.OPEN) throw new Error('not opened');
-
- return this._socket.resume();
-};
-
-/**
- * Sends a piece of data
- *
- * @param {Object} data to be sent to the server
- * @param {Object} Members - mask: boolean, binary: boolean, compress: boolean
- * @param {function} Optional callback which is executed after the send completes
- * @api public
- */
-
-WebSocket.prototype.send = function send(data, options, cb) {
- if (typeof options === 'function') {
- cb = options;
- options = {};
- }
-
- if (this.readyState !== WebSocket.OPEN) {
- if (typeof cb === 'function') cb(new Error('not opened'));
- else throw new Error('not opened');
- return;
- }
-
- if (!data) data = '';
- if (this._queue) {
- var self = this;
- this._queue.push(function() { self.send(data, options, cb); });
- return;
- }
-
- options = options || {};
- options.fin = true;
-
- if (typeof options.binary === 'undefined') {
- options.binary = (data instanceof ArrayBuffer || data instanceof Buffer ||
- data instanceof Uint8Array ||
- data instanceof Uint16Array ||
- data instanceof Uint32Array ||
- data instanceof Int8Array ||
- data instanceof Int16Array ||
- data instanceof Int32Array ||
- data instanceof Float32Array ||
- data instanceof Float64Array);
- }
-
- if (typeof options.mask === 'undefined') options.mask = !this._isServer;
- if (typeof options.compress === 'undefined') options.compress = true;
- if (!this.extensions[PerMessageDeflate.extensionName]) {
- options.compress = false;
- }
-
- var readable = typeof stream.Readable === 'function'
- ? stream.Readable
- : stream.Stream;
-
- if (data instanceof readable) {
- startQueue(this);
- var self = this;
-
- sendStream(this, data, options, function send(error) {
- process.nextTick(function tock() {
- executeQueueSends(self);
- });
-
- if (typeof cb === 'function') cb(error);
- });
- } else {
- this._sender.send(data, options, cb);
- }
-};
-
-/**
- * Streams data through calls to a user supplied function
- *
- * @param {Object} Members - mask: boolean, binary: boolean, compress: boolean
- * @param {function} 'function (error, send)' which is executed on successive ticks of which send is 'function (data, final)'.
- * @api public
- */
-WebSocket.prototype.stream = function stream(options, cb) {
- if (typeof options === 'function') {
- cb = options;
- options = {};
- }
-
- var self = this;
-
- if (typeof cb !== 'function') throw new Error('callback must be provided');
-
- if (this.readyState !== WebSocket.OPEN) {
- if (typeof cb === 'function') cb(new Error('not opened'));
- else throw new Error('not opened');
- return;
- }
-
- if (this._queue) {
- this._queue.push(function () { self.stream(options, cb); });
- return;
- }
-
- options = options || {};
-
- if (typeof options.mask === 'undefined') options.mask = !this._isServer;
- if (typeof options.compress === 'undefined') options.compress = true;
- if (!this.extensions[PerMessageDeflate.extensionName]) {
- options.compress = false;
- }
-
- startQueue(this);
-
- function send(data, final) {
- try {
- if (self.readyState !== WebSocket.OPEN) throw new Error('not opened');
- options.fin = final === true;
- self._sender.send(data, options);
- if (!final) process.nextTick(cb.bind(null, null, send));
- else executeQueueSends(self);
- } catch (e) {
- if (typeof cb === 'function') cb(e);
- else {
- delete self._queue;
- self.emit('error', e);
- }
- }
- }
-
- process.nextTick(cb.bind(null, null, send));
-};
-
-/**
- * Immediately shuts down the connection
- *
- * @api public
- */
-WebSocket.prototype.terminate = function terminate() {
- if (this.readyState === WebSocket.CLOSED) return;
-
- if (this._socket) {
- this.readyState = WebSocket.CLOSING;
-
- // End the connection
- try { this._socket.end(); }
- catch (e) {
- // Socket error during end() call, so just destroy it right now
- cleanupWebsocketResources.call(this, true);
- return;
- }
-
- // Add a timeout to ensure that the connection is completely
- // cleaned up within 30 seconds, even if the clean close procedure
- // fails for whatever reason
- // First cleanup any pre-existing timeout from an earlier "terminate" call,
- // if one exists. Otherwise terminate calls in quick succession will leak timeouts
- // and hold the program open for `closeTimout` time.
- if (this._closeTimer) { clearTimeout(this._closeTimer); }
- this._closeTimer = setTimeout(cleanupWebsocketResources.bind(this, true), closeTimeout);
- } else if (this.readyState === WebSocket.CONNECTING) {
- cleanupWebsocketResources.call(this, true);
- }
-};
-
-/**
- * Expose bufferedAmount
- *
- * @api public
- */
-Object.defineProperty(WebSocket.prototype, 'bufferedAmount', {
- get: function get() {
- var amount = 0;
- if (this._socket) {
- amount = this._socket.bufferSize || 0;
- }
- return amount;
- }
-});
-
-/**
- * Expose binaryType
- *
- * This deviates from the W3C interface since ws doesn't support the required
- * default "blob" type (instead we define a custom "nodebuffer" type).
- *
- * @see http://dev.w3.org/html5/websockets/#the-websocket-interface
- * @api public
- */
-Object.defineProperty(WebSocket.prototype, 'binaryType', {
- get: function get() {
- return this._binaryType;
- },
- set: function set(type) {
- if (type === 'arraybuffer' || type === 'nodebuffer')
- this._binaryType = type;
- else
- throw new SyntaxError('unsupported binaryType: must be either "nodebuffer" or "arraybuffer"');
- }
-});
-
-/**
- * Emulates the W3C Browser based WebSocket interface using function members.
- *
- * @see http://dev.w3.org/html5/websockets/#the-websocket-interface
- * @api public
- */
-['open', 'error', 'close', 'message'].forEach(function(method) {
- Object.defineProperty(WebSocket.prototype, 'on' + method, {
- /**
- * Returns the current listener
- *
- * @returns {Mixed} the set function or undefined
- * @api public
- */
- get: function get() {
- var listener = this.listeners(method)[0];
- return listener ? (listener._listener ? listener._listener : listener) : undefined;
- },
-
- /**
- * Start listening for events
- *
- * @param {Function} listener the listener
- * @returns {Mixed} the set function or undefined
- * @api public
- */
- set: function set(listener) {
- this.removeAllListeners(method);
- this.addEventListener(method, listener);
- }
- });
-});
-
-/**
- * Emulates the W3C Browser based WebSocket interface using addEventListener.
- *
- * @see https://developer.mozilla.org/en/DOM/element.addEventListener
- * @see http://dev.w3.org/html5/websockets/#the-websocket-interface
- * @api public
- */
-WebSocket.prototype.addEventListener = function(method, listener) {
- var target = this;
-
- function onMessage (data, flags) {
- if (flags.binary && this.binaryType === 'arraybuffer')
- data = new Uint8Array(data).buffer;
- listener.call(target, new MessageEvent(data, !!flags.binary, target));
- }
-
- function onClose (code, message) {
- listener.call(target, new CloseEvent(code, message, target));
- }
-
- function onError (event) {
- event.type = 'error';
- event.target = target;
- listener.call(target, event);
- }
-
- function onOpen () {
- listener.call(target, new OpenEvent(target));
- }
-
- if (typeof listener === 'function') {
- if (method === 'message') {
- // store a reference so we can return the original function from the
- // addEventListener hook
- onMessage._listener = listener;
- this.on(method, onMessage);
- } else if (method === 'close') {
- // store a reference so we can return the original function from the
- // addEventListener hook
- onClose._listener = listener;
- this.on(method, onClose);
- } else if (method === 'error') {
- // store a reference so we can return the original function from the
- // addEventListener hook
- onError._listener = listener;
- this.on(method, onError);
- } else if (method === 'open') {
- // store a reference so we can return the original function from the
- // addEventListener hook
- onOpen._listener = listener;
- this.on(method, onOpen);
- } else {
- this.on(method, listener);
- }
- }
-};
-
-module.exports = WebSocket;
-module.exports.buildHostHeader = buildHostHeader
-
-/**
- * W3C MessageEvent
- *
- * @see http://www.w3.org/TR/html5/comms.html
- * @constructor
- * @api private
- */
-function MessageEvent(dataArg, isBinary, target) {
- this.type = 'message';
- this.data = dataArg;
- this.target = target;
- this.binary = isBinary; // non-standard.
-}
-
-/**
- * W3C CloseEvent
- *
- * @see http://www.w3.org/TR/html5/comms.html
- * @constructor
- * @api private
- */
-function CloseEvent(code, reason, target) {
- this.type = 'close';
- this.wasClean = (typeof code === 'undefined' || code === 1000);
- this.code = code;
- this.reason = reason;
- this.target = target;
-}
-
-/**
- * W3C OpenEvent
- *
- * @see http://www.w3.org/TR/html5/comms.html
- * @constructor
- * @api private
- */
-function OpenEvent(target) {
- this.type = 'open';
- this.target = target;
-}
-
-// Append port number to Host header, only if specified in the url
-// and non-default
-function buildHostHeader(isSecure, hostname, port) {
- var headerHost = hostname;
- if (hostname) {
- if ((isSecure && (port != 443)) || (!isSecure && (port != 80))){
- headerHost = headerHost + ':' + port;
- }
- }
- return headerHost;
-}
-
-/**
- * Entirely private apis,
- * which may or may not be bound to a sepcific WebSocket instance.
- */
-function initAsServerClient(req, socket, upgradeHead, options) {
- options = new Options({
- protocolVersion: protocolVersion,
- protocol: null,
- extensions: {},
- maxPayload: 0
- }).merge(options);
-
- // expose state properties
- this.protocol = options.value.protocol;
- this.protocolVersion = options.value.protocolVersion;
- this.extensions = options.value.extensions;
- this.supports.binary = (this.protocolVersion !== 'hixie-76');
- this.upgradeReq = req;
- this.readyState = WebSocket.CONNECTING;
- this._isServer = true;
- this.maxPayload = options.value.maxPayload;
- // establish connection
- if (options.value.protocolVersion === 'hixie-76') {
- establishConnection.call(this, ReceiverHixie, SenderHixie, socket, upgradeHead);
- } else {
- establishConnection.call(this, Receiver, Sender, socket, upgradeHead);
- }
-}
-
-function initAsClient(address, protocols, options) {
- options = new Options({
- origin: null,
- protocolVersion: protocolVersion,
- host: null,
- headers: null,
- protocol: protocols.join(','),
- agent: null,
-
- // ssl-related options
- pfx: null,
- key: null,
- passphrase: null,
- cert: null,
- ca: null,
- ciphers: null,
- rejectUnauthorized: null,
- perMessageDeflate: true,
- localAddress: null
- }).merge(options);
-
- if (options.value.protocolVersion !== 8 && options.value.protocolVersion !== 13) {
- throw new Error('unsupported protocol version');
- }
-
- // verify URL and establish http class
- var serverUrl = url.parse(address);
- var isUnixSocket = serverUrl.protocol === 'ws+unix:';
- if (!serverUrl.host && !isUnixSocket) throw new Error('invalid url');
- var isSecure = serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:';
- var httpObj = isSecure ? https : http;
- var port = serverUrl.port || (isSecure ? 443 : 80);
- var auth = serverUrl.auth;
-
- // prepare extensions
- var extensionsOffer = {};
- var perMessageDeflate;
- if (options.value.perMessageDeflate) {
- perMessageDeflate = new PerMessageDeflate(typeof options.value.perMessageDeflate !== true ? options.value.perMessageDeflate : {}, false);
- extensionsOffer[PerMessageDeflate.extensionName] = perMessageDeflate.offer();
- }
-
- // expose state properties
- this._isServer = false;
- this.url = address;
- this.protocolVersion = options.value.protocolVersion;
- this.supports.binary = (this.protocolVersion !== 'hixie-76');
-
- // begin handshake
- var key = new Buffer(options.value.protocolVersion + '-' + Date.now()).toString('base64');
- var shasum = crypto.createHash('sha1');
- shasum.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11');
- var expectedServerKey = shasum.digest('base64');
-
- var agent = options.value.agent;
-
- var headerHost = buildHostHeader(isSecure, serverUrl.hostname, port)
-
- var requestOptions = {
- port: port,
- host: serverUrl.hostname,
- headers: {
- 'Connection': 'Upgrade',
- 'Upgrade': 'websocket',
- 'Host': headerHost,
- 'Sec-WebSocket-Version': options.value.protocolVersion,
- 'Sec-WebSocket-Key': key
- }
- };
-
- // If we have basic auth.
- if (auth) {
- requestOptions.headers.Authorization = 'Basic ' + new Buffer(auth).toString('base64');
- }
-
- if (options.value.protocol) {
- requestOptions.headers['Sec-WebSocket-Protocol'] = options.value.protocol;
- }
-
- if (options.value.host) {
- requestOptions.headers.Host = options.value.host;
- }
-
- if (options.value.headers) {
- for (var header in options.value.headers) {
- if (options.value.headers.hasOwnProperty(header)) {
- requestOptions.headers[header] = options.value.headers[header];
- }
- }
- }
-
- if (Object.keys(extensionsOffer).length) {
- requestOptions.headers['Sec-WebSocket-Extensions'] = Extensions.format(extensionsOffer);
- }
-
- if (options.isDefinedAndNonNull('pfx')
- || options.isDefinedAndNonNull('key')
- || options.isDefinedAndNonNull('passphrase')
- || options.isDefinedAndNonNull('cert')
- || options.isDefinedAndNonNull('ca')
- || options.isDefinedAndNonNull('ciphers')
- || options.isDefinedAndNonNull('rejectUnauthorized')) {
-
- if (options.isDefinedAndNonNull('pfx')) requestOptions.pfx = options.value.pfx;
- if (options.isDefinedAndNonNull('key')) requestOptions.key = options.value.key;
- if (options.isDefinedAndNonNull('passphrase')) requestOptions.passphrase = options.value.passphrase;
- if (options.isDefinedAndNonNull('cert')) requestOptions.cert = options.value.cert;
- if (options.isDefinedAndNonNull('ca')) requestOptions.ca = options.value.ca;
- if (options.isDefinedAndNonNull('ciphers')) requestOptions.ciphers = options.value.ciphers;
- if (options.isDefinedAndNonNull('rejectUnauthorized')) requestOptions.rejectUnauthorized = options.value.rejectUnauthorized;
-
- if (!agent) {
- // global agent ignores client side certificates
- agent = new httpObj.Agent(requestOptions);
- }
- }
-
- requestOptions.path = serverUrl.path || '/';
-
- if (agent) {
- requestOptions.agent = agent;
- }
-
- if (isUnixSocket) {
- requestOptions.socketPath = serverUrl.pathname;
- }
-
- if (options.value.localAddress) {
- requestOptions.localAddress = options.value.localAddress;
- }
-
- if (options.value.origin) {
- if (options.value.protocolVersion < 13) requestOptions.headers['Sec-WebSocket-Origin'] = options.value.origin;
- else requestOptions.headers.Origin = options.value.origin;
- }
-
- var self = this;
- var req = httpObj.request(requestOptions);
-
- req.on('error', function onerror(error) {
- self.emit('error', error);
- cleanupWebsocketResources.call(self, error);
- });
-
- req.once('response', function response(res) {
- var error;
-
- if (!self.emit('unexpected-response', req, res)) {
- error = new Error('unexpected server response (' + res.statusCode + ')');
- req.abort();
- self.emit('error', error);
- }
-
- cleanupWebsocketResources.call(self, error);
- });
-
- req.once('upgrade', function upgrade(res, socket, upgradeHead) {
- if (self.readyState === WebSocket.CLOSED) {
- // client closed before server accepted connection
- self.emit('close');
- self.removeAllListeners();
- socket.end();
- return;
- }
-
- var serverKey = res.headers['sec-websocket-accept'];
- if (typeof serverKey === 'undefined' || serverKey !== expectedServerKey) {
- self.emit('error', 'invalid server key');
- self.removeAllListeners();
- socket.end();
- return;
- }
-
- var serverProt = res.headers['sec-websocket-protocol'];
- var protList = (options.value.protocol || "").split(/, */);
- var protError = null;
-
- if (!options.value.protocol && serverProt) {
- protError = 'server sent a subprotocol even though none requested';
- } else if (options.value.protocol && !serverProt) {
- protError = 'server sent no subprotocol even though requested';
- } else if (serverProt && protList.indexOf(serverProt) === -1) {
- protError = 'server responded with an invalid protocol';
- }
-
- if (protError) {
- self.emit('error', protError);
- self.removeAllListeners();
- socket.end();
- return;
- } else if (serverProt) {
- self.protocol = serverProt;
- }
-
- var serverExtensions = Extensions.parse(res.headers['sec-websocket-extensions']);
- if (perMessageDeflate && serverExtensions[PerMessageDeflate.extensionName]) {
- try {
- perMessageDeflate.accept(serverExtensions[PerMessageDeflate.extensionName]);
- } catch (err) {
- self.emit('error', 'invalid extension parameter');
- self.removeAllListeners();
- socket.end();
- return;
- }
- self.extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
- }
-
- establishConnection.call(self, Receiver, Sender, socket, upgradeHead);
-
- // perform cleanup on http resources
- req.removeAllListeners();
- req = null;
- agent = null;
- });
-
- req.end();
- this.readyState = WebSocket.CONNECTING;
-}
-
-function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) {
- var ultron = this._ultron = new Ultron(socket)
- , called = false
- , self = this;
-
- socket.setTimeout(0);
- socket.setNoDelay(true);
-
- this._receiver = new ReceiverClass(this.extensions,this.maxPayload);
- this._socket = socket;
-
- // socket cleanup handlers
- ultron.on('end', cleanupWebsocketResources.bind(this));
- ultron.on('close', cleanupWebsocketResources.bind(this));
- ultron.on('error', cleanupWebsocketResources.bind(this));
-
- // ensure that the upgradeHead is added to the receiver
- function firstHandler(data) {
- if (called || self.readyState === WebSocket.CLOSED) return;
-
- called = true;
- socket.removeListener('data', firstHandler);
- ultron.on('data', realHandler);
-
- if (upgradeHead && upgradeHead.length > 0) {
- realHandler(upgradeHead);
- upgradeHead = null;
- }
-
- if (data) realHandler(data);
- }
-
- // subsequent packets are pushed straight to the receiver
- function realHandler(data) {
- self.bytesReceived += data.length;
- self._receiver.add(data);
- }
-
- ultron.on('data', firstHandler);
-
- // if data was passed along with the http upgrade,
- // this will schedule a push of that on to the receiver.
- // this has to be done on next tick, since the caller
- // hasn't had a chance to set event handlers on this client
- // object yet.
- process.nextTick(firstHandler);
-
- // receiver event handlers
- self._receiver.ontext = function ontext(data, flags) {
- flags = flags || {};
-
- self.emit('message', data, flags);
- };
-
- self._receiver.onbinary = function onbinary(data, flags) {
- flags = flags || {};
-
- flags.binary = true;
- self.emit('message', data, flags);
- };
-
- self._receiver.onping = function onping(data, flags) {
- flags = flags || {};
-
- self.pong(data, {
- mask: !self._isServer,
- binary: flags.binary === true
- }, true);
-
- self.emit('ping', data, flags);
- };
-
- self._receiver.onpong = function onpong(data, flags) {
- self.emit('pong', data, flags || {});
- };
-
- self._receiver.onclose = function onclose(code, data, flags) {
- flags = flags || {};
-
- self._closeReceived = true;
- self.close(code, data);
- };
-
- self._receiver.onerror = function onerror(reason, errorCode) {
- // close the connection when the receiver reports a HyBi error code
- self.close(typeof errorCode !== 'undefined' ? errorCode : 1002, '');
- self.emit('error', (reason instanceof Error) ? reason : (new Error(reason)));
- };
-
- // finalize the client
- this._sender = new SenderClass(socket, this.extensions);
- this._sender.on('error', function onerror(error) {
- self.close(1002, '');
- self.emit('error', error);
- });
-
- this.readyState = WebSocket.OPEN;
- this.emit('open');
-}
-
-function startQueue(instance) {
- instance._queue = instance._queue || [];
-}
-
-function executeQueueSends(instance) {
- var queue = instance._queue;
- if (typeof queue === 'undefined') return;
-
- delete instance._queue;
- for (var i = 0, l = queue.length; i < l; ++i) {
- queue[i]();
- }
-}
-
-function sendStream(instance, stream, options, cb) {
- stream.on('data', function incoming(data) {
- if (instance.readyState !== WebSocket.OPEN) {
- if (typeof cb === 'function') cb(new Error('not opened'));
- else {
- delete instance._queue;
- instance.emit('error', new Error('not opened'));
- }
- return;
- }
-
- options.fin = false;
- instance._sender.send(data, options);
- });
-
- stream.on('end', function end() {
- if (instance.readyState !== WebSocket.OPEN) {
- if (typeof cb === 'function') cb(new Error('not opened'));
- else {
- delete instance._queue;
- instance.emit('error', new Error('not opened'));
- }
- return;
- }
-
- options.fin = true;
- instance._sender.send(null, options);
-
- if (typeof cb === 'function') cb(null);
- });
-}
-
-function cleanupWebsocketResources(error) {
- if (this.readyState === WebSocket.CLOSED) return;
-
- this.readyState = WebSocket.CLOSED;
-
- clearTimeout(this._closeTimer);
- this._closeTimer = null;
-
- // If the connection was closed abnormally (with an error), or if
- // the close control frame was not received then the close code
- // must default to 1006.
- if (error || !this._closeReceived) {
- this._closeCode = 1006;
- }
- this.emit('close', this._closeCode || 1000, this._closeMessage || '');
-
- if (this._socket) {
- if (this._ultron) this._ultron.destroy();
- this._socket.on('error', function onerror() {
- try { this.destroy(); }
- catch (e) {}
- });
-
- try {
- if (!error) this._socket.end();
- else this._socket.destroy();
- } catch (e) { /* Ignore termination errors */ }
-
- this._socket = null;
- this._ultron = null;
- }
-
- if (this._sender) {
- this._sender.removeAllListeners();
- this._sender = null;
- }
-
- if (this._receiver) {
- this._receiver.cleanup();
- this._receiver = null;
- }
-
- if (this.extensions[PerMessageDeflate.extensionName]) {
- this.extensions[PerMessageDeflate.extensionName].cleanup();
- }
-
- this.extensions = null;
-
- this.removeAllListeners();
- this.on('error', function onerror() {}); // catch all errors after this
- delete this._queue;
-}
diff --git a/node_modules/ws/lib/WebSocketServer.js b/node_modules/ws/lib/WebSocketServer.js
deleted file mode 100644
index 92077cd5a..000000000
--- a/node_modules/ws/lib/WebSocketServer.js
+++ /dev/null
@@ -1,554 +0,0 @@
-/*!
- * ws: a node.js websocket client
- * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
- * MIT Licensed
- */
-
-var util = require('util')
- , events = require('events')
- , http = require('http')
- , crypto = require('crypto')
- , Options = require('options')
- , WebSocket = require('./WebSocket')
- , Extensions = require('./Extensions')
- , PerMessageDeflate = require('./PerMessageDeflate')
- , tls = require('tls')
- , url = require('url');
-
-/**
- * WebSocket Server implementation
- */
-
-function WebSocketServer(options, callback) {
- if (this instanceof WebSocketServer === false) {
- return new WebSocketServer(options, callback);
- }
-
- events.EventEmitter.call(this);
-
- options = new Options({
- host: '0.0.0.0',
- port: null,
- server: null,
- verifyClient: null,
- handleProtocols: null,
- path: null,
- noServer: false,
- disableHixie: false,
- clientTracking: true,
- perMessageDeflate: true,
- maxPayload: 100 * 1024 * 1024
- }).merge(options);
-
- if (!options.isDefinedAndNonNull('port') && !options.isDefinedAndNonNull('server') && !options.value.noServer) {
- throw new TypeError('`port` or a `server` must be provided');
- }
-
- var self = this;
-
- if (options.isDefinedAndNonNull('port')) {
- this._server = http.createServer(function (req, res) {
- var body = http.STATUS_CODES[426];
- res.writeHead(426, {
- 'Content-Length': body.length,
- 'Content-Type': 'text/plain'
- });
- res.end(body);
- });
- this._server.allowHalfOpen = false;
- this._server.listen(options.value.port, options.value.host, callback);
- this._closeServer = function() { if (self._server) self._server.close(); };
- }
- else if (options.value.server) {
- this._server = options.value.server;
- if (options.value.path) {
- // take note of the path, to avoid collisions when multiple websocket servers are
- // listening on the same http server
- if (this._server._webSocketPaths && options.value.server._webSocketPaths[options.value.path]) {
- throw new Error('two instances of WebSocketServer cannot listen on the same http server path');
- }
- if (typeof this._server._webSocketPaths !== 'object') {
- this._server._webSocketPaths = {};
- }
- this._server._webSocketPaths[options.value.path] = 1;
- }
- }
- if (this._server) {
- this._onceServerListening = function() { self.emit('listening'); };
- this._server.once('listening', this._onceServerListening);
- }
-
- if (typeof this._server != 'undefined') {
- this._onServerError = function(error) { self.emit('error', error) };
- this._server.on('error', this._onServerError);
- this._onServerUpgrade = function(req, socket, upgradeHead) {
- //copy upgradeHead to avoid retention of large slab buffers used in node core
- var head = new Buffer(upgradeHead.length);
- upgradeHead.copy(head);
-
- self.handleUpgrade(req, socket, head, function(client) {
- self.emit('connection'+req.url, client);
- self.emit('connection', client);
- });
- };
- this._server.on('upgrade', this._onServerUpgrade);
- }
-
- this.options = options.value;
- this.path = options.value.path;
- this.clients = [];
-}
-
-/**
- * Inherits from EventEmitter.
- */
-
-util.inherits(WebSocketServer, events.EventEmitter);
-
-/**
- * Immediately shuts down the connection.
- *
- * @api public
- */
-
-WebSocketServer.prototype.close = function(callback) {
- // terminate all associated clients
- var error = null;
- try {
- for (var i = 0, l = this.clients.length; i < l; ++i) {
- this.clients[i].terminate();
- }
- }
- catch (e) {
- error = e;
- }
-
- // remove path descriptor, if any
- if (this.path && this._server._webSocketPaths) {
- delete this._server._webSocketPaths[this.path];
- if (Object.keys(this._server._webSocketPaths).length == 0) {
- delete this._server._webSocketPaths;
- }
- }
-
- // close the http server if it was internally created
- try {
- if (typeof this._closeServer !== 'undefined') {
- this._closeServer();
- }
- }
- finally {
- if (this._server) {
- this._server.removeListener('listening', this._onceServerListening);
- this._server.removeListener('error', this._onServerError);
- this._server.removeListener('upgrade', this._onServerUpgrade);
- }
- delete this._server;
- }
- if(callback)
- callback(error);
- else if(error)
- throw error;
-}
-
-/**
- * Handle a HTTP Upgrade request.
- *
- * @api public
- */
-
-WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb) {
- // check for wrong path
- if (this.options.path) {
- var u = url.parse(req.url);
- if (u && u.pathname !== this.options.path) return;
- }
-
- if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') {
- abortConnection(socket, 400, 'Bad Request');
- return;
- }
-
- if (req.headers['sec-websocket-key1']) handleHixieUpgrade.apply(this, arguments);
- else handleHybiUpgrade.apply(this, arguments);
-}
-
-module.exports = WebSocketServer;
-
-/**
- * Entirely private apis,
- * which may or may not be bound to a sepcific WebSocket instance.
- */
-
-function handleHybiUpgrade(req, socket, upgradeHead, cb) {
- // handle premature socket errors
- var errorHandler = function() {
- try { socket.destroy(); } catch (e) {}
- }
- socket.on('error', errorHandler);
-
- // verify key presence
- if (!req.headers['sec-websocket-key']) {
- abortConnection(socket, 400, 'Bad Request');
- return;
- }
-
- // verify version
- var version = parseInt(req.headers['sec-websocket-version']);
- if ([8, 13].indexOf(version) === -1) {
- abortConnection(socket, 400, 'Bad Request');
- return;
- }
-
- // verify protocol
- var protocols = req.headers['sec-websocket-protocol'];
-
- // verify client
- var origin = version < 13 ?
- req.headers['sec-websocket-origin'] :
- req.headers['origin'];
-
- // handle extensions offer
- var extensionsOffer = Extensions.parse(req.headers['sec-websocket-extensions']);
-
- // handler to call when the connection sequence completes
- var self = this;
- var completeHybiUpgrade2 = function(protocol) {
-
- // calc key
- var key = req.headers['sec-websocket-key'];
- var shasum = crypto.createHash('sha1');
- shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
- key = shasum.digest('base64');
-
- var headers = [
- 'HTTP/1.1 101 Switching Protocols'
- , 'Upgrade: websocket'
- , 'Connection: Upgrade'
- , 'Sec-WebSocket-Accept: ' + key
- ];
-
- if (typeof protocol != 'undefined') {
- headers.push('Sec-WebSocket-Protocol: ' + protocol);
- }
-
- var extensions = {};
- try {
- extensions = acceptExtensions.call(self, extensionsOffer);
- } catch (err) {
- abortConnection(socket, 400, 'Bad Request');
- return;
- }
-
- if (Object.keys(extensions).length) {
- var serverExtensions = {};
- Object.keys(extensions).forEach(function(token) {
- serverExtensions[token] = [extensions[token].params]
- });
- headers.push('Sec-WebSocket-Extensions: ' + Extensions.format(serverExtensions));
- }
-
- // allows external modification/inspection of handshake headers
- self.emit('headers', headers);
-
- socket.setTimeout(0);
- socket.setNoDelay(true);
- try {
- socket.write(headers.concat('', '').join('\r\n'));
- }
- catch (e) {
- // if the upgrade write fails, shut the connection down hard
- try { socket.destroy(); } catch (e) {}
- return;
- }
-
- var client = new WebSocket([req, socket, upgradeHead], {
- protocolVersion: version,
- protocol: protocol,
- extensions: extensions,
- maxPayload: self.options.maxPayload
- });
-
- if (self.options.clientTracking) {
- self.clients.push(client);
- client.on('close', function() {
- var index = self.clients.indexOf(client);
- if (index != -1) {
- self.clients.splice(index, 1);
- }
- });
- }
-
- // signal upgrade complete
- socket.removeListener('error', errorHandler);
- cb(client);
- }
-
- // optionally call external protocol selection handler before
- // calling completeHybiUpgrade2
- var completeHybiUpgrade1 = function() {
- // choose from the sub-protocols
- if (typeof self.options.handleProtocols == 'function') {
- var protList = (protocols || "").split(/, */);
- var callbackCalled = false;
- var res = self.options.handleProtocols(protList, function(result, protocol) {
- callbackCalled = true;
- if (!result) abortConnection(socket, 401, 'Unauthorized');
- else completeHybiUpgrade2(protocol);
- });
- if (!callbackCalled) {
- // the handleProtocols handler never called our callback
- abortConnection(socket, 501, 'Could not process protocols');
- }
- return;
- } else {
- if (typeof protocols !== 'undefined') {
- completeHybiUpgrade2(protocols.split(/, */)[0]);
- }
- else {
- completeHybiUpgrade2();
- }
- }
- }
-
- // optionally call external client verification handler
- if (typeof this.options.verifyClient == 'function') {
- var info = {
- origin: origin,
- secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined',
- req: req
- };
- if (this.options.verifyClient.length == 2) {
- this.options.verifyClient(info, function(result, code, name) {
- if (typeof code === 'undefined') code = 401;
- if (typeof name === 'undefined') name = http.STATUS_CODES[code];
-
- if (!result) abortConnection(socket, code, name);
- else completeHybiUpgrade1();
- });
- return;
- }
- else if (!this.options.verifyClient(info)) {
- abortConnection(socket, 401, 'Unauthorized');
- return;
- }
- }
-
- completeHybiUpgrade1();
-}
-
-function handleHixieUpgrade(req, socket, upgradeHead, cb) {
- // handle premature socket errors
- var errorHandler = function() {
- try { socket.destroy(); } catch (e) {}
- }
- socket.on('error', errorHandler);
-
- // bail if options prevent hixie
- if (this.options.disableHixie) {
- abortConnection(socket, 401, 'Hixie support disabled');
- return;
- }
-
- // verify key presence
- if (!req.headers['sec-websocket-key2']) {
- abortConnection(socket, 400, 'Bad Request');
- return;
- }
-
- var origin = req.headers['origin']
- , self = this;
-
- // setup handshake completion to run after client has been verified
- var onClientVerified = function() {
- var wshost;
- if (!req.headers['x-forwarded-host'])
- wshost = req.headers.host;
- else
- wshost = req.headers['x-forwarded-host'];
- var location = ((req.headers['x-forwarded-proto'] === 'https' || socket.encrypted) ? 'wss' : 'ws') + '://' + wshost + req.url
- , protocol = req.headers['sec-websocket-protocol'];
-
- // build the response header and return a Buffer
- var buildResponseHeader = function() {
- var headers = [
- 'HTTP/1.1 101 Switching Protocols'
- , 'Upgrade: WebSocket'
- , 'Connection: Upgrade'
- , 'Sec-WebSocket-Location: ' + location
- ];
- if (typeof protocol != 'undefined') headers.push('Sec-WebSocket-Protocol: ' + protocol);
- if (typeof origin != 'undefined') headers.push('Sec-WebSocket-Origin: ' + origin);
-
- return new Buffer(headers.concat('', '').join('\r\n'));
- };
-
- // send handshake response before receiving the nonce
- var handshakeResponse = function() {
-
- socket.setTimeout(0);
- socket.setNoDelay(true);
-
- var headerBuffer = buildResponseHeader();
-
- try {
- socket.write(headerBuffer, 'binary', function(err) {
- // remove listener if there was an error
- if (err) socket.removeListener('data', handler);
- return;
- });
- } catch (e) {
- try { socket.destroy(); } catch (e) {}
- return;
- };
- };
-
- // handshake completion code to run once nonce has been successfully retrieved
- var completeHandshake = function(nonce, rest, headerBuffer) {
- // calculate key
- var k1 = req.headers['sec-websocket-key1']
- , k2 = req.headers['sec-websocket-key2']
- , md5 = crypto.createHash('md5');
-
- [k1, k2].forEach(function (k) {
- var n = parseInt(k.replace(/[^\d]/g, ''))
- , spaces = k.replace(/[^ ]/g, '').length;
- if (spaces === 0 || n % spaces !== 0){
- abortConnection(socket, 400, 'Bad Request');
- return;
- }
- n /= spaces;
- md5.update(String.fromCharCode(
- n >> 24 & 0xFF,
- n >> 16 & 0xFF,
- n >> 8 & 0xFF,
- n & 0xFF));
- });
- md5.update(nonce.toString('binary'));
-
- socket.setTimeout(0);
- socket.setNoDelay(true);
-
- try {
- var hashBuffer = new Buffer(md5.digest('binary'), 'binary');
- var handshakeBuffer = new Buffer(headerBuffer.length + hashBuffer.length);
- headerBuffer.copy(handshakeBuffer, 0);
- hashBuffer.copy(handshakeBuffer, headerBuffer.length);
-
- // do a single write, which - upon success - causes a new client websocket to be setup
- socket.write(handshakeBuffer, 'binary', function(err) {
- if (err) return; // do not create client if an error happens
- var client = new WebSocket([req, socket, rest], {
- protocolVersion: 'hixie-76',
- protocol: protocol
- });
- if (self.options.clientTracking) {
- self.clients.push(client);
- client.on('close', function() {
- var index = self.clients.indexOf(client);
- if (index != -1) {
- self.clients.splice(index, 1);
- }
- });
- }
-
- // signal upgrade complete
- socket.removeListener('error', errorHandler);
- cb(client);
- });
- }
- catch (e) {
- try { socket.destroy(); } catch (e) {}
- return;
- }
- }
-
- // retrieve nonce
- var nonceLength = 8;
- if (upgradeHead && upgradeHead.length >= nonceLength) {
- var nonce = upgradeHead.slice(0, nonceLength);
- var rest = upgradeHead.length > nonceLength ? upgradeHead.slice(nonceLength) : null;
- completeHandshake.call(self, nonce, rest, buildResponseHeader());
- }
- else {
- // nonce not present in upgradeHead
- var nonce = new Buffer(nonceLength);
- upgradeHead.copy(nonce, 0);
- var received = upgradeHead.length;
- var rest = null;
- var handler = function (data) {
- var toRead = Math.min(data.length, nonceLength - received);
- if (toRead === 0) return;
- data.copy(nonce, received, 0, toRead);
- received += toRead;
- if (received == nonceLength) {
- socket.removeListener('data', handler);
- if (toRead < data.length) rest = data.slice(toRead);
-
- // complete the handshake but send empty buffer for headers since they have already been sent
- completeHandshake.call(self, nonce, rest, new Buffer(0));
- }
- }
-
- // handle additional data as we receive it
- socket.on('data', handler);
-
- // send header response before we have the nonce to fix haproxy buffering
- handshakeResponse();
- }
- }
-
- // verify client
- if (typeof this.options.verifyClient == 'function') {
- var info = {
- origin: origin,
- secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined',
- req: req
- };
- if (this.options.verifyClient.length == 2) {
- var self = this;
- this.options.verifyClient(info, function(result, code, name) {
- if (typeof code === 'undefined') code = 401;
- if (typeof name === 'undefined') name = http.STATUS_CODES[code];
-
- if (!result) abortConnection(socket, code, name);
- else onClientVerified.apply(self);
- });
- return;
- }
- else if (!this.options.verifyClient(info)) {
- abortConnection(socket, 401, 'Unauthorized');
- return;
- }
- }
-
- // no client verification required
- onClientVerified();
-}
-
-function acceptExtensions(offer) {
- var extensions = {};
- var options = this.options.perMessageDeflate;
- var maxPayload = this.options.maxPayload;
- if (options && offer[PerMessageDeflate.extensionName]) {
- var perMessageDeflate = new PerMessageDeflate(options !== true ? options : {}, true, maxPayload);
- perMessageDeflate.accept(offer[PerMessageDeflate.extensionName]);
- extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
- }
- return extensions;
-}
-
-function abortConnection(socket, code, name) {
- try {
- var response = [
- 'HTTP/1.1 ' + code + ' ' + name,
- 'Content-type: text/html'
- ];
- socket.write(response.concat('', '').join('\r\n'));
- }
- catch (e) { /* ignore errors - we've aborted this connection */ }
- finally {
- // ensure that an early aborted connection is shut down completely
- try { socket.destroy(); } catch (e) {}
- }
-}
diff --git a/node_modules/ws/package.json b/node_modules/ws/package.json
deleted file mode 100644
index 1a7b69893..000000000
--- a/node_modules/ws/package.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "author": "Einar Otto Stangvik <einaros@gmail.com> (http://2x.io)",
- "name": "ws",
- "description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455",
- "version": "1.1.1",
- "license": "MIT",
- "main": "index.js",
- "keywords": [
- "Hixie",
- "HyBi",
- "Push",
- "RFC-6455",
- "WebSocket",
- "WebSockets",
- "real-time"
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/websockets/ws.git"
- },
- "scripts": {
- "test": "make test"
- },
- "dependencies": {
- "options": ">=0.0.5",
- "ultron": "1.0.x"
- },
- "devDependencies": {
- "ansi": "0.3.x",
- "benchmark": "0.3.x",
- "bufferutil": "1.2.x",
- "expect.js": "0.3.x",
- "istanbul": "^0.4.1",
- "mocha": "2.3.x",
- "should": "8.0.x",
- "tinycolor": "0.0.x",
- "utf-8-validate": "1.2.x"
- },
- "gypfile": true
-}