def run(): 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)) if args.domainpart: Tunnel.domain_part = args.domainpart Tunnel.backend_port = args.backend_port frontend = gevent.server.StreamServer( ('0.0.0.0', args.frontend_port), frontend_handler) backend = gevent.server.StreamServer( ('0.0.0.0', args.backend_port), backend_handler) try: Tunnel.schedule_cleanup() gevent.joinall(group([ gevent.spawn(frontend.serve_forever), gevent.spawn(backend.serve_forever), ])) 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: Tunnel.stats = util.StatHat(stats_key, 'localtunnel.') logging.info("starting stats session with {0}".format(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_handler) pool.spawn_n(eventlet.serve, backend_listener, backend_handler) pool.waitall() except KeyboardInterrupt: pass
def handle_proxy(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 run(): 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)) if args.domainpart: Tunnel.domain_part = args.domainpart Tunnel.backend_port = args.backend_port frontend = gevent.server.StreamServer(('0.0.0.0', args.frontend_port), frontend_handler) backend = gevent.server.StreamServer(('0.0.0.0', args.backend_port), backend_handler) try: Tunnel.schedule_cleanup() gevent.joinall( group([ gevent.spawn(frontend.serve_forever), gevent.spawn(backend.serve_forever), ])) 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: Tunnel.stats = util.StatHat(stats_key, 'localtunnel.') logging.info("starting stats session with {0}".format(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_handler) pool.spawn_n(eventlet.serve, backend_listener, backend_handler) pool.waitall() except KeyboardInterrupt: pass
def backend_handler(socket, address): header = recv_json(socket) if not header: logging.debug("!backend: no header, closing") socket.close() return try: tunnel = Tunnel.get_by_header(header) except RuntimeError, e: socket.sendall("{0}\n".format(json.dumps({"error": str(e)}))) socket.close() return
def backend_handler(socket, address): header = recv_json(socket) if not header: logging.debug("!backend: no header, closing") socket.close() return try: tunnel = Tunnel.get_by_header(header) except RuntimeError, e: socket.sendall("{0}\n".format( json.dumps({"error": str(e)}))) socket.close() return
def frontend_handler(socket, address): hostname = '' hostheader = re.compile('host: ([^\(\);:,<>]+)', re.I) # Peek up to 512 bytes into data for the Host header for n in [128, 256, 512]: bytes = socket.recv(n, MSG_PEEK) if not bytes: socket.close() return for line in bytes.split('\r\n'): match = hostheader.match(line) if match: hostname = match.group(1) if hostname: break hostname = hostname.split(':')[0] if not hostname: logging.debug("!frontend: no hostname, closing") socket.close() return if hostname.startswith('_version.'): data = """HTTP/1.1 200 OK\r\nContent-Length: {0}\r\nConnection: close\r\n\r\n{1} """.format(len(VERSION), VERSION).strip() socket.sendall(data) socket.close() logging.debug("version request") return if hostname.startswith('_backend.'): port = os.environ.get('DOTCLOUD_SERVER_BACKEND_PORT', Tunnel.backend_port) data = """HTTP/1.1 200 OK\r\nContent-Length: {0}\r\nConnection: close\r\n\r\n{1} """.format(len(str(port)), port).strip() socket.sendall(data) socket.close() return tunnel = Tunnel.get_by_hostname(hostname) if not tunnel: logging.debug("!frontend: no tunnel, closing ({0})".format(hostname)) socket.close() return conn = tunnel.pop_proxy_backend(timeout=2) if not conn: logging.debug("!frontend: no backend, closing") socket.close() return protocol.send_message(conn, protocol.proxy_reply()) pool = util.join_sockets(conn, socket) logging.debug("popped backend:\"{0}\" for frontend:\"{1}\"".format( tunnel.name, hostname)) pool.waitall()
def frontend_handler(socket, address): hostname = '' hostheader = re.compile('host: ([^\(\);:,<>]+)', re.I) # Peek up to 512 bytes into data for the Host header for n in [128, 256, 512]: bytes = socket.recv(n, MSG_PEEK) if not bytes: socket.close() return for line in bytes.split('\r\n'): match = hostheader.match(line) if match: hostname = match.group(1) if hostname: break hostname = hostname.split(':')[0] if not hostname: logging.debug("!frontend: no hostname, closing") socket.close() return if hostname.startswith('_version.'): data = """HTTP/1.1 200 OK\r\nContent-Length: {0}\r\nConnection: close\r\n\r\n{1} """.format(len(VERSION), VERSION).strip() socket.sendall(data) socket.close() logging.debug("version request") return if hostname.startswith('_backend.'): port = os.environ.get('DOTCLOUD_SERVER_BACKEND_PORT', Tunnel.backend_port) data = """HTTP/1.1 200 OK\r\nContent-Length: {0}\r\nConnection: close\r\n\r\n{1} """.format(len(str(port)), port).strip() socket.sendall(data) socket.close() return tunnel = Tunnel.get_by_hostname(hostname) if not tunnel: logging.debug("!frontend: no tunnel, closing ({0})".format( hostname)) socket.close() return conn = tunnel.pop_proxy_backend(timeout=2) if not conn: logging.debug("!frontend: no backend, closing") socket.close() return protocol.send_message(conn, protocol.proxy_reply()) pool = util.join_sockets(conn, socket) logging.debug("popped backend:\"{0}\" for frontend:\"{1}\"".format( tunnel.name, hostname)) pool.waitall()