import http.server import http.client import yaml import docker from socketserver import ThreadingMixIn import threading # Define the target server to proxy requests to class ProxyHandler(http.server.BaseHTTPRequestHandler): def __init__(self, configuration, docker_client): self.configuration = configuration self.docker_client = docker_client def __call__(self, *args, **kwargs): """Handle a request.""" super().__init__(*args, **kwargs) def log_message(self, format, *args): pass def do_GET(self): self.handle_request('GET') def do_POST(self): self.handle_request('POST') def do_PUT(self): self.handle_request('PUT') def do_DELETE(self): self.handle_request('DELETE') def do_HEAD(self): self.handle_request('HEAD') def handle_request(self, method): #print(self.headers.get('Host').split(":")[0]) proxy_host_configuration = next(filter(lambda host: host['domain'] == self.headers.get('Host').split(":")[0], self.configuration['proxy_hosts'])) starting = False for container in proxy_host_configuration['containers']: container_object = self.docker_client.containers.list(all=True, filters = { 'name' : container['container_name'] })[0] if (container_object.status != 'running'): print("starting container: {0}".format(container['container_name'])) container_object.start() starting = True if (starting == True): self.send_response(201) self.end_headers() self.wfile.write(str.encode("starting container: {0}".format(container['container_name']))) conn.close() # Open a connection to the target server conn = http.client.HTTPConnection(proxy_host_configuration['proxy_host'], proxy_host_configuration['proxy_port']) conn.request(method, self.path, headers=self.headers) response = conn.getresponse() #print(response.status) self.send_response(response.status) #self.send_header('host', proxy_host_configuration['container_name']) for header, value in response.getheaders(): self.send_header(header, value) self.end_headers() if (response.status != 301): self.wfile.write(response.getcode()) conn.close() class ThreadedHTTPServer(ThreadingMixIn, http.server.HTTPServer): """Handle requests in a separate thread.""" if __name__ == '__main__': with open('config.yml', 'r') as file: configuration = yaml.safe_load(file) docker_client = docker.from_env() # Start the reverse proxy server on port 8888 server_address = ('', configuration['proxy_port']) proxy_handler = ProxyHandler(configuration, docker_client) httpd = ThreadedHTTPServer(server_address, proxy_handler) print('Reverse proxy server running on port 8888...') httpd.serve_forever()