[Pkg-javascript-commits] [node-ws] 01/04: Imported Upstream version 0.8.0+ds1.e6ddaae4

Ximin Luo infinity0 at debian.org
Mon Aug 31 02:53:33 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository node-ws.

commit 719dc4d0ce2778234cad67d9f7f31d03e2e22b4c
Author: Ximin Luo <infinity0 at debian.org>
Date:   Mon Aug 31 01:54:40 2015 +0200

    Imported Upstream version 0.8.0+ds1.e6ddaae4
---
 .travis.yml                    |  21 ++++---
 README.md                      |  31 +++++++++
 bin/wscat                      |   9 ++-
 binding.gyp                    |   6 +-
 dependency.versions            |   6 +-
 doc/ws.md                      |   3 +-
 lib/BufferPool.js              |   4 ++
 lib/PerMessageDeflate.js       |   5 +-
 lib/Receiver.hixie.js          |   4 ++
 lib/Receiver.js                |   4 ++
 lib/Sender.hixie.js            |   4 ++
 lib/Sender.js                  |   7 +++
 lib/WebSocket.js               |  80 ++++++++++++++---------
 lib/WebSocketServer.js         |  13 +++-
 package.json                   |   6 +-
 src/bufferutil.cc              |  51 ++++++++-------
 src/validation.cc              |  26 ++++----
 test/BufferPool.test.js        |  13 +++-
 test/PerMessageDeflate.test.js |  12 ++++
 test/Receiver.hixie.test.js    |  12 ++++
 test/Receiver.test.js          |  13 +++-
 test/Sender.hixie.test.js      |  12 ++++
 test/Sender.test.js            |  12 ++++
 test/WebSocket.test.js         | 140 ++++++++++++++++++++++++++++++++++++++++-
 test/WebSocketServer.test.js   |  26 ++++++++
 25 files changed, 426 insertions(+), 94 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index dc97102..820f8c9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,21 +1,28 @@
 language: node_js
+sudo: false
 npm_args: --ws:native
 node_js:
+  - "iojs-v3"
+  - "iojs-v2"
+  - "iojs-v1"
   - "0.12"
   - "0.11"
   - "0.10"
   - "0.9"
   - "0.8"
-  - "iojs-v1.1"
-  - "iojs-v1.0"
-  - "iojs-v2.0"
+addons:
+  apt:
+    sources:
+      - ubuntu-toolchain-r-test
+    packages:
+      - gcc-4.9
+      - g++-4.9
 before_install:
-  - "npm install -g npm at 2.1.18"
+  - export CC="gcc-4.9" CXX="g++-4.9"
+  - "if [[ $(node --version) == v0.8.* ]]; then npm install -g npm at 2.1.18; fi"
 matrix:
   fast_finish: true
   allow_failures:
     - node_js: "0.11"
     - node_js: "0.9"
