[6a3a178] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | var util = require('util'),
|
---|
| 4 | net = require('net'),
|
---|
| 5 | tls = require('tls'),
|
---|
| 6 | url = require('url'),
|
---|
| 7 | driver = require('websocket-driver'),
|
---|
| 8 | API = require('./api'),
|
---|
| 9 | Event = require('./api/event');
|
---|
| 10 |
|
---|
| 11 | var DEFAULT_PORTS = { 'http:': 80, 'https:': 443, 'ws:':80, 'wss:': 443 },
|
---|
| 12 | SECURE_PROTOCOLS = ['https:', 'wss:'];
|
---|
| 13 |
|
---|
| 14 | var Client = function(_url, protocols, options) {
|
---|
| 15 | options = options || {};
|
---|
| 16 |
|
---|
| 17 | this.url = _url;
|
---|
| 18 | this._driver = driver.client(this.url, { maxLength: options.maxLength, protocols: protocols });
|
---|
| 19 |
|
---|
| 20 | ['open', 'error'].forEach(function(event) {
|
---|
| 21 | this._driver.on(event, function() {
|
---|
| 22 | self.headers = self._driver.headers;
|
---|
| 23 | self.statusCode = self._driver.statusCode;
|
---|
| 24 | });
|
---|
| 25 | }, this);
|
---|
| 26 |
|
---|
| 27 | var proxy = options.proxy || {},
|
---|
| 28 | endpoint = url.parse(proxy.origin || this.url),
|
---|
| 29 | port = endpoint.port || DEFAULT_PORTS[endpoint.protocol],
|
---|
| 30 | secure = SECURE_PROTOCOLS.indexOf(endpoint.protocol) >= 0,
|
---|
| 31 | onConnect = function() { self._onConnect() },
|
---|
| 32 | netOptions = options.net || {},
|
---|
| 33 | originTLS = options.tls || {},
|
---|
| 34 | socketTLS = proxy.origin ? (proxy.tls || {}) : originTLS,
|
---|
| 35 | self = this;
|
---|
| 36 |
|
---|
| 37 | netOptions.host = socketTLS.host = endpoint.hostname;
|
---|
| 38 | netOptions.port = socketTLS.port = port;
|
---|
| 39 |
|
---|
| 40 | originTLS.ca = originTLS.ca || options.ca;
|
---|
| 41 | socketTLS.servername = socketTLS.servername || endpoint.hostname;
|
---|
| 42 |
|
---|
| 43 | this._stream = secure
|
---|
| 44 | ? tls.connect(socketTLS, onConnect)
|
---|
| 45 | : net.connect(netOptions, onConnect);
|
---|
| 46 |
|
---|
| 47 | if (proxy.origin) this._configureProxy(proxy, originTLS);
|
---|
| 48 |
|
---|
| 49 | API.call(this, options);
|
---|
| 50 | };
|
---|
| 51 | util.inherits(Client, API);
|
---|
| 52 |
|
---|
| 53 | Client.prototype._onConnect = function() {
|
---|
| 54 | var worker = this._proxy || this._driver;
|
---|
| 55 | worker.start();
|
---|
| 56 | };
|
---|
| 57 |
|
---|
| 58 | Client.prototype._configureProxy = function(proxy, originTLS) {
|
---|
| 59 | var uri = url.parse(this.url),
|
---|
| 60 | secure = SECURE_PROTOCOLS.indexOf(uri.protocol) >= 0,
|
---|
| 61 | self = this,
|
---|
| 62 | name;
|
---|
| 63 |
|
---|
| 64 | this._proxy = this._driver.proxy(proxy.origin);
|
---|
| 65 |
|
---|
| 66 | if (proxy.headers) {
|
---|
| 67 | for (name in proxy.headers) this._proxy.setHeader(name, proxy.headers[name]);
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | this._proxy.pipe(this._stream, { end: false });
|
---|
| 71 | this._stream.pipe(this._proxy);
|
---|
| 72 |
|
---|
| 73 | this._proxy.on('connect', function() {
|
---|
| 74 | if (secure) {
|
---|
| 75 | var options = { socket: self._stream, servername: uri.hostname };
|
---|
| 76 | for (name in originTLS) options[name] = originTLS[name];
|
---|
| 77 | self._stream = tls.connect(options);
|
---|
| 78 | self._configureStream();
|
---|
| 79 | }
|
---|
| 80 | self._driver.io.pipe(self._stream);
|
---|
| 81 | self._stream.pipe(self._driver.io);
|
---|
| 82 | self._driver.start();
|
---|
| 83 | });
|
---|
| 84 |
|
---|
| 85 | this._proxy.on('error', function(error) {
|
---|
| 86 | self._driver.emit('error', error);
|
---|
| 87 | });
|
---|
| 88 | };
|
---|
| 89 |
|
---|
| 90 | module.exports = Client;
|
---|