mirror of
https://github.com/openstf/stf
synced 2025-10-04 10:19:30 +02:00
193 lines
5.4 KiB
JavaScript
193 lines
5.4 KiB
JavaScript
var net = require('net')
|
|
|
|
var Promise = require('bluebird')
|
|
var syrup = require('syrup')
|
|
var _ = require('lodash')
|
|
|
|
var wire = require('../../../../wire')
|
|
var logger = require('../../../../util/logger')
|
|
var lifecycle = require('../../../../util/lifecycle')
|
|
var streamutil = require('../../../../util/streamutil')
|
|
var wireutil = require('../../../../wire/util')
|
|
|
|
var ForwardManager = require('./util/manager')
|
|
|
|
module.exports = syrup.serial()
|
|
.dependency(require('../../support/adb'))
|
|
.dependency(require('../../support/router'))
|
|
.dependency(require('../../support/push'))
|
|
.dependency(require('../../resources/minirev'))
|
|
.dependency(require('../group'))
|
|
.define(function(options, adb, router, push, minirev, group) {
|
|
var log = logger.createLogger('device:plugins:forward')
|
|
var plugin = Object.create(null)
|
|
var manager = new ForwardManager()
|
|
|
|
function startService() {
|
|
log.info('Launching reverse port forwarding service')
|
|
return adb.shell(options.serial, [
|
|
'exec'
|
|
, minirev.bin
|
|
])
|
|
.timeout(10000)
|
|
.then(function(out) {
|
|
lifecycle.share('Forward shell', out)
|
|
streamutil.talk(log, 'Forward shell says: "%s"', out)
|
|
})
|
|
}
|
|
|
|
function connectService(times) {
|
|
function tryConnect(times, delay) {
|
|
return adb.openLocal(options.serial, 'localabstract:minirev')
|
|
.timeout(10000)
|
|
.catch(function(err) {
|
|
if (/closed/.test(err.message) && times > 1) {
|
|
return Promise.delay(delay)
|
|
.then(function() {
|
|
return tryConnect(--times, delay * 2)
|
|
})
|
|
}
|
|
return Promise.reject(err)
|
|
})
|
|
}
|
|
log.info('Connecting to reverse port forwarding service')
|
|
return tryConnect(times, 100)
|
|
}
|
|
|
|
function awaitServer() {
|
|
return connectService(5)
|
|
.then(function(conn) {
|
|
conn.end()
|
|
return true
|
|
})
|
|
}
|
|
|
|
plugin.createForward = function(id, forward) {
|
|
log.info(
|
|
'Creating reverse port forward "%s" from ":%d" to "%s:%d"'
|
|
, id
|
|
, forward.devicePort
|
|
, forward.targetHost
|
|
, forward.targetPort
|
|
)
|
|
return connectService(1)
|
|
.then(function(out) {
|
|
var header = new Buffer(4)
|
|
header.writeUInt16LE(0, 0)
|
|
header.writeUInt16LE(forward.devicePort, 2)
|
|
out.write(header)
|
|
return manager.add(id, out, forward)
|
|
})
|
|
}
|
|
|
|
plugin.removeForward = function(id) {
|
|
log.info('Removing reverse port forward "%s"', id)
|
|
manager.remove(id)
|
|
return Promise.resolve()
|
|
}
|
|
|
|
plugin.connect = function(options) {
|
|
var resolver = Promise.defer()
|
|
|
|
var conn = net.connect({
|
|
host: options.targetHost
|
|
, port: options.targetPort
|
|
})
|
|
|
|
function connectListener() {
|
|
resolver.resolve(conn)
|
|
}
|
|
|
|
function errorListener(err) {
|
|
resolver.reject(err)
|
|
}
|
|
|
|
conn.on('connect', connectListener)
|
|
conn.on('error', errorListener)
|
|
|
|
return resolver.promise.finally(function() {
|
|
conn.removeListener('connect', connectListener)
|
|
conn.removeListener('error', errorListener)
|
|
})
|
|
}
|
|
|
|
plugin.reset = function() {
|
|
manager.removeAll()
|
|
}
|
|
|
|
group.on('leave', plugin.reset)
|
|
|
|
var pushForwards = _.debounce(
|
|
function() {
|
|
push.send([
|
|
wireutil.global
|
|
, wireutil.envelope(new wire.ReverseForwardsEvent(
|
|
options.serial
|
|
, manager.listAll()
|
|
))
|
|
])
|
|
}
|
|
, 200
|
|
)
|
|
|
|
manager.on('add', pushForwards)
|
|
manager.on('remove', pushForwards)
|
|
|
|
return startService()
|
|
.then(awaitServer)
|
|
.then(function() {
|
|
router
|
|
.on(wire.ForwardTestMessage, function(channel, message) {
|
|
var reply = wireutil.reply(options.serial)
|
|
plugin.connect(message)
|
|
.then(function(conn) {
|
|
conn.end()
|
|
push.send([
|
|
channel
|
|
, reply.okay('success')
|
|
])
|
|
})
|
|
.catch(function() {
|
|
push.send([
|
|
channel
|
|
, reply.fail('fail_connect')
|
|
])
|
|
})
|
|
})
|
|
.on(wire.ForwardCreateMessage, function(channel, message) {
|
|
var reply = wireutil.reply(options.serial)
|
|
plugin.createForward(message.id, message)
|
|
.then(function() {
|
|
push.send([
|
|
channel
|
|
, reply.okay('success')
|
|
])
|
|
})
|
|
.catch(function(err) {
|
|
log.error('Reverse port forwarding failed', err.stack)
|
|
push.send([
|
|
channel
|
|
, reply.fail('fail_forward')
|
|
])
|
|
})
|
|
})
|
|
.on(wire.ForwardRemoveMessage, function(channel, message) {
|
|
var reply = wireutil.reply(options.serial)
|
|
plugin.removeForward(message.id)
|
|
.then(function() {
|
|
push.send([
|
|
channel
|
|
, reply.okay('success')
|
|
])
|
|
})
|
|
.catch(function(err) {
|
|
log.error('Reverse port unforwarding failed', err.stack)
|
|
push.send([
|
|
channel
|
|
, reply.fail('fail')
|
|
])
|
|
})
|
|
})
|
|
})
|
|
.return(plugin)
|
|
})
|