-    - node_js: "iojs-v1.1"
-    - node_js: "iojs-v1.0"
-    - node_js: "iojs-v2.0"
+    - node_js: "0.8"
diff --git a/README.md b/README.md
index fc8e106..9647d08 100644
--- a/README.md
+++ b/README.md
@@ -74,6 +74,37 @@ wss.on('connection', function connection(ws) {
 });
 ```
 
+### 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
diff --git a/bin/wscat b/bin/wscat
index 5ec8046..79eb17d 100755
--- a/bin/wscat
+++ b/bin/wscat
@@ -103,7 +103,7 @@ var version = require('../package.json').version;
 
 program
   .version(version)
-  .usage('[options] <url>')
+  .usage('[options] (--listen <port> | --connect <url>)')
   .option('-l, --listen <port>', 'listen on port')
   .option('-c, --connect <url>', 'connect to a websocket server')
   .option('-p, --protocol <version>', 'optional protocol version')
@@ -189,8 +189,13 @@ if (program.listen && program.connect) {
     headers.Authorization = 'Basic '+ new Buffer(program.auth).toString('base64');
   }
 
+  var connectUrl = program.connect;
+  if (!connectUrl.match(/\w+:\/\/.*$/i)) {
+    connectUrl = 'ws://' + connectUrl;
+  }
+
   options.headers = headers;
-  var ws = new WebSocket(program.connect, options);
+  var ws = new WebSocket(connectUrl, options);
 
   ws.on('open', function open() {
     wsConsole.print('connected (press CTRL+C to quit)', Console.Colors.Green);
diff --git a/binding.gyp b/binding.gyp
index 9b08e4e..d7bce71 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -1,8 +1,10 @@
-{'targets': [{'cflags': ['-O3'],
+{'targets': [{'cflags': ['-O2'],
+              'cflags!': ['-O3'],
               'include_dirs': ['<!(node -e "require(\'nan\')")'],
               'sources': ['src/bufferutil.cc'],
               'target_name': 'bufferutil'},
-             {'cflags': ['-O3'],
+             {'cflags': ['-O2'],
+              'cflags!': ['-O3'],
               'include_dirs': ['<!(node -e "require(\'nan\')")'],
               'sources': ['src/validation.cc'],
               'target_name': 'validation'}]}
diff --git a/dependency.versions b/dependency.versions
index d6a7d47..b6b758d 100644
--- a/dependency.versions
+++ b/dependency.versions
@@ -1,5 +1,5 @@
-bufferutil=1.1.0
-utf-8-validate=1.1.0
+bufferutil=1.2.1
+utf-8-validate=1.2.1
 ultron=1.0.2
 options.js=0.20.gff53d0a
-wscat=0.3.g6d2391a
+wscat=1.0.1
diff --git a/doc/ws.md b/doc/ws.md
index 93dd54a..8f23d51 100644
--- a/doc/ws.md
+++ b/doc/ws.md
@@ -31,7 +31,7 @@ Either `port` or `server` must be provided, otherwise you might enable
 * `info` Object:
   * `origin` String: The value in the Origin header indicated by the client.
   * `req` http.ClientRequest: The client HTTP GET request.
-  * `secure` Boolean: `true` if `req.connection.authorized` or `req.connection.encypted` is set.
+  * `secure` Boolean: `true` if `req.connection.authorized` or `req.connection.encrypted` is set.
 * `cb` Function: A callback that must be called by the user upon inspection of the `info` fields. Arguments in this callback are:
   * `result` Boolean: Whether the user accepts or not the handshake.
   * `code` Number: If `result` is `false` this field determines the HTTP error status code to be sent to the client.
@@ -119,6 +119,7 @@ This class represents a WebSocket connection. It is an `EventEmitter`.
   * `ciphers` String
   * `rejectUnauthorized` Boolean
   * `perMessageDeflate` Boolean|Object
+  * `localAddress` String
 
 Instantiating with an `address` creates a new WebSocket client object. If `address` is an Array (request, socket, rest), it is instantiated as a Server client (e.g. called from the `ws.Server`).
 
diff --git a/lib/BufferPool.js b/lib/BufferPool.js
index faf8637..8ee5990 100644
--- a/lib/BufferPool.js
+++ b/lib/BufferPool.js
@@ -7,6 +7,10 @@
 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;
diff --git a/lib/PerMessageDeflate.js b/lib/PerMessageDeflate.js
index f735977..b1fd743 100644
--- a/lib/PerMessageDeflate.js
+++ b/lib/PerMessageDeflate.js
@@ -12,6 +12,10 @@ PerMessageDeflate.extensionName = 'permessage-deflate';
  */
 
 function PerMessageDeflate(options, isServer) {
+  if (this instanceof PerMessageDeflate === false) {
+    throw new TypeError("Classes can't be function-called");
+  }
+
   this._options = options || {};
   this._isServer = !!isServer;
   this._inflate = null;
@@ -286,4 +290,3 @@ PerMessageDeflate.prototype.compress = function (data, fin, callback) {
 };
 
 module.exports = PerMessageDeflate;
-
diff --git a/lib/Receiver.hixie.js b/lib/Receiver.hixie.js
index a8e41c4..66bc561 100644
--- a/lib/Receiver.hixie.js
+++ b/lib/Receiver.hixie.js
@@ -20,6 +20,10 @@ var BINARYLENGTH = 2
  */
 
 function Receiver () {
+  if (this instanceof Receiver === false) {
+    throw new TypeError("Classes can't be function-called");
+  }
+
   this.state = EMPTY;
   this.buffers = [];
   this.messageEnd = -1;
diff --git a/lib/Receiver.js b/lib/Receiver.js
index 1ae1c4e..ff4590d 100644
--- a/lib/Receiver.js
+++ b/lib/Receiver.js
@@ -16,6 +16,10 @@ var util = require('util')
  */
 
 function Receiver (extensions) {
+  if (this instanceof Receiver === false) {
+    throw new TypeError("Classes can't be function-called");
+  }
+
   // memory pool for fragmented messages
   var fragmentedPoolPrevUsed = -1;
   this.fragmentedBufferPool = new BufferPool(1024, function(db, length) {
diff --git a/lib/Sender.hixie.js b/lib/Sender.hixie.js
index fd2fd25..b87d9dd 100644
--- a/lib/Sender.hixie.js
+++ b/lib/Sender.hixie.js
@@ -13,6 +13,10 @@ var events = require('events')
  */
 
 function Sender(socket) {
+  if (this instanceof Sender === false) {
+    throw new TypeError("Classes can't be function-called");
+  }
+
   events.EventEmitter.call(this);
 
   this.socket = socket;
diff --git a/lib/Sender.js b/lib/Sender.js
index f346748..2f8f7c4 100644
--- a/lib/Sender.js
+++ b/lib/Sender.js
@@ -16,6 +16,10 @@ var events = require('events')
  */
 
 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;
@@ -267,6 +271,9 @@ Sender.prototype.flush = function() {
 
 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);
diff --git a/lib/WebSocket.js b/lib/WebSocket.js
index dc885d5..3d9c3f1 100644
--- a/lib/WebSocket.js
+++ b/lib/WebSocket.js
@@ -44,6 +44,10 @@ var closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cl
  * @api public
  */
 function WebSocket(address, protocols, options) {
+  if (this instanceof WebSocket === false) {
+    throw new TypeError("Classes can't be function-called");
+  }
+
   EventEmitter.call(this);
 
   if (protocols && !Array.isArray(protocols) && 'object' === typeof protocols) {
@@ -411,7 +415,7 @@ WebSocket.prototype.addEventListener = function(method, listener) {
   var target = this;
 
   function onMessage (data, flags) {
-    listener.call(target, new MessageEvent(data, flags.binary ? 'Binary' : 'Text', target));
+    listener.call(target, new MessageEvent(data, !!flags.binary, target));
   }
 
   function onClose (code, message) {
@@ -419,6 +423,7 @@ WebSocket.prototype.addEventListener = function(method, listener) {
   }
 
   function onError (event) {
+    event.type = 'error';
     event.target = target;
     listener.call(target, event);
   }
@@ -455,6 +460,7 @@ WebSocket.prototype.addEventListener = function(method, listener) {
 };
 
 module.exports = WebSocket;
+module.exports.buildHostHeader = buildHostHeader
 
 /**
  * W3C MessageEvent
@@ -463,10 +469,11 @@ module.exports = WebSocket;
  * @constructor
  * @api private
  */
-function MessageEvent(dataArg, typeArg, target) {
+function MessageEvent(dataArg, isBinary, target) {
+  this.type = 'message';
   this.data = dataArg;
-  this.type = typeArg;
   this.target = target;
+  this.binary = isBinary; // non-standard.
 }
 
 /**
@@ -477,6 +484,7 @@ function MessageEvent(dataArg, typeArg, target) {
  * @api private
  */
 function CloseEvent(code, reason, target) {
+  this.type = 'close';
   this.wasClean = (typeof code === 'undefined' || code === 1000);
   this.code = code;
   this.reason = reason;
@@ -491,9 +499,22 @@ function CloseEvent(code, reason, target) {
  * @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.
@@ -539,7 +560,8 @@ function initAsClient(address, protocols, options) {
     ca: null,
     ciphers: null,
     rejectUnauthorized: null,
-    perMessageDeflate: true
+    perMessageDeflate: true,
+    localAddress: null
   }).merge(options);
 
   if (options.value.protocolVersion !== 8 && options.value.protocolVersion !== 13) {
@@ -577,14 +599,7 @@ function initAsClient(address, protocols, options) {
 
   var agent = options.value.agent;
 
-  var headerHost = serverUrl.hostname;
-  // Append port number to Host header, only if specified in the url
-  // and non-default
-  if (serverUrl.port) {
-    if ((isSecure && (port !== 443)) || (!isSecure && (port !== 80))){
-      headerHost = headerHost + ':' + port;
-    }
-  }
+  var headerHost = buildHostHeader(isSecure, serverUrl.hostname, port)
 
   var requestOptions = {
     port: port,
@@ -654,6 +669,11 @@ function initAsClient(address, protocols, options) {
   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;
@@ -743,13 +763,15 @@ function initAsClient(address, protocols, options) {
 }
 
 function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) {
-  var ultron = this._ultron = new Ultron(socket);
-  this._socket = socket;
+  var ultron = this._ultron = new Ultron(socket)
+    , called = false
+    , self = this;
 
   socket.setTimeout(0);
   socket.setNoDelay(true);
-  var self = this;
+
   this._receiver = new ReceiverClass(this.extensions);
+  this._socket = socket;
 
   // socket cleanup handlers
   ultron.on('end', cleanupWebsocketResources.bind(this));
@@ -758,30 +780,27 @@ function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) {
 
   // ensure that the upgradeHead is added to the receiver
   function firstHandler(data) {
-    if (self.readyState !== WebSocket.OPEN && self.readyState !== WebSocket.CLOSING) return;
+    if (called || self.readyState === WebSocket.CLOSED) return;
+
+    called = true;
+    socket.removeListener('data', firstHandler);
+    ultron.on('data', realHandler);
 
     if (upgradeHead && upgradeHead.length > 0) {
-      self.bytesReceived += upgradeHead.length;
-      var head = upgradeHead;
+      realHandler(upgradeHead);
       upgradeHead = null;
-      self._receiver.add(head);
     }
 
-    dataHandler = realHandler;
-
-    if (data) {
-      self.bytesReceived += data.length;
-      self._receiver.add(data);
-    }
+    if (data) realHandler(data);
   }
 
   // subsequent packets are pushed straight to the receiver
   function realHandler(data) {
-    if (data) self.bytesReceived += data.length;
+    self.bytesReceived += data.length;
     self._receiver.add(data);
   }
 
-  var dataHandler = firstHandler;
+  ultron.on('data', firstHandler);
 
   // if data was passed along with the http upgrade,
   // this will schedule a push of that on to the receiver.
@@ -841,8 +860,6 @@ function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) {
 
   this.readyState = WebSocket.OPEN;
   this.emit('open');
-
-  ultron.on('data', dataHandler);
 }
 
 function startQueue(instance) {
@@ -901,6 +918,11 @@ function cleanupWebsocketResources(error) {
   this._closeTimer = null;
 
   if (emitClose) {
+    // If the connection was closed abnormally (with an error), 
+    // then the close code must default to 1006.
+    if (error) {
+      this._closeCode = 1006;
+    }
     this.emit('close', this._closeCode || 1000, this._closeMessage || '');
   }
 
diff --git a/lib/WebSocketServer.js b/lib/WebSocketServer.js
index a2f3a61..b5f82db 100644
--- a/lib/WebSocketServer.js
+++ b/lib/WebSocketServer.js
@@ -20,6 +20,10 @@ var util = require('util')
  */
 
 function WebSocketServer(options, callback) {
+  if (this instanceof WebSocketServer === false) {
+    throw new TypeError("Classes can't be function-called");
+  }
+
   events.EventEmitter.call(this);
 
   options = new Options({
@@ -43,9 +47,14 @@ function WebSocketServer(options, callback) {
 
   if (options.isDefinedAndNonNull('port')) {
     this._server = http.createServer(function (req, res) {
-      res.writeHead(200, {'Content-Type': 'text/plain'});
-      res.end('Not implemented');
+      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(); };
   }
diff --git a/package.json b/package.json
index 240a23b..67ffb1a 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Einar Otto Stangvik <einaros at 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": "0.7.2",
+  "version": "0.8.0",
   "license": "MIT",
   "keywords": [
     "Hixie",
@@ -25,8 +25,8 @@
     "ultron": "1.0.x"
   },
   "optionalDependencies": {
-    "bufferutil": "1.1.x",
-    "utf-8-validate": "1.1.x"
+    "bufferutil": "1.2.x",
+    "utf-8-validate": "1.2.x"
   },
   "devDependencies": {
     "ansi": "0.3.x",
diff --git a/src/bufferutil.cc b/src/bufferutil.cc
index bd6f368..1e826b3 100644
--- a/src/bufferutil.cc
+++ b/src/bufferutil.cc
@@ -24,31 +24,31 @@ public:
 
   static void Initialize(v8::Handle<v8::Object> target)
   {
-    NanScope();
-    Local<FunctionTemplate> t = NanNew<FunctionTemplate>(New);
+    Nan::HandleScope scope;
+    Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
     t->InstanceTemplate()->SetInternalFieldCount(1);
-    NODE_SET_METHOD(t, "unmask", BufferUtil::Unmask);
-    NODE_SET_METHOD(t, "mask", BufferUtil::Mask);
-    NODE_SET_METHOD(t, "merge", BufferUtil::Merge);
-    target->Set(NanNew<String>("BufferUtil"), t->GetFunction());
+    Nan::SetMethod(t, "unmask", BufferUtil::Unmask);
+    Nan::SetMethod(t, "mask", BufferUtil::Mask);
+    Nan::SetMethod(t, "merge", BufferUtil::Merge);
+    Nan::Set(target, Nan::New<String>("BufferUtil").ToLocalChecked(), t->GetFunction());
   }
 
 protected:
 
   static NAN_METHOD(New)
   {
-    NanScope();
+    Nan::HandleScope scope;
     BufferUtil* bufferUtil = new BufferUtil();
-    bufferUtil->Wrap(args.This());
-    NanReturnValue(args.This());
+    bufferUtil->Wrap(info.This());
+    info.GetReturnValue().Set(info.This());
   }
 
   static NAN_METHOD(Merge)
   {
-    NanScope();
-    Local<Object> bufferObj = args[0]->ToObject();
+    Nan::HandleScope scope;
+    Local<Object> bufferObj = info[0]->ToObject();
     char* buffer = Buffer::Data(bufferObj);
-    Local<Array> array = Local<Array>::Cast(args[1]);
+    Local<Array> array = Local<Array>::Cast(info[1]);
     unsigned int arrayLength = array->Length();
     size_t offset = 0;
     unsigned int i;
@@ -58,15 +58,15 @@ protected:
       memcpy(buffer + offset, Buffer::Data(src), length);
       offset += length;
     }
-    NanReturnValue(NanTrue());
+    info.GetReturnValue().Set(Nan::True());
   }
 
   static NAN_METHOD(Unmask)
   {
-    NanScope();
-    Local<Object> buffer_obj = args[0]->ToObject();
+    Nan::HandleScope scope;
+    Local<Object> buffer_obj = info[0]->ToObject();
     size_t length = Buffer::Length(buffer_obj);
-    Local<Object> mask_obj = args[1]->ToObject();
+    Local<Object> mask_obj = info[1]->ToObject();
     unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
     unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
     size_t len32 = length / 4;
@@ -79,18 +79,18 @@ protected:
       case 1: *((unsigned char*)from  ) = *((unsigned char*)from  ) ^ ((unsigned char*)mask)[0];
       case 0:;
     }
-    NanReturnValue(NanTrue());
+    info.GetReturnValue().Set(Nan::True());
   }
 
   static NAN_METHOD(Mask)
   {
-    NanScope();
-    Local<Object> buffer_obj = args[0]->ToObject();
-    Local<Object> mask_obj = args[1]->ToObject();
+    Nan::HandleScope scope;
+    Local<Object> buffer_obj = info[0]->ToObject();
+    Local<Object> mask_obj = info[1]->ToObject();
     unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
-    Local<Object> output_obj = args[2]->ToObject();
-    unsigned int dataOffset = args[3]->Int32Value();
-    unsigned int length = args[4]->Int32Value();
+    Local<Object> output_obj = info[2]->ToObject();
+    unsigned int dataOffset = info[3]->Int32Value();
+    unsigned int length = info[4]->Int32Value();
     unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset);
     unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
     unsigned int len32 = length / 4;
@@ -104,7 +104,7 @@ protected:
       case 1: *((unsigned char*)to  ) = *((unsigned char*)from  ) ^ *((unsigned char*)mask);
       case 0:;
     }
-    NanReturnValue(NanTrue());
+    info.GetReturnValue().Set(Nan::True());
   }
 };
 
@@ -113,9 +113,8 @@ extern "C"
 #endif
 void init (Handle<Object> target)
 {
-  NanScope();
+  Nan::HandleScope scope;
   BufferUtil::Initialize(target);
 }
 
 NODE_MODULE(bufferutil, init)
-
diff --git a/src/validation.cc b/src/validation.cc
index 264edcd..305ebaf 100644
--- a/src/validation.cc
+++ b/src/validation.cc
@@ -106,33 +106,33 @@ public:
 
   static void Initialize(v8::Handle<v8::Object> target)
   {
-    NanScope();
-    Local<FunctionTemplate> t = NanNew<FunctionTemplate>(New);
+    Nan::HandleScope scope;
+    Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
     t->InstanceTemplate()->SetInternalFieldCount(1);
-    NODE_SET_METHOD(t, "isValidUTF8", Validation::IsValidUTF8);
-    target->Set(NanNew<String>("Validation"), t->GetFunction());
+    Nan::SetMethod(t, "isValidUTF8", Validation::IsValidUTF8);
+    Nan::Set(target, Nan::New<String>("Validation").ToLocalChecked(), t->GetFunction());
   }
 
 protected:
 
   static NAN_METHOD(New)
   {
-    NanScope();
+    Nan::HandleScope scope;
     Validation* validation = new Validation();
-    validation->Wrap(args.This());
-    NanReturnValue(args.This());
+    validation->Wrap(info.This());
+    info.GetReturnValue().Set(info.This());
   }
 
   static NAN_METHOD(IsValidUTF8)
   {
-    NanScope();
-    if (!Buffer::HasInstance(args[0])) {
-      return NanThrowTypeError("First argument needs to be a buffer");
+    Nan::HandleScope scope;
+    if (!Buffer::HasInstance(info[0])) {
+      return Nan::ThrowTypeError("First argument needs to be a buffer");
     }
-    Local<Object> buffer_obj = args[0]->ToObject();
+    Local<Object> buffer_obj = info[0]->ToObject();
     char *buffer_data = Buffer::Data(buffer_obj);
     size_t buffer_length = Buffer::Length(buffer_obj);
-    NanReturnValue(is_valid_utf8(buffer_length, buffer_data) == 1 ? NanTrue() : NanFalse());
+    info.GetReturnValue().Set(is_valid_utf8(buffer_length, buffer_data) == 1 ? Nan::True() : Nan::False());
   }
 };
 #if !NODE_VERSION_AT_LEAST(0,10,0)
@@ -140,7 +140,7 @@ extern "C"
 #endif
 void init (Handle<Object> target)
 {
-  NanScope();
+  Nan::HandleScope scope;
   Validation::Initialize(target);
 }
 
diff --git a/test/BufferPool.test.js b/test/BufferPool.test.js
index 1ee7ff0..ccd087e 100644
--- a/test/BufferPool.test.js
+++ b/test/BufferPool.test.js
@@ -1,12 +1,21 @@
 var BufferPool = require('../lib/BufferPool');
 require('should');
 
-describe('BufferPool', function() {  
+describe('BufferPool', function() {
   describe('#ctor', function() {
     it('allocates pool', function() {
       var db = new BufferPool(1000);
       db.size.should.eql(1000);
     });
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var db = BufferPool(1000);
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
   });
   describe('#get', function() {
     it('grows the pool if necessary', function() {
@@ -39,7 +48,7 @@ describe('BufferPool', function() {
       var db = new BufferPool(1000);
       var buf = db.get(1000);
       db.size.should.eql(1000);
-      buf.length.should.eql(1000);      
+      buf.length.should.eql(1000);
     });
   });
   describe('#reset', function() {
diff --git a/test/PerMessageDeflate.test.js b/test/PerMessageDeflate.test.js
index 81eceec..6b70ccb 100644
--- a/test/PerMessageDeflate.test.js
+++ b/test/PerMessageDeflate.test.js
@@ -3,6 +3,18 @@ var Extensions = require('../lib/Extensions');
 require('should');
 
 describe('PerMessageDeflate', function() {
+  describe('#ctor', function() {
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var perMessageDeflate = PerMessageDeflate();
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
+  });
+
   describe('#offer', function() {
     it('should create default params', function() {
       var perMessageDeflate = new PerMessageDeflate();
diff --git a/test/Receiver.hixie.test.js b/test/Receiver.hixie.test.js
index 043d3bc..8646d76 100644
--- a/test/Receiver.hixie.test.js
+++ b/test/Receiver.hixie.test.js
@@ -4,6 +4,18 @@ var assert = require('assert')
 require('./hybi-common');
 
 describe('Receiver', function() {
+  describe('#ctor', function() {
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var p = Receiver();
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
+  });
+
   it('can parse text message', function() {
     var p = new Receiver();
     var packet = '00 48 65 6c 6c 6f ff';
diff --git a/test/Receiver.test.js b/test/Receiver.test.js
index 2c34d1e..30fd3b8 100644
--- a/test/Receiver.test.js
+++ b/test/Receiver.test.js
@@ -5,6 +5,18 @@ require('should');
 require('./hybi-common');
 
 describe('Receiver', function() {
+  describe('#ctor', function() {
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var p = Receiver();
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
+  });
+
   it('can parse unmasked text message', function() {
     var p = new Receiver();
     var packet = '81 05 48 65 6c 6c 6f';
@@ -312,4 +324,3 @@ describe('Receiver', function() {
     });
   });
 });
-
diff --git a/test/Sender.hixie.test.js b/test/Sender.hixie.test.js
index 783f892..3bf3e64 100644
--- a/test/Sender.hixie.test.js
+++ b/test/Sender.hixie.test.js
@@ -4,6 +4,18 @@ require('should');
 require('./hybi-common');
 
 describe('Sender', function() {
+  describe('#ctor', function() {
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var sender = Sender({ write: function() {} });
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
+  });
+
   describe('#send', function() {
     it('frames and sends a text message', function(done) {
       var message = 'Hello world';
diff --git a/test/Sender.test.js b/test/Sender.test.js
index d70a111..8b5ccc0 100644
--- a/test/Sender.test.js
+++ b/test/Sender.test.js
@@ -3,6 +3,18 @@ var Sender = require('../lib/Sender')
 require('should');
 
 describe('Sender', function() {
+  describe('#ctor', function() {
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var sender = Sender({ write: function() {} });
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
+  });
+
   describe('#frameAndSend', function() {
     it('does not modify a masked binary buffer', function() {
       var sender = new Sender({ write: function() {} });
diff --git a/test/WebSocket.test.js b/test/WebSocket.test.js
index a105086..0c5ea0d 100644
--- a/test/WebSocket.test.js
+++ b/test/WebSocket.test.js
@@ -5,6 +5,7 @@ var assert = require('assert')
   , WebSocket = require('../')
   , WebSocketServer = require('../').Server
   , fs = require('fs')
+  , os = require('os')
   , server = require('./testserver')
   , crypto = require('crypto');
 
@@ -39,6 +40,15 @@ describe('WebSocket', function() {
         done();
       }
     });
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var ws = WebSocket('ws://localhost:' + port);
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
   });
 
   describe('options', function() {
@@ -65,6 +75,47 @@ describe('WebSocket', function() {
         var ws = new WebSocket('ws://localhost:' + port, [], { agent: agent });
       });
     });
+
+    it('should accept the localAddress option', function(done) {
+      // explore existing interfaces
+      var devs = os.networkInterfaces()
+        , localAddresses = []
+        , j, ifc, dev, devname;
+      for ( devname in devs ) {
+        dev = devs[devname];
+        for ( j=0;j<dev.length;j++ ) {
+          ifc = dev[j];
+          if ( !ifc.internal && ifc.family === 'IPv4' ) {
+            localAddresses.push(ifc.address);
+          }
+        }
+      }
+      var wss = new WebSocketServer({port: ++port}, function() {
+        var ws = new WebSocket('ws://localhost:' + port, { localAddress: localAddresses[0] });
+        ws.on('open', function () {
+          done();
+        });
+      });
+    });
+
+    it('should accept the localAddress option whether it was wrong interface', function(done) {
+      if ( process.platform === 'linux' && process.version.match(/^v0\.([0-9]\.|10)/) ) {
+        return done();
+      }
+      var wss = new WebSocketServer({port: ++port}, function() {
+        try {
+          var ws = new WebSocket('ws://localhost:' + port, { localAddress: '123.456.789.428' });
+          ws.on('error', function (error) {
+            error.code.should.eql('EADDRNOTAVAIL');
+            done();
+          });
+        }
+        catch(e) {
+          e.should.match(/localAddress must be a valid IP/);
+          done();
+        }
+      });
+    });
   });
 
   describe('properties', function() {
@@ -706,7 +757,7 @@ describe('WebSocket', function() {
           ws.send(array.buffer);
         });
         ws.onmessage = function (event) {
-          assert.ok(event.type = 'Binary');
+          assert.ok(event.binary);
           assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(event.data))));
           ws.terminate();
           srv.close();
@@ -723,7 +774,7 @@ describe('WebSocket', function() {
           ws.send(buf);
         });
         ws.onmessage = function (event) {
-          assert.ok(event.type = 'Binary');
+          assert.ok(event.binary);
           assert.ok(areArraysEqual(event.data, buf));
           ws.terminate();
           srv.close();
@@ -1603,6 +1654,32 @@ describe('WebSocket', function() {
         client.send('hi')
       });
     });
+
+    it('should have type set on Events', function(done) {
+      var wss = new WebSocketServer({port: ++port}, function() {
+        var ws = new WebSocket('ws://localhost:' + port);
+        ws.addEventListener('open', function(openEvent) {
+          assert.equal('open', openEvent.type);
+        });
+        ws.addEventListener('message', function(messageEvent) {
+          assert.equal('message', messageEvent.type);
+          wss.close();
+        });
+        ws.addEventListener('close', function(closeEvent) {
+          assert.equal('close', closeEvent.type);
+          ws.emit('error', new Error('forced'));
+        });
+        ws.addEventListener('error', function(errorEvent) {
+          assert.equal(errorEvent.message, 'forced');
+          assert.equal('error', errorEvent.type);
+          ws.terminate();
+          done();
+        });
+      });
+      wss.on('connection', function(client) {
+        client.send('hi')
+      });
+    });
   });
 
   describe('ssl', function() {
@@ -1822,6 +1899,21 @@ describe('WebSocket', function() {
         var ws = new WebSocket('ws://localhost:' + port, options);
       });
     });
+
+    it('excludes default ports from host header', function(done) {
+      // can't create a server listening on ports 80 or 443
+      // so we need to expose the method that does this
+      var buildHostHeader = WebSocket.buildHostHeader
+      var host = buildHostHeader(false, 'localhost', 80)
+      assert.equal('localhost', host);
+      host = buildHostHeader(false, 'localhost', 88)
+      assert.equal('localhost:88', host);
+      host = buildHostHeader(true, 'localhost', 443)
+      assert.equal('localhost', host);
+      host = buildHostHeader(true, 'localhost', 8443)
+      assert.equal('localhost:8443', host);
+      done()
+    });
   });
 
   describe('permessage-deflate', function() {
@@ -1902,6 +1994,50 @@ describe('WebSocket', function() {
       });
     });
 
+    it('can send and receive a typed array', function(done) {
+      var array = new Float32Array(5);
+      for (var i = 0; i < array.length; i++) array[i] = i / 2;
+      var wss = new WebSocketServer({port: ++port, perMessageDeflate: true}, function() {
+        var ws = new WebSocket('ws://localhost:' + port, {perMessageDeflate: true});
+        ws.on('open', function() {
+          ws.send(array, {compress: true});
+        });
+        ws.on('message', function(message, flags) {
+          assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message))));
+          ws.terminate();
+          wss.close();
+          done();
+        });
+      });
+      wss.on('connection', function(ws) {
+        ws.on('message', function(message, flags) {
+          ws.send(message, {compress: true});
+        });
+      });
+    });
+
+    it('can send and receive ArrayBuffer', function(done) {
+      var array = new Float32Array(5);
+      for (var i = 0; i < array.length; i++) array[i] = i / 2;
+      var wss = new WebSocketServer({port: ++port, perMessageDeflate: true}, function() {
+        var ws = new WebSocket('ws://localhost:' + port, {perMessageDeflate: true});
+        ws.on('open', function() {
+          ws.send(array.buffer, {compress: true});
+        });
+        ws.on('message', function(message, flags) {
+          assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message))));
+          ws.terminate();
+          wss.close();
+          done();
+        });
+      });
+      wss.on('connection', function(ws) {
+        ws.on('message', function(message, flags) {
+          ws.send(message, {compress: true});
+        });
+      });
+    });
+
     it('with binary stream will send fragmented data', function(done) {
       var wss = new WebSocketServer({port: ++port, perMessageDeflate: true}, function() {
         var ws = new WebSocket('ws://localhost:' + port, {perMessageDeflate: true});
diff --git a/test/WebSocketServer.test.js b/test/WebSocketServer.test.js
index 7227a18..a300db7 100644
--- a/test/WebSocketServer.test.js
+++ b/test/WebSocketServer.test.js
@@ -26,6 +26,16 @@ function areArraysEqual(x, y) {
 
 describe('WebSocketServer', function() {
   describe('#ctor', function() {
+    it('throws TypeError when called without new', function(done) {
+      try {
+        var ws = WebSocketServer({noServer: true});
+      }
+      catch (e) {
+        e.should.be.instanceof(TypeError);
+        done();
+      }
+    });
+
     it('throws an error if no option object is passed', function() {
       var gotException = false;
       try {
@@ -92,6 +102,22 @@ describe('WebSocketServer', function() {
       });
     });
 
+    it('426s for non-Upgrade requests', function (done) {
+      var wss = new WebSocketServer({ port: ++port }, function () {
+        http.get('http://localhost:' + port, function (res) {
+          var body = '';
+
+          res.statusCode.should.equal(426);
+          res.on('data', function (chunk) { body += chunk; });
+          res.on('end', function () {
+            body.should.equal(http.STATUS_CODES[426]);
+            wss.close();
+            done();
+          });
+        });
+      });
+    });
+
     // Don't test this on Windows. It throws errors for obvious reasons.
     if(!/^win/i.test(process.platform)) {
       it('uses a precreated http server listening on unix socket', function (done) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-ws.git



More information about the Pkg-javascript-commits mailing list