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;
|
---|