def run(): eventlet.debug.hub_prevent_multiple_readers(False) eventlet.monkey_patch(socket=True) logging.basicConfig( format="%(asctime)s %(levelname) 7s %(module)s: %(message)s", level=logging.DEBUG) parser = argparse.ArgumentParser(description='Localtunnel server daemon') parser.add_argument( 'frontend', metavar='frontend_listener', type=str, help='hostname to run frontend on (default: vcap.me:8000)', default='vcap.me:8000') parser.add_argument( 'backend', metavar='backend_listener', type=str, help='port or address to run backend server on (default: 8001)', default='8001') args = parser.parse_args() frontend_address, frontend_hostname = util.parse_address(args.frontend) backend_address, backend_hostname = util.parse_address(args.backend) logging.info("starting frontend on {0} for {1}...".format( frontend_address, frontend_hostname)) logging.info("starting backend on {0}...".format(backend_address)) Tunnel.backend_port = backend_address[1] if frontend_address[1] == 80: Tunnel.domain_suffix = frontend_hostname else: Tunnel.domain_suffix = ":".join( [frontend_hostname, str(frontend_address[1])]) stats_key = os.environ.get('STATHAT_EZKEY', None) if stats_key: metrics.run_reporter(stats_key) frontend_listener = eventlet.listen(frontend_address) backend_listener = eventlet.listen(backend_address) try: Tunnel.schedule_idle_scan() pool = eventlet.greenpool.GreenPool(size=2) pool.spawn_n(eventlet.serve, frontend_listener, frontend.connection_handler) pool.spawn_n(eventlet.serve, backend_listener, backend.connection_handler) pool.waitall() except KeyboardInterrupt: pass
def run(): eventlet.debug.hub_prevent_multiple_readers(False) eventlet.monkey_patch(socket=True) logging.basicConfig( format="%(asctime)s %(levelname) 7s %(module)s: %(message)s", level=logging.DEBUG) parser = argparse.ArgumentParser(description='Localtunnel server daemon') parser.add_argument('frontend_port', metavar='frontend_port', type=int, help='port to run public frontend', default=8000) parser.add_argument('backend_port', metavar='backend_port', type=int, help='port to run backend server', default=8001) parser.add_argument( '-d', '--domainpart', type=int, help='domain part (from the right) to extract tunnel name') args = parser.parse_args() logging.info("starting frontend on {0}...".format(args.frontend_port)) logging.info("starting backend on {0}...".format(args.backend_port)) Tunnel.backend_port = args.backend_port if args.domainpart: Tunnel.domain_part = args.domainpart stats_key = os.environ.get('STATHAT_EZKEY', None) if stats_key: metrics.run_reporter(stats_key) frontend_listener = eventlet.listen(('0.0.0.0', args.frontend_port)) backend_listener = eventlet.listen(('0.0.0.0', args.backend_port)) try: Tunnel.schedule_idle_scan() pool = eventlet.greenpool.GreenPool(size=2) pool.spawn_n(eventlet.serve, frontend_listener, frontend.connection_handler) pool.spawn_n(eventlet.serve, backend_listener, backend.connection_handler) pool.waitall() except KeyboardInterrupt: pass
def run(): eventlet.debug.hub_prevent_multiple_readers(False) eventlet.monkey_patch(socket=True) logging.basicConfig(format="%(asctime)s %(levelname) 7s %(module)s: %(message)s", level=logging.DEBUG) parser = argparse.ArgumentParser(description="Localtunnel server daemon") parser.add_argument( "frontend", metavar="frontend_listener", type=str, help="hostname to run frontend on (default: vcap.me:8000)", default="vcap.me:8000", ) parser.add_argument( "backend", metavar="backend_listener", type=str, help="port or address to run backend server on (default: 8001)", default="8001", ) args = parser.parse_args() frontend_address, frontend_hostname = util.parse_address(args.frontend) backend_address, backend_hostname = util.parse_address(args.backend) logging.info("starting frontend on {0} for {1}...".format(frontend_address, frontend_hostname)) logging.info("starting backend on {0}...".format(backend_address)) Tunnel.backend_port = backend_address[1] if frontend_address[1] == 80: Tunnel.domain_suffix = frontend_hostname else: Tunnel.domain_suffix = ":".join([frontend_hostname, str(frontend_address[1])]) stats_key = os.environ.get("STATHAT_EZKEY", None) if stats_key: metrics.run_reporter(stats_key) frontend_listener = eventlet.listen(frontend_address) backend_listener = eventlet.listen(backend_address) try: Tunnel.schedule_idle_scan() pool = eventlet.greenpool.GreenPool(size=2) pool.spawn_n(eventlet.serve, frontend_listener, frontend.connection_handler) pool.spawn_n(eventlet.serve, backend_listener, backend.connection_handler) pool.waitall() except KeyboardInterrupt: pass
def handle_proxy_request(socket, request): try: tunnel = Tunnel.get_by_proxy_request(request) except RuntimeError, e: protocol.send_message(socket, protocol.error_reply('notavailable')) socket.close() return
def connection_handler(socket, address): hostname = peek_http_host(socket) if not hostname: send_http_error(socket, 'No hostname', '400 Bad Request') return if hostname == Tunnel.domain_suffix: meta.server.process_request((socket, address)) return tunnel = Tunnel.get_by_hostname(hostname) if not tunnel: send_http_error(socket, 'No tunnel for {0}'.format(hostname), '410 Gone') return conn, proxy_used = tunnel.pop_proxy_conn(timeout=2) if not conn: send_http_error(socket, 'No proxy connections', '502 Bad Gateway') return protocol.send_message(conn, protocol.proxy_reply()) pool = util.join_sockets(conn, socket) proxy_used.send(pool) logging.debug("popped connection:\"{0}\" for frontend:\"{1}\"".format( tunnel.name, hostname)) pool.waitall()
def connection_handler(socket, address): hostname = peek_http_host(socket) if not hostname: send_http_error(socket, "No hostname", "400 Bad Request") return if hostname == Tunnel.domain_suffix: meta.server.process_request((socket, address)) return tunnel = Tunnel.get_by_hostname(hostname) if not tunnel: send_http_error(socket, "No tunnel for {0}".format(hostname), "410 Gone") return conn, proxy_used = tunnel.pop_proxy_conn(timeout=2) if not conn: send_http_error(socket, "No proxy connections", "502 Bad Gateway") return protocol.send_message(conn, protocol.proxy_reply()) pool = util.join_sockets(conn, socket) proxy_used.send(pool) logging.debug('popped connection:"{0}" for frontend:"{1}"'.format(tunnel.name, hostname)) pool.waitall()
def test_get_by_hostname(self): Tunnel.domain_suffix = 'bar' tunnel = Tunnel.create(dict(name='foo', client='Test-Client')) self.assertTrue(Tunnel.get_by_hostname('foo.bar')) self.assertTrue(Tunnel.get_by_hostname('xxx.foo.bar')) self.assertFalse(Tunnel.get_by_hostname('foo.bar.bar')) tunnel.destroy() Tunnel.domain_suffix = 'foo.bar' tunnel = Tunnel.create(dict(name='hello', client='Test-Client')) self.assertTrue(Tunnel.get_by_hostname('hello.foo.bar')) self.assertTrue(Tunnel.get_by_hostname('world.hello.foo.bar')) self.assertFalse(Tunnel.get_by_hostname('foo.bar')) self.assertFalse(Tunnel.get_by_hostname('bar')) self.assertFalse(Tunnel.get_by_hostname('hello.world.foo.bar')) tunnel.destroy() Tunnel.domain_suffix = None
def test_get_by_hostname(self): Tunnel.domain_suffix = "bar" tunnel = Tunnel.create(dict(name="foo", client="Test-Client")) self.assertTrue(Tunnel.get_by_hostname("foo.bar")) self.assertTrue(Tunnel.get_by_hostname("xxx.foo.bar")) self.assertFalse(Tunnel.get_by_hostname("foo.bar.bar")) tunnel.destroy() Tunnel.domain_suffix = "foo.bar" tunnel = Tunnel.create(dict(name="hello", client="Test-Client")) self.assertTrue(Tunnel.get_by_hostname("hello.foo.bar")) self.assertTrue(Tunnel.get_by_hostname("world.hello.foo.bar")) self.assertFalse(Tunnel.get_by_hostname("foo.bar")) self.assertFalse(Tunnel.get_by_hostname("bar")) self.assertFalse(Tunnel.get_by_hostname("hello.world.foo.bar")) tunnel.destroy() Tunnel.domain_suffix = None
def run(): eventlet.debug.hub_prevent_multiple_readers(False) eventlet.monkey_patch(socket=True) logging.basicConfig( format="%(asctime)s %(levelname) 7s %(module)s: %(message)s", level=logging.DEBUG) parser = argparse.ArgumentParser(description='Localtunnel server daemon') parser.add_argument('frontend_port', metavar='frontend_port', type=int, help='port to run public frontend', default=8000) parser.add_argument('backend_port', metavar='backend_port', type=int, help='port to run backend server', default=8001) parser.add_argument('-d', '--domainpart', type=int, help='domain part (from the right) to extract tunnel name') args = parser.parse_args() logging.info("starting frontend on {0}...".format(args.frontend_port)) logging.info("starting backend on {0}...".format(args.backend_port)) Tunnel.backend_port = args.backend_port if args.domainpart: Tunnel.domain_part = args.domainpart stats_key = os.environ.get('STATHAT_EZKEY', None) if stats_key: metrics.run_reporter(stats_key) frontend_listener = eventlet.listen(('0.0.0.0', args.frontend_port)) backend_listener = eventlet.listen(('0.0.0.0', args.backend_port)) try: Tunnel.schedule_idle_scan() pool = eventlet.greenpool.GreenPool(size=2) pool.spawn_n(eventlet.serve, frontend_listener, frontend.connection_handler) pool.spawn_n(eventlet.serve, backend_listener, backend.connection_handler) pool.waitall() except KeyboardInterrupt: pass
def connection_handler(socket, address): host = peek_http_host(socket) hostname = host.split(':')[0] if not hostname: logging.debug("!no hostname, closing") socket.close() return if hostname.startswith('_version.'): send_http_response(socket, __version__) socket.close() logging.debug("version request from {0}".format(address[0])) return if hostname.startswith('_backend.'): port = os.environ.get('DOTCLOUD_SERVER_BACKEND_PORT', Tunnel.backend_port) send_http_response(socket, port) socket.close() return if hostname.startswith('_metrics.'): content = json.dumps(metrics.dump_metrics(), sort_keys=True, indent=2, separators=(',', ': ')) send_http_response(socket, content) socket.close() logging.debug("metrics request from {0}".format(address[0])) return tunnel = Tunnel.get_by_hostname(hostname) if not tunnel: logging.debug("!no tunnel, closing ({0})".format(hostname)) socket.close() return conn, proxy_used = tunnel.pop_proxy_conn(timeout=2) if not conn: logging.debug("!no proxy connection, closing") socket.close() return protocol.send_message(conn, protocol.proxy_reply()) pool = util.join_sockets(conn, socket) proxy_used.send(pool) logging.debug("popped connection:\"{0}\" for frontend:\"{1}\"".format( tunnel.name, hostname)) pool.waitall()
def connection_handler(socket, address): host = peek_http_host(socket) hostname = host.split(':')[0] if not hostname: logging.debug("!no hostname, closing") socket.close() return if hostname.startswith('_version.'): send_http_response(socket, __version__) socket.close() logging.debug("version request from {0}".format(address[0])) return if hostname.startswith('_backend.'): port = os.environ.get('DOTCLOUD_SERVER_BACKEND_PORT', Tunnel.backend_port) send_http_response(socket, port) socket.close() return if hostname.startswith('_metrics.'): content = json.dumps(metrics.dump_metrics(), sort_keys=True, indent=2, separators=(',', ': ')) send_http_response(socket, content) socket.close() logging.debug("metrics request from {0}".format(address[0])) return tunnel = Tunnel.get_by_hostname(hostname) if not tunnel: logging.debug("!no tunnel, closing ({0})".format( hostname)) socket.close() return conn, proxy_used = tunnel.pop_proxy_conn(timeout=2) if not conn: logging.debug("!no proxy connection, closing") socket.close() return protocol.send_message(conn, protocol.proxy_reply()) pool = util.join_sockets(conn, socket) proxy_used.send(pool) logging.debug("popped connection:\"{0}\" for frontend:\"{1}\"".format( tunnel.name, hostname)) pool.waitall()
def test_tunnel_callbacks(self): Tunnel.domain_suffix = 'bar' self.create_called = False self.destroy_called = False def create_callback(tunnel): self.assertEquals(tunnel.name, "foo") self.create_called = True def destroy_callback(tunnel): self.assertEquals(tunnel.name, "foo") self.destroy_called = True Tunnel.create_callback = create_callback Tunnel.destroy_callback = destroy_callback tunnel = Tunnel.create(dict(name='foo', client='Test-Client')) tunnel.destroy() self.assertTrue(self.create_called) self.assertTrue(self.destroy_called)