mirror of
				https://github.com/musix-org/musix-oss
				synced 2025-11-04 12:59:31 +00:00 
			
		
		
		
	Updated
This commit is contained in:
		
							
								
								
									
										133
									
								
								node_modules/faye-websocket/lib/faye/eventsource.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								node_modules/faye-websocket/lib/faye/eventsource.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var Stream      = require('stream').Stream,
 | 
			
		||||
    util        = require('util'),
 | 
			
		||||
    driver      = require('websocket-driver'),
 | 
			
		||||
    Headers     = require('websocket-driver/lib/websocket/driver/headers'),
 | 
			
		||||
    API         = require('./websocket/api'),
 | 
			
		||||
    EventTarget = require('./websocket/api/event_target'),
 | 
			
		||||
    Event       = require('./websocket/api/event');
 | 
			
		||||
 | 
			
		||||
var EventSource = function(request, response, options) {
 | 
			
		||||
  this.writable = true;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  this._stream = response.socket;
 | 
			
		||||
  this._ping   = options.ping  || this.DEFAULT_PING;
 | 
			
		||||
  this._retry  = options.retry || this.DEFAULT_RETRY;
 | 
			
		||||
 | 
			
		||||
  var scheme       = driver.isSecureRequest(request) ? 'https:' : 'http:';
 | 
			
		||||
  this.url         = scheme + '//' + request.headers.host + request.url;
 | 
			
		||||
  this.lastEventId = request.headers['last-event-id'] || '';
 | 
			
		||||
  this.readyState  = API.CONNECTING;
 | 
			
		||||
 | 
			
		||||
  var headers = new Headers(),
 | 
			
		||||
      self    = this;
 | 
			
		||||
 | 
			
		||||
  if (options.headers) {
 | 
			
		||||
    for (var key in options.headers) headers.set(key, options.headers[key]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!this._stream || !this._stream.writable) return;
 | 
			
		||||
  process.nextTick(function() { self._open() });
 | 
			
		||||
 | 
			
		||||
  this._stream.setTimeout(0);
 | 
			
		||||
  this._stream.setNoDelay(true);
 | 
			
		||||
 | 
			
		||||
  var handshake = 'HTTP/1.1 200 OK\r\n' +
 | 
			
		||||
                  'Content-Type: text/event-stream\r\n' +
 | 
			
		||||
                  'Cache-Control: no-cache, no-store\r\n' +
 | 
			
		||||
                  'Connection: close\r\n' +
 | 
			
		||||
                  headers.toString() +
 | 
			
		||||
                  '\r\n' +
 | 
			
		||||
                  'retry: ' + Math.floor(this._retry * 1000) + '\r\n\r\n';
 | 
			
		||||
 | 
			
		||||
  this._write(handshake);
 | 
			
		||||
 | 
			
		||||
  this._stream.on('drain', function() { self.emit('drain') });
 | 
			
		||||
 | 
			
		||||
  if (this._ping)
 | 
			
		||||
    this._pingTimer = setInterval(function() { self.ping() }, this._ping * 1000);
 | 
			
		||||
 | 
			
		||||
  ['error', 'end'].forEach(function(event) {
 | 
			
		||||
    self._stream.on(event, function() { self.close() });
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
util.inherits(EventSource, Stream);
 | 
			
		||||
 | 
			
		||||
EventSource.isEventSource = function(request) {
 | 
			
		||||
  if (request.method !== 'GET') return false;
 | 
			
		||||
  var accept = (request.headers.accept || '').split(/\s*,\s*/);
 | 
			
		||||
  return accept.indexOf('text/event-stream') >= 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var instance = {
 | 
			
		||||
  DEFAULT_PING:   10,
 | 
			
		||||
  DEFAULT_RETRY:  5,
 | 
			
		||||
 | 
			
		||||
  _write: function(chunk) {
 | 
			
		||||
    if (!this.writable) return false;
 | 
			
		||||
    try {
 | 
			
		||||
      return this._stream.write(chunk, 'utf8');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _open: function() {
 | 
			
		||||
    if (this.readyState !== API.CONNECTING) return;
 | 
			
		||||
 | 
			
		||||
    this.readyState = API.OPEN;
 | 
			
		||||
 | 
			
		||||
    var event = new Event('open');
 | 
			
		||||
    event.initEvent('open', false, false);
 | 
			
		||||
    this.dispatchEvent(event);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  write: function(message) {
 | 
			
		||||
    return this.send(message);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  end: function(message) {
 | 
			
		||||
    if (message !== undefined) this.write(message);
 | 
			
		||||
    this.close();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  send: function(message, options) {
 | 
			
		||||
    if (this.readyState > API.OPEN) return false;
 | 
			
		||||
 | 
			
		||||
    message = String(message).replace(/(\r\n|\r|\n)/g, '$1data: ');
 | 
			
		||||
    options = options || {};
 | 
			
		||||
 | 
			
		||||
    var frame = '';
 | 
			
		||||
    if (options.event) frame += 'event: ' + options.event + '\r\n';
 | 
			
		||||
    if (options.id)    frame += 'id: '    + options.id    + '\r\n';
 | 
			
		||||
    frame += 'data: ' + message + '\r\n\r\n';
 | 
			
		||||
 | 
			
		||||
    return this._write(frame);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  ping: function() {
 | 
			
		||||
    return this._write(':\r\n\r\n');
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  close: function() {
 | 
			
		||||
    if (this.readyState > API.OPEN) return false;
 | 
			
		||||
 | 
			
		||||
    this.readyState = API.CLOSED;
 | 
			
		||||
    this.writable = false;
 | 
			
		||||
    if (this._pingTimer) clearInterval(this._pingTimer);
 | 
			
		||||
    if (this._stream) this._stream.end();
 | 
			
		||||
 | 
			
		||||
    var event = new Event('close');
 | 
			
		||||
    event.initEvent('close', false, false);
 | 
			
		||||
    this.dispatchEvent(event);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
for (var method in instance) EventSource.prototype[method] = instance[method];
 | 
			
		||||
for (var key in EventTarget) EventSource.prototype[key] = EventTarget[key];
 | 
			
		||||
 | 
			
		||||
module.exports = EventSource;
 | 
			
		||||
							
								
								
									
										47
									
								
								node_modules/faye-websocket/lib/faye/websocket.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								node_modules/faye-websocket/lib/faye/websocket.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
// API references:
 | 
			
		||||
//
 | 
			
		||||
// * https://html.spec.whatwg.org/multipage/comms.html#network
 | 
			
		||||
// * https://dom.spec.whatwg.org/#interface-eventtarget
 | 
			
		||||
// * https://dom.spec.whatwg.org/#interface-event
 | 
			
		||||
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var util   = require('util'),
 | 
			
		||||
    driver = require('websocket-driver'),
 | 
			
		||||
    API    = require('./websocket/api');
 | 
			
		||||
 | 
			
		||||
var WebSocket = function(request, socket, body, protocols, options) {
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  this._stream = socket;
 | 
			
		||||
  this._driver = driver.http(request, {maxLength: options.maxLength, protocols: protocols});
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
  if (!this._stream || !this._stream.writable) return;
 | 
			
		||||
  if (!this._stream.readable) return this._stream.end();
 | 
			
		||||
 | 
			
		||||
  var catchup = function() { self._stream.removeListener('data', catchup) };
 | 
			
		||||
  this._stream.on('data', catchup);
 | 
			
		||||
 | 
			
		||||
  API.call(this, options);
 | 
			
		||||
 | 
			
		||||
  process.nextTick(function() {
 | 
			
		||||
    self._driver.start();
 | 
			
		||||
    self._driver.io.write(body);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
util.inherits(WebSocket, API);
 | 
			
		||||
 | 
			
		||||
WebSocket.isWebSocket = function(request) {
 | 
			
		||||
  return driver.isWebSocket(request);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WebSocket.validateOptions = function(options, validKeys) {
 | 
			
		||||
  driver.validateOptions(options, validKeys);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WebSocket.WebSocket   = WebSocket;
 | 
			
		||||
WebSocket.Client      = require('./websocket/client');
 | 
			
		||||
WebSocket.EventSource = require('./eventsource');
 | 
			
		||||
 | 
			
		||||
module.exports        = WebSocket;
 | 
			
		||||
							
								
								
									
										197
									
								
								node_modules/faye-websocket/lib/faye/websocket/api.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								node_modules/faye-websocket/lib/faye/websocket/api.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var Stream      = require('stream').Stream,
 | 
			
		||||
    util        = require('util'),
 | 
			
		||||
    driver      = require('websocket-driver'),
 | 
			
		||||
    EventTarget = require('./api/event_target'),
 | 
			
		||||
    Event       = require('./api/event');
 | 
			
		||||
 | 
			
		||||
var API = function(options) {
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  driver.validateOptions(options, ['headers', 'extensions', 'maxLength', 'ping', 'proxy', 'tls', 'ca']);
 | 
			
		||||
 | 
			
		||||
  this.readable = this.writable = true;
 | 
			
		||||
 | 
			
		||||
  var headers = options.headers;
 | 
			
		||||
  if (headers) {
 | 
			
		||||
    for (var name in headers) this._driver.setHeader(name, headers[name]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var extensions = options.extensions;
 | 
			
		||||
  if (extensions) {
 | 
			
		||||
    [].concat(extensions).forEach(this._driver.addExtension, this._driver);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this._ping          = options.ping;
 | 
			
		||||
  this._pingId        = 0;
 | 
			
		||||
  this.readyState     = API.CONNECTING;
 | 
			
		||||
  this.bufferedAmount = 0;
 | 
			
		||||
  this.protocol       = '';
 | 
			
		||||
  this.url            = this._driver.url;
 | 
			
		||||
  this.version        = this._driver.version;
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  this._driver.on('open',    function(e) { self._open() });
 | 
			
		||||
  this._driver.on('message', function(e) { self._receiveMessage(e.data) });
 | 
			
		||||
  this._driver.on('close',   function(e) { self._beginClose(e.reason, e.code) });
 | 
			
		||||
 | 
			
		||||
  this._driver.on('error', function(error) {
 | 
			
		||||
    self._emitError(error.message);
 | 
			
		||||
  });
 | 
			
		||||
  this.on('error', function() {});
 | 
			
		||||
 | 
			
		||||
  this._driver.messages.on('drain', function() {
 | 
			
		||||
    self.emit('drain');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (this._ping)
 | 
			
		||||
    this._pingTimer = setInterval(function() {
 | 
			
		||||
      self._pingId += 1;
 | 
			
		||||
      self.ping(self._pingId.toString());
 | 
			
		||||
    }, this._ping * 1000);
 | 
			
		||||
 | 
			
		||||
  this._configureStream();
 | 
			
		||||
 | 
			
		||||
  if (!this._proxy) {
 | 
			
		||||
    this._stream.pipe(this._driver.io);
 | 
			
		||||
    this._driver.io.pipe(this._stream);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
util.inherits(API, Stream);
 | 
			
		||||
 | 
			
		||||
API.CONNECTING = 0;
 | 
			
		||||
API.OPEN       = 1;
 | 
			
		||||
API.CLOSING    = 2;
 | 
			
		||||
API.CLOSED     = 3;
 | 
			
		||||
 | 
			
		||||
API.CLOSE_TIMEOUT = 30000;
 | 
			
		||||
 | 
			
		||||
var instance = {
 | 
			
		||||
  write: function(data) {
 | 
			
		||||
    return this.send(data);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  end: function(data) {
 | 
			
		||||
    if (data !== undefined) this.send(data);
 | 
			
		||||
    this.close();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  pause: function() {
 | 
			
		||||
    return this._driver.messages.pause();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  resume: function() {
 | 
			
		||||
    return this._driver.messages.resume();
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  send: function(data) {
 | 
			
		||||
    if (this.readyState > API.OPEN) return false;
 | 
			
		||||
    if (!(data instanceof Buffer)) data = String(data);
 | 
			
		||||
    return this._driver.messages.write(data);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  ping: function(message, callback) {
 | 
			
		||||
    if (this.readyState > API.OPEN) return false;
 | 
			
		||||
    return this._driver.ping(message, callback);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  close: function(code, reason) {
 | 
			
		||||
    if (code === undefined) code = 1000;
 | 
			
		||||
    if (reason === undefined) reason = '';
 | 
			
		||||
 | 
			
		||||
    if (code !== 1000 && (code < 3000 || code > 4999))
 | 
			
		||||
      throw new Error("Failed to execute 'close' on WebSocket: " +
 | 
			
		||||
                      "The code must be either 1000, or between 3000 and 4999. " +
 | 
			
		||||
                      code + " is neither.");
 | 
			
		||||
 | 
			
		||||
    if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING;
 | 
			
		||||
    var self = this;
 | 
			
		||||
 | 
			
		||||
    this._closeTimer = setTimeout(function() {
 | 
			
		||||
      self._beginClose('', 1006);
 | 
			
		||||
    }, API.CLOSE_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
    this._driver.close(reason, code);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _configureStream: function() {
 | 
			
		||||
    var self = this;
 | 
			
		||||
 | 
			
		||||
    this._stream.setTimeout(0);
 | 
			
		||||
    this._stream.setNoDelay(true);
 | 
			
		||||
 | 
			
		||||
    ['close', 'end'].forEach(function(event) {
 | 
			
		||||
      this._stream.on(event, function() { self._finalizeClose() });
 | 
			
		||||
    }, this);
 | 
			
		||||
 | 
			
		||||
    this._stream.on('error', function(error) {
 | 
			
		||||
      self._emitError('Network error: ' + self.url + ': ' + error.message);
 | 
			
		||||
      self._finalizeClose();
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _open: function() {
 | 
			
		||||
    if (this.readyState !== API.CONNECTING) return;
 | 
			
		||||
 | 
			
		||||
    this.readyState = API.OPEN;
 | 
			
		||||
    this.protocol = this._driver.protocol || '';
 | 
			
		||||
 | 
			
		||||
    var event = new Event('open');
 | 
			
		||||
    event.initEvent('open', false, false);
 | 
			
		||||
    this.dispatchEvent(event);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _receiveMessage: function(data) {
 | 
			
		||||
    if (this.readyState > API.OPEN) return false;
 | 
			
		||||
 | 
			
		||||
    if (this.readable) this.emit('data', data);
 | 
			
		||||
 | 
			
		||||
    var event = new Event('message', {data: data});
 | 
			
		||||
    event.initEvent('message', false, false);
 | 
			
		||||
    this.dispatchEvent(event);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _emitError: function(message) {
 | 
			
		||||
    if (this.readyState >= API.CLOSING) return;
 | 
			
		||||
 | 
			
		||||
    var event = new Event('error', {message: message});
 | 
			
		||||
    event.initEvent('error', false, false);
 | 
			
		||||
    this.dispatchEvent(event);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _beginClose: function(reason, code) {
 | 
			
		||||
    if (this.readyState === API.CLOSED) return;
 | 
			
		||||
    this.readyState = API.CLOSING;
 | 
			
		||||
    this._closeParams = [reason, code];
 | 
			
		||||
 | 
			
		||||
    if (this._stream) {
 | 
			
		||||
      this._stream.destroy();
 | 
			
		||||
      if (!this._stream.readable) this._finalizeClose();
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  _finalizeClose: function() {
 | 
			
		||||
    if (this.readyState === API.CLOSED) return;
 | 
			
		||||
    this.readyState = API.CLOSED;
 | 
			
		||||
 | 
			
		||||
    if (this._closeTimer) clearTimeout(this._closeTimer);
 | 
			
		||||
    if (this._pingTimer) clearInterval(this._pingTimer);
 | 
			
		||||
    if (this._stream) this._stream.end();
 | 
			
		||||
 | 
			
		||||
    if (this.readable) this.emit('end');
 | 
			
		||||
    this.readable = this.writable = false;
 | 
			
		||||
 | 
			
		||||
    var reason = this._closeParams ? this._closeParams[0] : '',
 | 
			
		||||
        code   = this._closeParams ? this._closeParams[1] : 1006;
 | 
			
		||||
 | 
			
		||||
    var event = new Event('close', {code: code, reason: reason});
 | 
			
		||||
    event.initEvent('close', false, false);
 | 
			
		||||
    this.dispatchEvent(event);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
for (var method in instance) API.prototype[method] = instance[method];
 | 
			
		||||
for (var key in EventTarget) API.prototype[key] = EventTarget[key];
 | 
			
		||||
 | 
			
		||||
module.exports = API;
 | 
			
		||||
							
								
								
									
										22
									
								
								node_modules/faye-websocket/lib/faye/websocket/api/event.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								node_modules/faye-websocket/lib/faye/websocket/api/event.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var Event = function(eventType, options) {
 | 
			
		||||
  this.type = eventType;
 | 
			
		||||
  for (var key in options)
 | 
			
		||||
    this[key] = options[key];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Event.prototype.initEvent = function(eventType, canBubble, cancelable) {
 | 
			
		||||
  this.type       = eventType;
 | 
			
		||||
  this.bubbles    = canBubble;
 | 
			
		||||
  this.cancelable = cancelable;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Event.prototype.stopPropagation = function() {};
 | 
			
		||||
Event.prototype.preventDefault  = function() {};
 | 
			
		||||
 | 
			
		||||
Event.CAPTURING_PHASE = 1;
 | 
			
		||||
Event.AT_TARGET       = 2;
 | 
			
		||||
Event.BUBBLING_PHASE  = 3;
 | 
			
		||||
 | 
			
		||||
module.exports = Event;
 | 
			
		||||
							
								
								
									
										30
									
								
								node_modules/faye-websocket/lib/faye/websocket/api/event_target.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								node_modules/faye-websocket/lib/faye/websocket/api/event_target.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var Event = require('./event');
 | 
			
		||||
 | 
			
		||||
var EventTarget = {
 | 
			
		||||
  onopen:     null,
 | 
			
		||||
  onmessage:  null,
 | 
			
		||||
  onerror:    null,
 | 
			
		||||
  onclose:    null,
 | 
			
		||||
 | 
			
		||||
  addEventListener: function(eventType, listener, useCapture) {
 | 
			
		||||
    this.on(eventType, listener);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  removeEventListener: function(eventType, listener, useCapture) {
 | 
			
		||||
    this.removeListener(eventType, listener);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  dispatchEvent: function(event) {
 | 
			
		||||
    event.target = event.currentTarget = this;
 | 
			
		||||
    event.eventPhase = Event.AT_TARGET;
 | 
			
		||||
 | 
			
		||||
    if (this['on' + event.type])
 | 
			
		||||
      this['on' + event.type](event);
 | 
			
		||||
 | 
			
		||||
    this.emit(event.type, event);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = EventTarget;
 | 
			
		||||
							
								
								
									
										90
									
								
								node_modules/faye-websocket/lib/faye/websocket/client.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								node_modules/faye-websocket/lib/faye/websocket/client.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var util   = require('util'),
 | 
			
		||||
    net    = require('net'),
 | 
			
		||||
    tls    = require('tls'),
 | 
			
		||||
    url    = require('url'),
 | 
			
		||||
    driver = require('websocket-driver'),
 | 
			
		||||
    API    = require('./api'),
 | 
			
		||||
    Event  = require('./api/event');
 | 
			
		||||
 | 
			
		||||
var DEFAULT_PORTS    = {'http:': 80, 'https:': 443, 'ws:':80, 'wss:': 443},
 | 
			
		||||
    SECURE_PROTOCOLS = ['https:', 'wss:'];
 | 
			
		||||
 | 
			
		||||
var Client = function(_url, protocols, options) {
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  this.url     = _url;
 | 
			
		||||
  this._driver = driver.client(this.url, {maxLength: options.maxLength, protocols: protocols});
 | 
			
		||||
 | 
			
		||||
  ['open', 'error'].forEach(function(event) {
 | 
			
		||||
    this._driver.on(event, function() {
 | 
			
		||||
      self.headers    = self._driver.headers;
 | 
			
		||||
      self.statusCode = self._driver.statusCode;
 | 
			
		||||
    });
 | 
			
		||||
  }, this);
 | 
			
		||||
 | 
			
		||||
  var proxy      = options.proxy || {},
 | 
			
		||||
      endpoint   = url.parse(proxy.origin || this.url),
 | 
			
		||||
      port       = endpoint.port || DEFAULT_PORTS[endpoint.protocol],
 | 
			
		||||
      secure     = SECURE_PROTOCOLS.indexOf(endpoint.protocol) >= 0,
 | 
			
		||||
      onConnect  = function() { self._onConnect() },
 | 
			
		||||
      netOptions = options.net || {},
 | 
			
		||||
      originTLS  = options.tls || {},
 | 
			
		||||
      socketTLS  = proxy.origin ? (proxy.tls || {}) : originTLS,
 | 
			
		||||
      self       = this;
 | 
			
		||||
 | 
			
		||||
  netOptions.host = socketTLS.host = endpoint.hostname;
 | 
			
		||||
  netOptions.port = socketTLS.port = port;
 | 
			
		||||
 | 
			
		||||
  originTLS.ca = originTLS.ca || options.ca;
 | 
			
		||||
  socketTLS.servername = socketTLS.servername || endpoint.hostname;
 | 
			
		||||
 | 
			
		||||
  this._stream = secure
 | 
			
		||||
               ? tls.connect(socketTLS, onConnect)
 | 
			
		||||
               : net.connect(netOptions, onConnect);
 | 
			
		||||
 | 
			
		||||
  if (proxy.origin) this._configureProxy(proxy, originTLS);
 | 
			
		||||
 | 
			
		||||
  API.call(this, options);
 | 
			
		||||
};
 | 
			
		||||
util.inherits(Client, API);
 | 
			
		||||
 | 
			
		||||
Client.prototype._onConnect = function() {
 | 
			
		||||
  var worker = this._proxy || this._driver;
 | 
			
		||||
  worker.start();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Client.prototype._configureProxy = function(proxy, originTLS) {
 | 
			
		||||
  var uri    = url.parse(this.url),
 | 
			
		||||
      secure = SECURE_PROTOCOLS.indexOf(uri.protocol) >= 0,
 | 
			
		||||
      self   = this,
 | 
			
		||||
      name;
 | 
			
		||||
 | 
			
		||||
  this._proxy = this._driver.proxy(proxy.origin);
 | 
			
		||||
 | 
			
		||||
  if (proxy.headers) {
 | 
			
		||||
    for (name in proxy.headers) this._proxy.setHeader(name, proxy.headers[name]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this._proxy.pipe(this._stream, {end: false});
 | 
			
		||||
  this._stream.pipe(this._proxy);
 | 
			
		||||
 | 
			
		||||
  this._proxy.on('connect', function() {
 | 
			
		||||
    if (secure) {
 | 
			
		||||
      var options = {socket: self._stream, servername: uri.hostname};
 | 
			
		||||
      for (name in originTLS) options[name] = originTLS[name];
 | 
			
		||||
      self._stream = tls.connect(options);
 | 
			
		||||
      self._configureStream();
 | 
			
		||||
    }
 | 
			
		||||
    self._driver.io.pipe(self._stream);
 | 
			
		||||
    self._stream.pipe(self._driver.io);
 | 
			
		||||
    self._driver.start();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  this._proxy.on('error', function(error) {
 | 
			
		||||
    self._driver.emit('error', error);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = Client;
 | 
			
		||||
		Reference in New Issue
	
	Block a user