124 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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;
 |