arnaucube
arnaucube/raspberryGPIOhtmlserverPublic Self-hosted repository
raspberryGPIOhtmlserver/node_modules/ws/test/WebSocket.test.js
node_modules/ws/test/WebSocket.test.jsRaw
   1var assert = require('assert')
   2  , https = require('https')
   3  , http = require('http')
   4  , should = require('should')
   5  , WebSocket = require('../')
   6  , WebSocketServer = require('../').Server
   7  , fs = require('fs')
   8  , server = require('./testserver')
   9  , crypto = require('crypto');
  10
  11var port = 20000;
  12
  13function getArrayBuffer(buf) {
  14  var l = buf.length;
  15  var arrayBuf = new ArrayBuffer(l);
  16  var uint8View = new Uint8Array(arrayBuf);
  17  for (var i = 0; i < l; i++) {
  18    uint8View[i] = buf[i];
  19  }
  20  return uint8View.buffer;
  21}
  22
  23
  24function areArraysEqual(x, y) {
  25  if (x.length != y.length) return false;
  26  for (var i = 0, l = x.length; i < l; ++i) {
  27    if (x[i] !== y[i]) return false;
  28  }
  29  return true;
  30}
  31
  32describe('WebSocket', function() {
  33  describe('#ctor', function() {
  34    it('throws exception for invalid url', function(done) {
  35      try {
  36        var ws = new WebSocket('echo.websocket.org');
  37      }
  38      catch (e) {
  39        done();
  40      }
  41    });
  42  });
  43
  44  describe('options', function() {
  45    it('should accept an `agent` option', function(done) {
  46      var wss = new WebSocketServer({port: ++port}, function() {
  47        var agent = {
  48          addRequest: function() {
  49            wss.close();
  50            done();
  51          }
  52        };
  53        var ws = new WebSocket('ws://localhost:' + port, { agent: agent });
  54      });
  55    });
  56    // GH-227
  57    it('should accept the `options` object as the 3rd argument', function(done) {
  58      var wss = new WebSocketServer({port: ++port}, function() {
  59        var agent = {
  60          addRequest: function() {
  61            wss.close();
  62            done();
  63          }
  64        };
  65        var ws = new WebSocket('ws://localhost:' + port, [], { agent: agent });
  66      });
  67    });
  68  });
  69
  70  describe('properties', function() {
  71    it('#bytesReceived exposes number of bytes received', function(done) {
  72      var wss = new WebSocketServer({port: ++port}, function() {
  73        var ws = new WebSocket('ws://localhost:' + port);
  74        ws.on('message', function() {
  75          ws.bytesReceived.should.eql(8);
  76          wss.close();
  77          done();
  78        });
  79      });
  80      wss.on('connection', function(ws) {
  81        ws.send('foobar');
  82      });
  83    });
  84
  85    it('#url exposes the server url', function(done) {
  86      server.createServer(++port, function(srv) {
  87        var url = 'ws://localhost:' + port;
  88        var ws = new WebSocket(url);
  89        assert.equal(url, ws.url);
  90        ws.terminate();
  91        ws.on('close', function() {
  92          srv.close();
  93          done();
  94        });
  95      });
  96    });
  97
  98    it('#protocolVersion exposes the protocol version', function(done) {
  99      server.createServer(++port, function(srv) {
 100        var url = 'ws://localhost:' + port;
 101        var ws = new WebSocket(url);
 102        assert.equal(13, ws.protocolVersion);
 103        ws.terminate();
 104        ws.on('close', function() {
 105          srv.close();
 106          done();
 107        });
 108      });
 109    });
 110
 111    describe('#bufferedAmount', function() {
 112      it('defaults to zero', function(done) {
 113        server.createServer(++port, function(srv) {
 114          var url = 'ws://localhost:' + port;
 115          var ws = new WebSocket(url);
 116          assert.equal(0, ws.bufferedAmount);
 117          ws.terminate();
 118          ws.on('close', function() {
 119            srv.close();
 120            done();
 121          });
 122        });
 123      });
 124
 125      it('defaults to zero upon "open"', function(done) {
 126        server.createServer(++port, function(srv) {
 127          var url = 'ws://localhost:' + port;
 128          var ws = new WebSocket(url);
 129          ws.onopen = function() {
 130            assert.equal(0, ws.bufferedAmount);
 131            ws.terminate();
 132            ws.on('close', function() {
 133              srv.close();
 134              done();
 135            });
 136          };
 137        });
 138      });
 139
 140      it('stress kernel write buffer', function(done) {
 141        var wss = new WebSocketServer({port: ++port}, function() {
 142          var ws = new WebSocket('ws://localhost:' + port);
 143        });
 144        wss.on('connection', function(ws) {
 145          while (true) {
 146            if (ws.bufferedAmount > 0) break;
 147            ws.send((new Array(10000)).join('hello'));
 148          }
 149          ws.terminate();
 150          ws.on('close', function() {
 151            wss.close();
 152            done();
 153          });
 154        });
 155      });
 156    });
 157
 158    describe('Custom headers', function() {
 159      it('request has an authorization header', function (done) {
 160        var auth = 'test:testpass';
 161        var srv = http.createServer(function (req, res) {});
 162        var wss = new WebSocketServer({server: srv});
 163        srv.listen(++port);
 164        var ws = new WebSocket('ws://' + auth + '@localhost:' + port);
 165        srv.on('upgrade', function (req, socket, head) {
 166          assert(req.headers.authorization, 'auth header exists');
 167          assert.equal(req.headers.authorization, 'Basic ' + new Buffer(auth).toString('base64'));
 168          ws.terminate();
 169          ws.on('close', function () {
 170            srv.close();
 171            wss.close();
 172            done();
 173          });
 174        });
 175      });
 176
 177      it('accepts custom headers', function (done) {
 178        var srv = http.createServer(function (req, res) {});
 179        var wss = new WebSocketServer({server: srv});
 180        srv.listen(++port);
 181
 182        var ws = new WebSocket('ws://localhost:' + port, {
 183          headers: {
 184            'Cookie': 'foo=bar'
 185          }
 186        });
 187
 188        srv.on('upgrade', function (req, socket, head) {
 189          assert(req.headers.cookie, 'auth header exists');
 190          assert.equal(req.headers.cookie, 'foo=bar');
 191
 192          ws.terminate();
 193          ws.on('close', function () {
 194            srv.close();
 195            wss.close();
 196            done();
 197          });
 198        });
 199      });
 200    });
 201
 202    describe('#readyState', function() {
 203      it('defaults to connecting', function(done) {
 204        server.createServer(++port, function(srv) {
 205          var ws = new WebSocket('ws://localhost:' + port);
 206          assert.equal(WebSocket.CONNECTING, ws.readyState);
 207          ws.terminate();
 208          ws.on('close', function() {
 209            srv.close();
 210            done();
 211          });
 212        });
 213      });
 214
 215      it('set to open once connection is established', function(done) {
 216        server.createServer(++port, function(srv) {
 217          var ws = new WebSocket('ws://localhost:' + port);
 218          ws.on('open', function() {
 219            assert.equal(WebSocket.OPEN, ws.readyState);
 220            srv.close();
 221            done();
 222          });
 223        });
 224      });
 225
 226      it('set to closed once connection is closed', function(done) {
 227        server.createServer(++port, function(srv) {
 228          var ws = new WebSocket('ws://localhost:' + port);
 229          ws.close(1001);
 230          ws.on('close', function() {
 231            assert.equal(WebSocket.CLOSED, ws.readyState);
 232            srv.close();
 233            done();
 234          });
 235        });
 236      });
 237
 238      it('set to closed once connection is terminated', function(done) {
 239        server.createServer(++port, function(srv) {
 240          var ws = new WebSocket('ws://localhost:' + port);
 241          ws.terminate();
 242          ws.on('close', function() {
 243            assert.equal(WebSocket.CLOSED, ws.readyState);
 244            srv.close();
 245            done();
 246          });
 247        });
 248      });
 249    });
 250
 251    /*
 252     * Ready state constants
 253     */
 254
 255    var readyStates = {
 256      CONNECTING: 0,
 257      OPEN: 1,
 258      CLOSING: 2,
 259      CLOSED: 3
 260    };
 261
 262    /*
 263     * Ready state constant tests
 264     */
 265
 266    Object.keys(readyStates).forEach(function(state) {
 267      describe('.' + state, function() {
 268        it('is enumerable property of class', function() {
 269          var propertyDescripter = Object.getOwnPropertyDescriptor(WebSocket, state)
 270          assert.equal(readyStates[state], propertyDescripter.value);
 271          assert.equal(true, propertyDescripter.enumerable);
 272        });
 273      });
 274    });
 275
 276    server.createServer(++port, function(srv) {
 277      var ws = new WebSocket('ws://localhost:' + port);
 278      Object.keys(readyStates).forEach(function(state) {
 279        describe('.' + state, function() {
 280          it('is property of instance', function() {
 281            assert.equal(readyStates[state], ws[state]);
 282          });
 283        });
 284      });
 285    });
 286  });
 287
 288  describe('events', function() {
 289    it('emits a ping event', function(done) {
 290      var wss = new WebSocketServer({port: ++port});
 291      wss.on('connection', function(client) {
 292        client.ping();
 293      });
 294      var ws = new WebSocket('ws://localhost:' + port);
 295      ws.on('ping', function() {
 296        ws.terminate();
 297        wss.close();
 298        done();
 299      });
 300    });
 301
 302    it('emits a pong event', function(done) {
 303      var wss = new WebSocketServer({port: ++port});
 304      wss.on('connection', function(client) {
 305        client.pong();
 306      });
 307      var ws = new WebSocket('ws://localhost:' + port);
 308      ws.on('pong', function() {
 309        ws.terminate();
 310        wss.close();
 311        done();
 312      });
 313    });
 314  });
 315
 316  describe('connection establishing', function() {
 317    it('can disconnect before connection is established', function(done) {
 318      server.createServer(++port, function(srv) {
 319        var ws = new WebSocket('ws://localhost:' + port);
 320        ws.terminate();
 321        ws.on('open', function() {
 322          assert.fail('connect shouldnt be raised here');
 323        });
 324        ws.on('close', function() {
 325          srv.close();
 326          done();
 327        });
 328      });
 329    });
 330
 331    it('can close before connection is established', function(done) {
 332      server.createServer(++port, function(srv) {
 333        var ws = new WebSocket('ws://localhost:' + port);
 334        ws.close(1001);
 335        ws.on('open', function() {
 336          assert.fail('connect shouldnt be raised here');
 337        });
 338        ws.on('close', function() {
 339          srv.close();
 340          done();
 341        });
 342      });
 343    });
 344
 345    it('invalid server key is denied', function(done) {
 346      server.createServer(++port, server.handlers.invalidKey, function(srv) {
 347        var ws = new WebSocket('ws://localhost:' + port);
 348        ws.on('error', function() {
 349          srv.close();
 350          done();
 351        });
 352      });
 353    });
 354
 355    it('close event is raised when server closes connection', function(done) {
 356      server.createServer(++port, server.handlers.closeAfterConnect, function(srv) {
 357        var ws = new WebSocket('ws://localhost:' + port);
 358        ws.on('close', function() {
 359          srv.close();
 360          done();
 361        });
 362      });
 363    });
 364
 365    it('error is emitted if server aborts connection', function(done) {
 366      server.createServer(++port, server.handlers.return401, function(srv) {
 367        var ws = new WebSocket('ws://localhost:' + port);
 368        ws.on('open', function() {
 369          assert.fail('connect shouldnt be raised here');
 370        });
 371        ws.on('error', function() {
 372          srv.close();
 373          done();
 374        });
 375      });
 376    });
 377  });
 378
 379  describe('#pause and #resume', function() {
 380    it('pauses the underlying stream', function(done) {
 381      // this test is sort-of racecondition'y, since an unlikely slow connection
 382      // to localhost can cause the test to succeed even when the stream pausing
 383      // isn't working as intended. that is an extremely unlikely scenario, though
 384      // and an acceptable risk for the test.
 385      var client;
 386      var serverClient;
 387      var openCount = 0;
 388      function onOpen() {
 389        if (++openCount == 2) {
 390          var paused = true;
 391          serverClient.on('message', function() {
 392            paused.should.not.be.ok;
 393            wss.close();
 394            done();
 395          });
 396          serverClient.pause();
 397          setTimeout(function() {
 398            paused = false;
 399            serverClient.resume();
 400          }, 200);
 401          client.send('foo');
 402        }
 403      }
 404      var wss = new WebSocketServer({port: ++port}, function() {
 405        var ws = new WebSocket('ws://localhost:' + port);
 406        serverClient = ws;
 407        serverClient.on('open', onOpen);
 408      });
 409      wss.on('connection', function(ws) {
 410        client = ws;
 411        onOpen();
 412      });
 413    });
 414  });
 415
 416  describe('#ping', function() {
 417    it('before connect should fail', function(done) {
 418      server.createServer(++port, function(srv) {
 419        var ws = new WebSocket('ws://localhost:' + port);
 420        ws.on('error', function() {});
 421        try {
 422          ws.ping();
 423        }
 424        catch (e) {
 425          srv.close();
 426          ws.terminate();
 427          done();
 428        }
 429      });
 430    });
 431
 432    it('before connect can silently fail', function(done) {
 433      server.createServer(++port, function(srv) {
 434        var ws = new WebSocket('ws://localhost:' + port);
 435        ws.on('error', function() {});
 436        ws.ping('', {}, true);
 437        srv.close();
 438        ws.terminate();
 439        done();
 440      });
 441    });
 442
 443    it('without message is successfully transmitted to the server', function(done) {
 444      server.createServer(++port, function(srv) {
 445        var ws = new WebSocket('ws://localhost:' + port);
 446        ws.on('open', function() {
 447          ws.ping();
 448        });
 449        srv.on('ping', function(message) {
 450          srv.close();
 451          ws.terminate();
 452          done();
 453        });
 454      });
 455    });
 456
 457    it('with message is successfully transmitted to the server', function(done) {
 458      server.createServer(++port, function(srv) {
 459        var ws = new WebSocket('ws://localhost:' + port);
 460        ws.on('open', function() {
 461          ws.ping('hi');
 462        });
 463        srv.on('ping', function(message) {
 464          assert.equal('hi', message);
 465          srv.close();
 466          ws.terminate();
 467          done();
 468        });
 469      });
 470    });
 471
 472    it('with encoded message is successfully transmitted to the server', function(done) {
 473      server.createServer(++port, function(srv) {
 474        var ws = new WebSocket('ws://localhost:' + port);
 475        ws.on('open', function() {
 476          ws.ping('hi', {mask: true});
 477        });
 478        srv.on('ping', function(message, flags) {
 479          assert.ok(flags.masked);
 480          assert.equal('hi', message);
 481          srv.close();
 482          ws.terminate();
 483          done();
 484        });
 485      });
 486    });
 487  });
 488
 489  describe('#pong', function() {
 490    it('before connect should fail', function(done) {
 491      server.createServer(++port, function(srv) {
 492        var ws = new WebSocket('ws://localhost:' + port);
 493        ws.on('error', function() {});
 494        try {
 495          ws.pong();
 496        }
 497        catch (e) {
 498          srv.close();
 499          ws.terminate();
 500          done();
 501        }
 502      });
 503    });
 504
 505    it('before connect can silently fail', function(done) {
 506      server.createServer(++port, function(srv) {
 507        var ws = new WebSocket('ws://localhost:' + port);
 508        ws.on('error', function() {});
 509        ws.pong('', {}, true);
 510        srv.close();
 511        ws.terminate();
 512        done();
 513      });
 514    });
 515
 516    it('without message is successfully transmitted to the server', function(done) {
 517      server.createServer(++port, function(srv) {
 518        var ws = new WebSocket('ws://localhost:' + port);
 519        ws.on('open', function() {
 520          ws.pong();
 521        });
 522        srv.on('pong', function(message) {
 523          srv.close();
 524          ws.terminate();
 525          done();
 526        });
 527      });
 528    });
 529
 530    it('with message is successfully transmitted to the server', function(done) {
 531      server.createServer(++port, function(srv) {
 532        var ws = new WebSocket('ws://localhost:' + port);
 533        ws.on('open', function() {
 534          ws.pong('hi');
 535        });
 536        srv.on('pong', function(message) {
 537          assert.equal('hi', message);
 538          srv.close();
 539          ws.terminate();
 540          done();
 541        });
 542      });
 543    });
 544
 545    it('with encoded message is successfully transmitted to the server', function(done) {
 546      server.createServer(++port, function(srv) {
 547        var ws = new WebSocket('ws://localhost:' + port);
 548        ws.on('open', function() {
 549          ws.pong('hi', {mask: true});
 550        });
 551        srv.on('pong', function(message, flags) {
 552          assert.ok(flags.masked);
 553          assert.equal('hi', message);
 554          srv.close();
 555          ws.terminate();
 556          done();
 557        });
 558      });
 559    });
 560  });
 561
 562  describe('#send', function() {
 563    it('very long binary data can be sent and received (with echoing server)', function(done) {
 564      server.createServer(++port, function(srv) {
 565        var ws = new WebSocket('ws://localhost:' + port);
 566        var array = new Float32Array(5 * 1024 * 1024);
 567        for (var i = 0; i < array.length; ++i) array[i] = i / 5;
 568        ws.on('open', function() {
 569          ws.send(array, {binary: true});
 570        });
 571        ws.on('message', function(message, flags) {
 572          assert.ok(flags.binary);
 573          assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message))));
 574          ws.terminate();
 575          srv.close();
 576          done();
 577        });
 578      });
 579    });
 580
 581    it('can send and receive text data', function(done) {
 582      server.createServer(++port, function(srv) {
 583        var ws = new WebSocket('ws://localhost:' + port);
 584        ws.on('open', function() {
 585          ws.send('hi');
 586        });
 587        ws.on('message', function(message, flags) {
 588          assert.equal('hi', message);
 589          ws.terminate();
 590          srv.close();
 591          done();
 592        });
 593      });
 594    });
 595
 596    it('send and receive binary data as an array', function(done) {
 597      server.createServer(++port, function(srv) {
 598        var ws = new WebSocket('ws://localhost:' + port);
 599        var array = new Float32Array(6);
 600        for (var i = 0; i < array.length; ++i) array[i] = i / 2;
 601        var partial = array.subarray(2, 5);
 602        ws.on('open', function() {
 603          ws.send(partial, {binary: true});
 604        });
 605        ws.on('message', function(message, flags) {
 606          assert.ok(flags.binary);
 607          assert.ok(areArraysEqual(partial, new Float32Array(getArrayBuffer(message))));
 608          ws.terminate();
 609          srv.close();
 610          done();
 611        });
 612      });
 613    });
 614
 615    it('binary data can be sent and received as buffer', function(done) {
 616      server.createServer(++port, function(srv) {
 617        var ws = new WebSocket('ws://localhost:' + port);
 618        var buf = new Buffer('foobar');
 619        ws.on('open', function() {
 620          ws.send(buf, {binary: true});
 621        });
 622        ws.on('message', function(message, flags) {
 623          assert.ok(flags.binary);
 624          assert.ok(areArraysEqual(buf, message));
 625          ws.terminate();
 626          srv.close();
 627          done();
 628        });
 629      });
 630    });
 631
 632    it('ArrayBuffer is auto-detected without binary flag', function(done) {
 633      server.createServer(++port, function(srv) {
 634        var ws = new WebSocket('ws://localhost:' + port);
 635        var array = new Float32Array(5);
 636        for (var i = 0; i < array.length; ++i) array[i] = i / 2;
 637        ws.on('open', function() {
 638          ws.send(array.buffer);
 639        });
 640        ws.onmessage = function (event) {
 641          assert.ok(event.type = 'Binary');
 642          assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(event.data))));
 643          ws.terminate();
 644          srv.close();
 645          done();
 646        };
 647      });
 648    });
 649
 650    it('Buffer is auto-detected without binary flag', function(done) {
 651      server.createServer(++port, function(srv) {
 652        var ws = new WebSocket('ws://localhost:' + port);
 653        var buf = new Buffer('foobar');
 654        ws.on('open', function() {
 655          ws.send(buf);
 656        });
 657        ws.onmessage = function (event) {
 658          assert.ok(event.type = 'Binary');
 659          assert.ok(areArraysEqual(event.data, buf));
 660          ws.terminate();
 661          srv.close();
 662          done();
 663        };
 664      });
 665    });
 666
 667    it('before connect should fail', function(done) {
 668      server.createServer(++port, function(srv) {
 669        var ws = new WebSocket('ws://localhost:' + port);
 670        ws.on('error', function() {});
 671        try {
 672          ws.send('hi');
 673        }
 674        catch (e) {
 675          ws.terminate();
 676          srv.close();
 677          done();
 678        }
 679      });
 680    });
 681
 682    it('before connect should pass error through callback, if present', function(done) {
 683      server.createServer(++port, function(srv) {
 684        var ws = new WebSocket('ws://localhost:' + port);
 685        ws.on('error', function() {});
 686        ws.send('hi', function(error) {
 687          assert.ok(error instanceof Error);
 688          ws.terminate();
 689          srv.close();
 690          done();
 691        });
 692      });
 693    });
 694
 695    it('without data should be successful', function(done) {
 696      server.createServer(++port, function(srv) {
 697        var ws = new WebSocket('ws://localhost:' + port);
 698        ws.on('open', function() {
 699          ws.send();
 700        });
 701        srv.on('message', function(message, flags) {
 702          assert.equal('', message);
 703          srv.close();
 704          ws.terminate();
 705          done();
 706        });
 707      });
 708    });
 709
 710    it('calls optional callback when flushed', function(done) {
 711      server.createServer(++port, function(srv) {
 712        var ws = new WebSocket('ws://localhost:' + port);
 713        ws.on('open', function() {
 714          ws.send('hi', function() {
 715            srv.close();
 716            ws.terminate();
 717            done();
 718          });
 719        });
 720      });
 721    });
 722
 723    it('with unencoded message is successfully transmitted to the server', function(done) {
 724      server.createServer(++port, function(srv) {
 725        var ws = new WebSocket('ws://localhost:' + port);
 726        ws.on('open', function() {
 727          ws.send('hi');
 728        });
 729        srv.on('message', function(message, flags) {
 730          assert.equal('hi', message);
 731          srv.close();
 732          ws.terminate();
 733          done();
 734        });
 735      });
 736    });
 737
 738    it('with encoded message is successfully transmitted to the server', function(done) {
 739      server.createServer(++port, function(srv) {
 740        var ws = new WebSocket('ws://localhost:' + port);
 741        ws.on('open', function() {
 742          ws.send('hi', {mask: true});
 743        });
 744        srv.on('message', function(message, flags) {
 745          assert.ok(flags.masked);
 746          assert.equal('hi', message);
 747          srv.close();
 748          ws.terminate();
 749          done();
 750        });
 751      });
 752    });
 753
 754    it('with unencoded binary message is successfully transmitted to the server', function(done) {
 755      server.createServer(++port, function(srv) {
 756        var ws = new WebSocket('ws://localhost:' + port);
 757        var array = new Float32Array(5);
 758        for (var i = 0; i < array.length; ++i) array[i] = i / 2;
 759        ws.on('open', function() {
 760          ws.send(array, {binary: true});
 761        });
 762        srv.on('message', function(message, flags) {
 763          assert.ok(flags.binary);
 764          assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message))));
 765          srv.close();
 766          ws.terminate();
 767          done();
 768        });
 769      });
 770    });
 771
 772    it('with encoded binary message is successfully transmitted to the server', function(done) {
 773      server.createServer(++port, function(srv) {
 774        var ws = new WebSocket('ws://localhost:' + port);
 775        var array = new Float32Array(5);
 776        for (var i = 0; i < array.length; ++i) array[i] = i / 2;
 777        ws.on('open', function() {
 778          ws.send(array, {mask: true, binary: true});
 779        });
 780        srv.on('message', function(message, flags) {
 781          assert.ok(flags.binary);
 782          assert.ok(flags.masked);
 783          assert.ok(areArraysEqual(array, new Float32Array(getArrayBuffer(message))));
 784          srv.close();
 785          ws.terminate();
 786          done();
 787        });
 788      });
 789    });
 790
 791    it('with binary stream will send fragmented data', function(done) {
 792      server.createServer(++port, function(srv) {
 793        var ws = new WebSocket('ws://localhost:' + port);
 794        var callbackFired = false;
 795        ws.on('open', function() {
 796          var fileStream = fs.createReadStream('test/fixtures/textfile');
 797          fileStream.bufferSize = 100;
 798          ws.send(fileStream, {binary: true}, function(error) {
 799            assert.equal(null, error);
 800            callbackFired = true;
 801          });
 802        });
 803        srv.on('message', function(data, flags) {
 804          assert.ok(flags.binary);
 805          assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile'), data));
 806          ws.terminate();
 807        });
 808        ws.on('close', function() {
 809          assert.ok(callbackFired);
 810          srv.close();
 811          done();
 812        });
 813      });
 814    });
 815
 816    it('with text stream will send fragmented data', function(done) {
 817      server.createServer(++port, function(srv) {
 818        var ws = new WebSocket('ws://localhost:' + port);
 819        var callbackFired = false;
 820        ws.on('open', function() {
 821          var fileStream = fs.createReadStream('test/fixtures/textfile');
 822          fileStream.setEncoding('utf8');
 823          fileStream.bufferSize = 100;
 824          ws.send(fileStream, {binary: false}, function(error) {
 825            assert.equal(null, error);
 826            callbackFired = true;
 827          });
 828        });
 829        srv.on('message', function(data, flags) {
 830          assert.ok(!flags.binary);
 831          assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data));
 832          ws.terminate();
 833        });
 834        ws.on('close', function() {
 835          assert.ok(callbackFired);
 836          srv.close();
 837          done();
 838        });
 839      });
 840    });
 841
 842    it('will cause intermittent send to be delayed in order', function(done) {
 843      server.createServer(++port, function(srv) {
 844        var ws = new WebSocket('ws://localhost:' + port);
 845        ws.on('open', function() {
 846          var fileStream = fs.createReadStream('test/fixtures/textfile');
 847          fileStream.setEncoding('utf8');
 848          fileStream.bufferSize = 100;
 849          ws.send(fileStream);
 850          ws.send('foobar');
 851          ws.send('baz');
 852        });
 853        var receivedIndex = 0;
 854        srv.on('message', function(data, flags) {
 855          ++receivedIndex;
 856          if (receivedIndex == 1) {
 857            assert.ok(!flags.binary);
 858            assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data));
 859          }
 860          else if (receivedIndex == 2) {
 861            assert.ok(!flags.binary);
 862            assert.equal('foobar', data);
 863          }
 864          else {
 865            assert.ok(!flags.binary);
 866            assert.equal('baz', data);
 867            srv.close();
 868            ws.terminate();
 869            done();
 870          }
 871        });
 872      });
 873    });
 874
 875    it('will cause intermittent stream to be delayed in order', function(done) {
 876      server.createServer(++port, function(srv) {
 877        var ws = new WebSocket('ws://localhost:' + port);
 878        ws.on('open', function() {
 879          var fileStream = fs.createReadStream('test/fixtures/textfile');
 880          fileStream.setEncoding('utf8');
 881          fileStream.bufferSize = 100;
 882          ws.send(fileStream);
 883          var i = 0;
 884          ws.stream(function(error, send) {
 885            assert.ok(!error);
 886            if (++i == 1) send('foo');
 887            else send('bar', true);
 888          });
 889        });
 890        var receivedIndex = 0;
 891        srv.on('message', function(data, flags) {
 892          ++receivedIndex;
 893          if (receivedIndex == 1) {
 894            assert.ok(!flags.binary);
 895            assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data));
 896          }
 897          else if (receivedIndex == 2) {
 898            assert.ok(!flags.binary);
 899            assert.equal('foobar', data);
 900            srv.close();
 901            ws.terminate();
 902            done();
 903          }
 904        });
 905      });
 906    });
 907
 908    it('will cause intermittent ping to be delivered', function(done) {
 909      server.createServer(++port, function(srv) {
 910        var ws = new WebSocket('ws://localhost:' + port);
 911        ws.on('open', function() {
 912          var fileStream = fs.createReadStream('test/fixtures/textfile');
 913          fileStream.setEncoding('utf8');
 914          fileStream.bufferSize = 100;
 915          ws.send(fileStream);
 916          ws.ping('foobar');
 917        });
 918        var receivedIndex = 0;
 919        srv.on('message', function(data, flags) {
 920          assert.ok(!flags.binary);
 921          assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data));
 922          if (++receivedIndex == 2) {
 923            srv.close();
 924            ws.terminate();
 925            done();
 926          }
 927        });
 928        srv.on('ping', function(data) {
 929          assert.equal('foobar', data);
 930          if (++receivedIndex == 2) {
 931            srv.close();
 932            ws.terminate();
 933            done();
 934          }
 935        });
 936      });
 937    });
 938
 939    it('will cause intermittent pong to be delivered', function(done) {
 940      server.createServer(++port, function(srv) {
 941        var ws = new WebSocket('ws://localhost:' + port);
 942        ws.on('open', function() {
 943          var fileStream = fs.createReadStream('test/fixtures/textfile');
 944          fileStream.setEncoding('utf8');
 945          fileStream.bufferSize = 100;
 946          ws.send(fileStream);
 947          ws.pong('foobar');
 948        });
 949        var receivedIndex = 0;
 950        srv.on('message', function(data, flags) {
 951          assert.ok(!flags.binary);
 952          assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data));
 953          if (++receivedIndex == 2) {
 954            srv.close();
 955            ws.terminate();
 956            done();
 957          }
 958        });
 959        srv.on('pong', function(data) {
 960          assert.equal('foobar', data);
 961          if (++receivedIndex == 2) {
 962            srv.close();
 963            ws.terminate();
 964            done();
 965          }
 966        });
 967      });
 968    });
 969
 970    it('will cause intermittent close to be delivered', function(done) {
 971      server.createServer(++port, function(srv) {
 972        var ws = new WebSocket('ws://localhost:' + port);
 973        ws.on('open', function() {
 974          var fileStream = fs.createReadStream('test/fixtures/textfile');
 975          fileStream.setEncoding('utf8');
 976          fileStream.bufferSize = 100;
 977          ws.send(fileStream);
 978          ws.close(1000, 'foobar');
 979        });
 980        ws.on('close', function() {
 981          srv.close();
 982          ws.terminate();
 983          done();
 984        });
 985        ws.on('error', function() { /* That's quite alright -- a send was attempted after close */ });
 986        srv.on('message', function(data, flags) {
 987          assert.ok(!flags.binary);
 988          assert.ok(areArraysEqual(fs.readFileSync('test/fixtures/textfile', 'utf8'), data));
 989        });
 990        srv.on('close', function(code, data) {
 991          assert.equal(1000, code);
 992          assert.equal('foobar', data);
 993        });
 994      });
 995    });
 996  });
 997
 998  describe('#stream', function() {
 999    it('very long binary data can be streamed', function(done) {
1000      server.createServer(++port, function(srv) {
1001        var ws = new WebSocket('ws://localhost:' + port);
1002        var buffer = new Buffer(10 * 1024);
1003        for (var i = 0; i < buffer.length; ++i) buffer[i] = i % 0xff;
1004        ws.on('open', function() {
1005          var i = 0;
1006          var blockSize = 800;
1007          var bufLen = buffer.length;
1008          ws.stream({binary: true}, function(error, send) {
1009            assert.ok(!error);
1010            var start = i * blockSize;
1011            var toSend = Math.min(blockSize, bufLen - (i * blockSize));
1012            var end = start + toSend;
1013            var isFinal = toSend < blockSize;
1014            send(buffer.slice(start, end), isFinal);
1015            i += 1;
1016          });
1017        });
1018        srv.on('message', function(data, flags) {
1019          assert.ok(flags.binary);
1020          assert.ok(areArraysEqual(buffer, data));
1021          ws.terminate();
1022          srv.close();
1023          done();
1024        });
1025      });
1026    });
1027
1028    it('before connect should pass error through callback', function(done) {
1029      server.createServer(++port, function(srv) {
1030        var ws = new WebSocket('ws://localhost:' + port);
1031        ws.on('error', function() {});
1032        ws.stream(function(error) {
1033          assert.ok(error instanceof Error);
1034          ws.terminate();
1035          srv.close();
1036          done();
1037        });
1038      });
1039    });
1040
1041    it('without callback should fail', function(done) {
1042      server.createServer(++port, function(srv) {
1043        var ws = new WebSocket('ws://localhost:' + port);
1044        var payload = 'HelloWorld';
1045        ws.on('open', function() {
1046          try {
1047            ws.stream();
1048          }
1049          catch (e) {
1050            srv.close();
1051            ws.terminate();
1052            done();
1053          }
1054        });
1055      });
1056    });
1057
1058    it('will cause intermittent send to be delayed in order', function(done) {
1059      server.createServer(++port, function(srv) {
1060        var ws = new WebSocket('ws://localhost:' + port);
1061        var payload = 'HelloWorld';
1062        ws.on('open', function() {
1063          var i = 0;
1064          ws.stream(function(error, send) {
1065            assert.ok(!error);
1066            if (++i == 1) {
1067              send(payload.substr(0, 5));
1068              ws.send('foobar');
1069              ws.send('baz');
1070            }
1071            else {
1072              send(payload.substr(5, 5), true);
1073            }
1074          });
1075        });
1076        var receivedIndex = 0;
1077        srv.on('message', function(data, flags) {
1078          ++receivedIndex;
1079          if (receivedIndex == 1) {
1080            assert.ok(!flags.binary);
1081            assert.equal(payload, data);
1082          }
1083          else if (receivedIndex == 2) {
1084            assert.ok(!flags.binary);
1085            assert.equal('foobar', data);
1086          }
1087          else {
1088            assert.ok(!flags.binary);
1089            assert.equal('baz', data);
1090            srv.close();
1091            ws.terminate();
1092            done();
1093          }
1094        });
1095      });
1096    });
1097
1098    it('will cause intermittent stream to be delayed in order', function(done) {
1099      server.createServer(++port, function(srv) {
1100        var ws = new WebSocket('ws://localhost:' + port);
1101        var payload = 'HelloWorld';
1102        ws.on('open', function() {
1103          var i = 0;
1104          ws.stream(function(error, send) {
1105            assert.ok(!error);
1106            if (++i == 1) {
1107              send(payload.substr(0, 5));
1108              var i2 = 0;
1109              ws.stream(function(error, send) {
1110                assert.ok(!error);
1111                if (++i2 == 1) send('foo');
1112                else send('bar', true);
1113              });
1114              ws.send('baz');
1115            }
1116            else send(payload.substr(5, 5), true);
1117          });
1118        });
1119        var receivedIndex = 0;
1120        srv.on('message', function(data, flags) {
1121          ++receivedIndex;
1122          if (receivedIndex == 1) {
1123            assert.ok(!flags.binary);
1124            assert.equal(payload, data);
1125          }
1126          else if (receivedIndex == 2) {
1127            assert.ok(!flags.binary);
1128            assert.equal('foobar', data);
1129          }
1130          else if (receivedIndex == 3){
1131            assert.ok(!flags.binary);
1132            assert.equal('baz', data);
1133            setTimeout(function() {
1134              srv.close();
1135              ws.terminate();
1136              done();
1137            }, 1000);
1138          }
1139          else throw new Error('more messages than we actually sent just arrived');
1140        });
1141      });
1142    });
1143
1144    it('will cause intermittent ping to be delivered', function(done) {
1145      server.createServer(++port, function(srv) {
1146        var ws = new WebSocket('ws://localhost:' + port);
1147        var payload = 'HelloWorld';
1148        ws.on('open', function() {
1149          var i = 0;
1150          ws.stream(function(error, send) {
1151            assert.ok(!error);
1152            if (++i == 1) {
1153              send(payload.substr(0, 5));
1154              ws.ping('foobar');
1155            }
1156            else {
1157              send(payload.substr(5, 5), true);
1158            }
1159          });
1160        });
1161        var receivedIndex = 0;
1162        srv.on('message', function(data, flags) {
1163          assert.ok(!flags.binary);
1164          assert.equal(payload, data);
1165          if (++receivedIndex == 2) {
1166            srv.close();
1167            ws.terminate();
1168            done();
1169          }
1170        });
1171        srv.on('ping', function(data) {
1172          assert.equal('foobar', data);
1173          if (++receivedIndex == 2) {
1174            srv.close();
1175            ws.terminate();
1176            done();
1177          }
1178        });
1179      });
1180    });
1181
1182    it('will cause intermittent pong to be delivered', function(done) {
1183      server.createServer(++port, function(srv) {
1184        var ws = new WebSocket('ws://localhost:' + port);
1185        var payload = 'HelloWorld';
1186        ws.on('open', function() {
1187          var i = 0;
1188          ws.stream(function(error, send) {
1189            assert.ok(!error);
1190            if (++i == 1) {
1191              send(payload.substr(0, 5));
1192              ws.pong('foobar');
1193            }
1194            else {
1195              send(payload.substr(5, 5), true);
1196            }
1197          });
1198        });
1199        var receivedIndex = 0;
1200        srv.on('message', function(data, flags) {
1201          assert.ok(!flags.binary);
1202          assert.equal(payload, data);
1203          if (++receivedIndex == 2) {
1204            srv.close();
1205            ws.terminate();
1206            done();
1207          }
1208        });
1209        srv.on('pong', function(data) {
1210          assert.equal('foobar', data);
1211          if (++receivedIndex == 2) {
1212            srv.close();
1213            ws.terminate();
1214            done();
1215          }
1216        });
1217      });
1218    });
1219
1220    it('will cause intermittent close to be delivered', function(done) {
1221      server.createServer(++port, function(srv) {
1222        var ws = new WebSocket('ws://localhost:' + port);
1223        var payload = 'HelloWorld';
1224        var errorGiven = false;
1225        ws.on('open', function() {
1226          var i = 0;
1227          ws.stream(function(error, send) {
1228            if (++i == 1) {
1229              send(payload.substr(0, 5));
1230              ws.close(1000, 'foobar');
1231            }
1232            else if(i == 2) {
1233              send(payload.substr(5, 5), true);
1234            }
1235            else if (i == 3) {
1236              assert.ok(error);
1237              errorGiven = true;
1238            }
1239          });
1240        });
1241        ws.on('close', function() {
1242          assert.ok(errorGiven);
1243          srv.close();
1244          ws.terminate();
1245          done();
1246        });
1247        srv.on('message', function(data, flags) {
1248          assert.ok(!flags.binary);
1249          assert.equal(payload, data);
1250        });
1251        srv.on('close', function(code, data) {
1252          assert.equal(1000, code);
1253          assert.equal('foobar', data);
1254        });
1255      });
1256    });
1257  });
1258
1259  describe('#close', function() {
1260    it('will raise error callback, if any, if called during send stream', function(done) {
1261      server.createServer(++port, function(srv) {
1262        var ws = new WebSocket('ws://localhost:' + port);
1263        var errorGiven = false;
1264        ws.on('open', function() {
1265          var fileStream = fs.createReadStream('test/fixtures/textfile');
1266          fileStream.setEncoding('utf8');
1267          fileStream.bufferSize = 100;
1268          ws.send(fileStream, function(error) {
1269            errorGiven = error != null;
1270          });
1271          ws.close(1000, 'foobar');
1272        });
1273        ws.on('close', function() {
1274          setTimeout(function() {
1275            assert.ok(errorGiven);
1276            srv.close();
1277            ws.terminate();
1278            done();
1279          }, 1000);
1280        });
1281      });
1282    });
1283
1284    it('without invalid first argument throws exception', function(done) {
1285      server.createServer(++port, function(srv) {
1286        var ws = new WebSocket('ws://localhost:' + port);
1287        ws.on('open', function() {
1288          try {
1289            ws.close('error');
1290          }
1291          catch (e) {
1292            srv.close();
1293            ws.terminate();
1294            done();
1295          }
1296        });
1297      });
1298    });
1299
1300    it('without reserved error code 1004 throws exception', function(done) {
1301      server.createServer(++port, function(srv) {
1302        var ws = new WebSocket('ws://localhost:' + port);
1303        ws.on('open', function() {
1304          try {
1305            ws.close(1004);
1306          }
1307          catch (e) {
1308            srv.close();
1309            ws.terminate();
1310            done();
1311          }
1312        });
1313      });
1314    });
1315
1316    it('without message is successfully transmitted to the server', function(done) {
1317      server.createServer(++port, function(srv) {
1318        var ws = new WebSocket('ws://localhost:' + port);
1319        ws.on('open', function() {
1320          ws.close(1000);
1321        });
1322        srv.on('close', function(code, message, flags) {
1323          assert.equal('', message);
1324          srv.close();
1325          ws.terminate();
1326          done();
1327        });
1328      });
1329    });
1330
1331    it('with message is successfully transmitted to the server', function(done) {
1332      server.createServer(++port, function(srv) {
1333        var ws = new WebSocket('ws://localhost:' + port);
1334        ws.on('open', function() {
1335          ws.close(1000, 'some reason');
1336        });
1337        srv.on('close', function(code, message, flags) {
1338          assert.ok(flags.masked);
1339          assert.equal('some reason', message);
1340          srv.close();
1341          ws.terminate();
1342          done();
1343        });
1344      });
1345    });
1346
1347    it('with encoded message is successfully transmitted to the server', function(done) {
1348      server.createServer(++port, function(srv) {
1349        var ws = new WebSocket('ws://localhost:' + port);
1350        ws.on('open', function() {
1351          ws.close(1000, 'some reason', {mask: true});
1352        });
1353        srv.on('close', function(code, message, flags) {
1354          assert.ok(flags.masked);
1355          assert.equal('some reason', message);
1356          srv.close();
1357          ws.terminate();
1358          done();
1359        });
1360      });
1361    });
1362
1363    it('ends connection to the server', function(done) {
1364      server.createServer(++port, function(srv) {
1365        var ws = new WebSocket('ws://localhost:' + port);
1366        var connectedOnce = false;
1367        ws.on('open', function() {
1368          connectedOnce = true;
1369          ws.close(1000, 'some reason', {mask: true});
1370        });
1371        ws.on('close', function() {
1372          assert.ok(connectedOnce);
1373          srv.close();
1374          ws.terminate();
1375          done();
1376        });
1377      });
1378    });
1379  });
1380
1381  describe('W3C API emulation', function() {
1382    it('should not throw errors when getting and setting', function(done) {
1383      server.createServer(++port, function(srv) {
1384        var ws = new WebSocket('ws://localhost:' + port);
1385        var listener = function () {};
1386
1387        ws.onmessage = listener;
1388        ws.onerror = listener;
1389        ws.onclose = listener;
1390        ws.onopen = listener;
1391
1392        assert.ok(ws.onopen === listener);
1393        assert.ok(ws.onmessage === listener);
1394        assert.ok(ws.onclose === listener);
1395        assert.ok(ws.onerror === listener);
1396
1397        srv.close();
1398        ws.terminate();
1399        done();
1400      });
1401    });
1402
1403    it('should work the same as the EventEmitter api', function(done) {
1404      server.createServer(++port, function(srv) {
1405        var ws = new WebSocket('ws://localhost:' + port);
1406        var listener = function() {};
1407        var message = 0;
1408        var close = 0;
1409        var open = 0;
1410
1411        ws.onmessage = function(messageEvent) {
1412          assert.ok(!!messageEvent.data);
1413          ++message;
1414          ws.close();
1415        };
1416
1417        ws.onopen = function() {
1418          ++open;
1419        }
1420
1421        ws.onclose = function() {
1422          ++close;
1423        }
1424
1425        ws.on('open', function() {
1426          ws.send('foo');
1427        });
1428
1429        ws.on('close', function() {
1430          process.nextTick(function() {
1431            assert.ok(message === 1);
1432            assert.ok(open === 1);
1433            assert.ok(close === 1);
1434
1435            srv.close();
1436            ws.terminate();
1437            done();
1438          });
1439        });
1440      });
1441    });
1442
1443    it('should receive text data wrapped in a MessageEvent when using addEventListener', function(done) {
1444      server.createServer(++port, function(srv) {
1445        var ws = new WebSocket('ws://localhost:' + port);
1446        ws.addEventListener('open', function() {
1447          ws.send('hi');
1448        });
1449        ws.addEventListener('message', function(messageEvent) {
1450          assert.equal('hi', messageEvent.data);
1451          ws.terminate();
1452          srv.close();
1453          done();
1454        });
1455      });
1456    });
1457
1458    it('should receive valid CloseEvent when server closes with code 1000', function(done) {
1459      var wss = new WebSocketServer({port: ++port}, function() {
1460        var ws = new WebSocket('ws://localhost:' + port);
1461        ws.addEventListener('close', function(closeEvent) {
1462          assert.equal(true, closeEvent.wasClean);
1463          assert.equal(1000, closeEvent.code);
1464          ws.terminate();
1465          wss.close();
1466          done();
1467        });
1468      });
1469      wss.on('connection', function(client) {
1470        client.close(1000);
1471      });
1472    });
1473
1474    it('should receive valid CloseEvent when server closes with code 1001', function(done) {
1475      var wss = new WebSocketServer({port: ++port}, function() {
1476        var ws = new WebSocket('ws://localhost:' + port);
1477        ws.addEventListener('close', function(closeEvent) {
1478          assert.equal(false, closeEvent.wasClean);
1479          assert.equal(1001, closeEvent.code);
1480          assert.equal('some daft reason', closeEvent.reason);
1481          ws.terminate();
1482          wss.close();
1483          done();
1484        });
1485      });
1486      wss.on('connection', function(client) {
1487        client.close(1001, 'some daft reason');
1488      });
1489    });
1490
1491    it('should have target set on Events', function(done) {
1492      var wss = new WebSocketServer({port: ++port}, function() {
1493        var ws = new WebSocket('ws://localhost:' + port);
1494        ws.addEventListener('open', function(openEvent) {
1495          assert.equal(ws, openEvent.target);
1496        });
1497        ws.addEventListener('message', function(messageEvent) {
1498          assert.equal(ws, messageEvent.target);
1499          wss.close();
1500        });
1501        ws.addEventListener('close', function(closeEvent) {
1502          assert.equal(ws, closeEvent.target);
1503          ws.emit('error', new Error('forced'));
1504        });
1505        ws.addEventListener('error', function(errorEvent) {
1506          assert.equal(errorEvent.message, 'forced');
1507          assert.equal(ws, errorEvent.target);
1508          ws.terminate();
1509          done();
1510        });
1511      });
1512      wss.on('connection', function(client) {
1513        client.send('hi')
1514      });
1515    });
1516  });
1517
1518  describe('ssl', function() {
1519    it('can connect to secure websocket server', function(done) {
1520      var options = {
1521        key: fs.readFileSync('test/fixtures/key.pem'),
1522        cert: fs.readFileSync('test/fixtures/certificate.pem')
1523      };
1524      var app = https.createServer(options, function (req, res) {
1525        res.writeHead(200);
1526        res.end();
1527      });
1528      var wss = new WebSocketServer({server: app});
1529      app.listen(++port, function() {
1530        var ws = new WebSocket('wss://localhost:' + port);
1531      });
1532      wss.on('connection', function(ws) {
1533        app.close();
1534        ws.terminate();
1535        wss.close();
1536        done();
1537      });
1538    });
1539
1540    it('can connect to secure websocket server with client side certificate', function(done) {
1541      var options = {
1542        key: fs.readFileSync('test/fixtures/key.pem'),
1543        cert: fs.readFileSync('test/fixtures/certificate.pem'),
1544        ca: [fs.readFileSync('test/fixtures/ca1-cert.pem')],
1545        requestCert: true
1546      };
1547      var clientOptions = {
1548        key: fs.readFileSync('test/fixtures/agent1-key.pem'),
1549        cert: fs.readFileSync('test/fixtures/agent1-cert.pem')
1550      };
1551      var app = https.createServer(options, function (req, res) {
1552        res.writeHead(200);
1553        res.end();
1554      });
1555      var success = false;
1556      var wss = new WebSocketServer({
1557        server: app,
1558        verifyClient: function(info) {
1559          success = !!info.req.client.authorized;
1560          return true;
1561        }
1562      });
1563      app.listen(++port, function() {
1564        var ws = new WebSocket('wss://localhost:' + port, clientOptions);
1565      });
1566      wss.on('connection', function(ws) {
1567        app.close();
1568        ws.terminate();
1569        wss.close();
1570        success.should.be.ok;
1571        done();
1572      });
1573    });
1574
1575    it('cannot connect to secure websocket server via ws://', function(done) {
1576      var options = {
1577        key: fs.readFileSync('test/fixtures/key.pem'),
1578        cert: fs.readFileSync('test/fixtures/certificate.pem')
1579      };
1580      var app = https.createServer(options, function (req, res) {
1581        res.writeHead(200);
1582        res.end();
1583      });
1584      var wss = new WebSocketServer({server: app});
1585      app.listen(++port, function() {
1586        var ws = new WebSocket('ws://localhost:' + port, { rejectUnauthorized :false });
1587        ws.on('error', function() {
1588          app.close();
1589          ws.terminate();
1590          wss.close();
1591          done();
1592        });
1593      });
1594    });
1595
1596    it('can send and receive text data', function(done) {
1597      var options = {
1598        key: fs.readFileSync('test/fixtures/key.pem'),
1599        cert: fs.readFileSync('test/fixtures/certificate.pem')
1600      };
1601      var app = https.createServer(options, function (req, res) {
1602        res.writeHead(200);
1603        res.end();
1604      });
1605      var wss = new WebSocketServer({server: app});
1606      app.listen(++port, function() {
1607        var ws = new WebSocket('wss://localhost:' + port);
1608        ws.on('open', function() {
1609          ws.send('foobar');
1610        });
1611      });
1612      wss.on('connection', function(ws) {
1613        ws.on('message', function(message, flags) {
1614          message.should.eql('foobar');
1615          app.close();
1616          ws.terminate();
1617          wss.close();
1618          done();
1619        });
1620      });
1621    });
1622
1623    it('can send and receive very long binary data', function(done) {
1624      var options = {
1625        key: fs.readFileSync('test/fixtures/key.pem'),
1626        cert: fs.readFileSync('test/fixtures/certificate.pem')
1627      }
1628      var app = https.createServer(options, function (req, res) {
1629        res.writeHead(200);
1630        res.end();
1631      });
1632      crypto.randomBytes(5 * 1024 * 1024, function(ex, buf) {
1633        if (ex) throw ex;
1634        var wss = new WebSocketServer({server: app});
1635        app.listen(++port, function() {
1636          var ws = new WebSocket('wss://localhost:' + port);
1637          ws.on('open', function() {
1638            ws.send(buf, {binary: true});
1639          });
1640          ws.on('message', function(message, flags) {
1641            flags.binary.should.be.ok;
1642            areArraysEqual(buf, message).should.be.ok;
1643            app.close();
1644            ws.terminate();
1645            wss.close();
1646            done();
1647          });
1648        });
1649        wss.on('connection', function(ws) {
1650          ws.on('message', function(message, flags) {
1651            ws.send(message, {binary: true});
1652          });
1653        });
1654      });
1655    });
1656  });
1657
1658  describe('protocol support discovery', function() {
1659    describe('#supports', function() {
1660      describe('#binary', function() {
1661        it('returns true for hybi transport', function(done) {
1662          var wss = new WebSocketServer({port: ++port}, function() {
1663            var ws = new WebSocket('ws://localhost:' + port);
1664          });
1665          wss.on('connection', function(client) {
1666            assert.equal(true, client.supports.binary);
1667            wss.close();
1668            done();
1669          });
1670        });
1671
1672        it('returns false for hixie transport', function(done) {
1673          var wss = new WebSocketServer({port: ++port}, function() {
1674            var options = {
1675              port: port,
1676              host: '127.0.0.1',
1677              headers: {
1678                'Connection': 'Upgrade',
1679                'Upgrade': 'WebSocket',
1680                'Sec-WebSocket-Key1': '3e6b263  4 17 80',
1681                'Sec-WebSocket-Key2': '17  9 G`ZD9   2 2b 7X 3 /r90'
1682              }
1683            };
1684            var req = http.request(options);
1685            req.write('WjN}|M(6');
1686            req.end();
1687          });
1688          wss.on('connection', function(client) {
1689            assert.equal(false, client.supports.binary);
1690            wss.close();
1691            done();
1692          });
1693        });
1694      });
1695    });
1696  });
1697
1698  describe('host and origin headers', function() {
1699    it('includes the host header with port number', function(done) {
1700      var srv = http.createServer();
1701      srv.listen(++port, function(){
1702        srv.on('upgrade', function(req, socket, upgradeHeade) {
1703          assert.equal('localhost:' + port, req.headers['host']);
1704          srv.close();
1705          done();
1706        });
1707        var ws = new WebSocket('ws://localhost:' + port);
1708      });
1709    });
1710
1711    it('includes the origin header with port number', function(done) {
1712      var srv = http.createServer();
1713      srv.listen(++port, function() {
1714        srv.on('upgrade', function(req, socket, upgradeHeade) {
1715          assert.equal('localhost:' + port, req.headers['origin']);
1716          srv.close();
1717          done();
1718        });
1719        var ws = new WebSocket('ws://localhost:' + port);
1720      });
1721    });
1722  });
1723
1724});