Improve docker HTTP console

Fix #816
pull/830/head
Julien Duponchelle 8 years ago
parent 846041a59c
commit c4327ec74c
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8

@ -434,15 +434,20 @@ class DockerVM(BaseNode):
@asyncio.coroutine
def _start_http(self):
"""
Start an HTTP tunnel to container localhost
Start an HTTP tunnel to container localhost. It's not perfect
but the only way we have to inject network packet is using nc.
"""
log.debug("Forward HTTP for %s to %d", self.name, self._console_http_port)
command = ["docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "nc", "127.0.0.1", str(self._console_http_port)]
# We replace the port in the server answer otherwise some link could be broken
# We replace host and port in the server answer otherwise some link could be broken
server = AsyncioRawCommandServer(command, replaces=[
(
'{}'.format(self._console_http_port).encode(),
'{}'.format(self.console).encode(),
'://127.0.0.1'.encode(), # {{HOST}} mean client host
'://{{HOST}}'.encode(),
),
(
':{}'.format(self._console_http_port).encode(),
':{}'.format(self.console).encode(),
)
])
self._telnet_servers.append((yield from asyncio.start_server(server.run, self._manager.port_manager.console_host, self.console)))

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
import copy
import asyncio
import asyncio.subprocess
@ -59,6 +60,15 @@ class AsyncioRawCommandServer:
@asyncio.coroutine
def _process(self, network_reader, network_writer, process_reader, process_writer):
replaces = []
# Server host from the client point of view
host = network_writer.transport.get_extra_info("sockname")[0]
for replace in self._replaces:
if b'{{HOST}}' in replace[1]:
replaces.append((replace[0], replace[1].replace(b'{{HOST}}', host.encode()), ))
else:
replaces.append((replace[0], replace[1], ))
network_read = asyncio.async(network_reader.read(READ_SIZE))
reader_read = asyncio.async(process_reader.read(READ_SIZE))
timeout = 30
@ -89,7 +99,7 @@ class AsyncioRawCommandServer:
reader_read = asyncio.async(process_reader.read(READ_SIZE))
for replace in self._replaces:
for replace in replaces:
data = data.replace(replace[0], replace[1])
timeout = 2 # We reduce the timeout when the process start to return stuff to avoid problem with server not closing the connection
@ -102,8 +112,8 @@ if __name__ == '__main__':
loop = asyncio.get_event_loop()
command = ["nc", "localhost", "80"]
server = AsyncioRawCommandServer(command)
coro = asyncio.start_server(server.run, '127.0.0.1', 4444, loop=loop)
server = AsyncioRawCommandServer(command, replaces=[(b"work", b"{{HOST}}", )])
coro = asyncio.start_server(server.run, '0.0.0.0', 4444, loop=loop)
s = loop.run_until_complete(coro)
try:

Loading…
Cancel
Save