| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 | 'use strict';var Buffer = require('safe-buffer').Buffer,    Base   = require('./base'),    util   = require('util');var Draft75 = function(request, url, options) {  Base.apply(this, arguments);  this._stage  = 0;  this.version = 'hixie-75';  this._headers.set('Upgrade', 'WebSocket');  this._headers.set('Connection', 'Upgrade');  this._headers.set('WebSocket-Origin', this._request.headers.origin);  this._headers.set('WebSocket-Location', this.url);};util.inherits(Draft75, Base);var instance = {  close: function() {    if (this.readyState === 3) return false;    this.readyState = 3;    this.emit('close', new Base.CloseEvent(null, null));    return true;  },  parse: function(chunk) {    if (this.readyState > 1) return;    this._reader.put(chunk);    this._reader.eachByte(function(octet) {      var message;      switch (this._stage) {        case -1:          this._body.push(octet);          this._sendHandshakeBody();          break;        case 0:          this._parseLeadingByte(octet);          break;        case 1:          this._length = (octet & 0x7F) + 128 * this._length;          if (this._closing && this._length === 0) {            return this.close();          }          else if ((octet & 0x80) !== 0x80) {            if (this._length === 0) {              this._stage = 0;            }            else {              this._skipped = 0;              this._stage   = 2;            }          }          break;        case 2:          if (octet === 0xFF) {            this._stage = 0;            message = Buffer.from(this._buffer).toString('utf8', 0, this._buffer.length);            this.emit('message', new Base.MessageEvent(message));          }          else {            if (this._length) {              this._skipped += 1;              if (this._skipped === this._length)                this._stage = 0;            } else {              this._buffer.push(octet);              if (this._buffer.length > this._maxLength) return this.close();            }          }          break;      }    }, this);  },  frame: function(buffer) {    if (this.readyState === 0) return this._queue([buffer]);    if (this.readyState > 1) return false;    if (typeof buffer !== 'string') buffer = buffer.toString();    var length = Buffer.byteLength(buffer),        frame  = Buffer.allocUnsafe(length + 2);    frame[0] = 0x00;    frame.write(buffer, 1);    frame[frame.length - 1] = 0xFF;    this._write(frame);    return true;  },  _handshakeResponse: function() {    var start   = 'HTTP/1.1 101 Web Socket Protocol Handshake',        headers = [start, this._headers.toString(), ''];    return Buffer.from(headers.join('\r\n'), 'utf8');  },  _parseLeadingByte: function(octet) {    if ((octet & 0x80) === 0x80) {      this._length = 0;      this._stage  = 1;    } else {      delete this._length;      delete this._skipped;      this._buffer = [];      this._stage  = 2;    }  }};for (var key in instance)  Draft75.prototype[key] = instance[key];module.exports = Draft75;
 |