UNPKG

4.84 kBtext/coffeescriptView Raw
1SocketIoClient = require('socket.io-client')
2SocketIoStream = require('socket.io-stream')
3OS = require('os')
4
5
6Base = require('../base')
7Caller = require('./caller')
8ClientInfo = require('./client_info')
9Connector = require('./connector')
10Crypto = require('./crypto')
11HttpProxy = require('./http_proxy')
12Logger = require('./logger')
13PolyglotRelay = require('./polyglot_relay')
14Publisher = require('./publisher')
15
16
17EVENTS = [ 'connect', 'connect_error', 'connect_timeout', 'reconnect', 'reconnect_error', 'reconnect_failed', 'error', 'disconnect', 'open', 'close', 'reconnect_attempt' ]
18
19debug = Base.logger('connector')
20
21isHttpProxy = false
22isRelay = false
23
24# Connection state variables.
25socket = null
26proxyData = null
27isHttpProxySetup = false
28
29
30exports.connectToProxy = (data) ->
31 debug('connectToProxy', data)
32 # Reset connection state.
33 socket = null
34 proxyData = null
35 isHttpProxySetup = false
36 Logger.loadFilter ->
37 proxyData = data
38 proxyData.proxyUrl = "https://"+Base.env.IX_PROXY_HOST_OVERRIDE if Base.env.IX_PROXY_HOST_OVERRIDE
39 console.log('Connecting to '+proxyData.proxyUrl+'...')
40 socket = SocketIoClient(proxyData.proxyUrl, { reconnection: false, multiplex: false, rejectUnauthorized: Base.env.IX_PROXY_HOST_ALLOW_UNVERIFIED != 'TRUE' }) # rejectUnauthorized: https://www.cigital.com/blog/node-js-socket-io/
41 setDebugHandlers(socket, EVENTS)
42 setDebugHandlers(socket.io, EVENTS, 'manager:')
43 socket.on('connect', onConnect)
44 socket.on 'connect_error', (err) ->
45 console.log('Connect error: '+err)
46 reconnect()
47 socket.on 'disconnect', (cause) ->
48 console.log('Disconnected from '+proxyData.proxyUrl+': '+cause)
49 reconnect()
50 unless isHttpProxy
51 socket.on('ix-call', onIxCall)
52 socket.on('ix-ping', onIxPing)
53 socket.on('ix-x', onIxX)
54
55exports.connectRelayToProxy = (data) ->
56 debug('connectRelayToProxy', data)
57 isRelay = true
58 exports.connectToProxy(data)
59
60exports.connectHttpToProxy = (upstream, data) ->
61 debug('connectHttpToProxy', upstream, data)
62 isHttpProxy = true
63 HttpProxy.setupHttpProxy(upstream)
64 exports.connectToProxy(data)
65
66
67onConnect = ->
68 debug('connect')
69 ClientInfo.clientInfo()
70 .then (clientInfo) ->
71 debug('clientInfo', clientInfo)
72 socket.emit 'set-client',
73 apiConfig: Base.apiConfig()
74 proxyUrl: proxyData.proxyUrl
75 proxyExport: proxyData.proxyExport
76 device: { key: clientInfo.deviceKey, secret: clientInfo.deviceSecret } # TODO: update IX to use deviceKey, deviceSecret instead of device.
77 deviceKey: clientInfo.deviceKey
78 deviceSecret: clientInfo.deviceSecret
79 hostname: OS.hostname()
80 pid: process.pid
81 processKey: getProcessKey()
82 clientInfo: clientInfo
83 , (err, connectData) ->
84 debug('connect result', err, connectData)
85 if err
86 console.log('Connect error: Unable to complete connection to '+proxyData.proxyUrl+': '+JSON.stringify(err))
87 throw new Error(err)
88 else
89 if isHttpProxy
90 SocketIoStream.forceBase64 = true unless connectData.enableBinaryStream
91 debug('SocketIoStream.forceBase64', SocketIoStream.forceBase64)
92 unless isHttpProxySetup
93 isHttpProxySetup = true
94 streamSocket = SocketIoStream(socket)
95 setDebugHandlers(streamSocket, EVENTS, 'stream:')
96 streamSocket.on('http-proxy', HttpProxy.onHttpProxy)
97 console.log('Connected to '+proxyData.proxyUrl+'.')
98
99reconnect = ->
100 setTimeout ->
101 Publisher.getProxyForReconnect(isHttpProxy)
102 .then (data) ->
103 Connector.connectToProxy(data)
104 , (e) ->
105 console.error('ERROR WHILE RECONNECTING', e)
106 reconnect()
107 , 1000 # + Math.random()*2000 # Float timers broken in 0.10.30: https://github.com/nodejs/node-v0.x-archive/pull/8073
108
109
110onIxCall = (data, responder) ->
111 debug('ix-call', arguments)
112 try
113 Logger.logCallRequest(data)
114 responder = Logger.wrapResponder(data, debug.wrap(responder))
115 catch e
116 try
117 if isRelay
118 Caller.ixCall(data, responder, PolyglotRelay.invoker)
119 else
120 Caller.ixCallNodejs(data, responder)
121 catch e
122 responder(e)
123
124onIxPing = (replyData, responder) ->
125 debug('ix-ping', replyData)
126 responder(null, replyData)
127
128onIxX = (cipherParams, responder) ->
129 debug('ix-x', cipherParams)
130 Crypto.decrypt cipherParams, (err, data) ->
131 if err
132 responder.call(err); return
133 onIxCall(data, Crypto.encryptingResponder(responder))
134
135
136PROCESS_KEY = null
137getProcessKey = ->
138 PROCESS_KEY ?= (new Date()).getTime()+'-'+Math.floor((Math.random()*1000000))
139 PROCESS_KEY
140
141setDebugHandlers = (socket, events, prefix) ->
142 prefix = prefix || ''
143 for event in events
144 socket.on(event, debugHandlerFor(prefix+event))
145
146debugHandlerFor = (type) ->
147 (args...) ->
148 args.unshift('event:'+type)
149 debug.apply(this, args)