Merge pull request #81 from vatesfr/julien-f-direct-consoles

Access directly to consoles without using wsproxy.
This commit is contained in:
Olivier Lambert
2015-09-01 17:58:06 +02:00
4 changed files with 52 additions and 7 deletions

View File

@@ -82,6 +82,7 @@
"make-error": "^1",
"ms": "^0.7.1",
"multikey-hash": "^1.0.1",
"partial-stream": "0.0.0",
"passport": "^0.3.0",
"passport-local": "^1.0.0",
"proxy-http-request": "0.1.0",

View File

@@ -13,6 +13,7 @@ import isArray from 'lodash.isarray'
import isFunction from 'lodash.isfunction'
import map from 'lodash.map'
import pick from 'lodash.pick'
import proxyConsole from './proxy-console'
import proxyRequest from 'proxy-http-request'
import serveStatic from 'serve-static'
import WebSocket from 'ws'
@@ -441,15 +442,16 @@ const setUpConsoleProxy = (webServer, xo) => {
const [, id] = matches
try {
const url = xo.getXAPI(id, ['VM', 'VM-controller']).getVmConsoleUrl(id)
const xapi = xo.getXAPI(id, ['VM', 'VM-controller'])
const vmConsole = xapi.getVmConsole(id)
// FIXME: lost connection due to VM restart is not detected.
webSocketServer.handleUpgrade(req, socket, head, connection => {
wsProxy(connection, url, {
rejectUnauthorized: false
})
proxyConsole(connection, vmConsole, xapi.sessionId)
})
} catch (_) {}
} catch (_) {
console.error(_)
}
})
}

42
src/proxy-console.js Normal file
View File

@@ -0,0 +1,42 @@
import partialStream from 'partial-stream'
import {connect} from 'tls'
import {parse} from 'url'
export default function proxyConsole (ws, vmConsole, sessionId) {
const url = parse(vmConsole.location)
const socket = connect({
host: url.host,
port: url.port || 443,
rejectUnauthorized: false
}, () => {
// Write headers.
socket.write([
`CONNECT ${url.path} HTTP/1.0`,
`Host: ${url.hostname}`,
`Cookie: session_id=${sessionId}`,
'', ''
].join('\r\n'))
socket.pipe(partialStream('\r\n\r\n', headers => {
// TODO: check status code 200.
})).on('data', data => {
// Encode to base 64.
ws.send(data.toString('base64'))
}).on('end', () => {
ws.close()
})
ws
.on('error', () => {
socket.close()
})
.on('message', data => {
// Decode from base 64.
socket.write(new Buffer(data, 'base64'))
})
.on('close', () => {
socket.end()
})
})
}

View File

@@ -591,7 +591,7 @@ export default class Xapi extends XapiBase {
await this.call('VM.destroy', vm.$ref)
}
getVmConsoleUrl (vmId) {
getVmConsole (vmId) {
const vm = this.getObject(vmId)
const console = find(vm.$consoles, { protocol: 'rfb' })
@@ -599,7 +599,7 @@ export default class Xapi extends XapiBase {
throw new Error('no RFB console found')
}
return `${console.location}&session_id=${this.sessionId}`
return console
}
// Returns a stream to the exported VM.