PY_PROXY/app.py
2025-01-21 13:02:38 +01:00

88 lines
3.3 KiB
Python

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.send_header('Content-Type', 'text/plain')
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
self.send_header('refresh', proxy_host_configuration['proxy_timeout_seconds'])
self.end_headers()
self.wfile.write(bytes("starting container: {0} waiting for {1}s".format(container['container_name'], proxy_host_configuration['proxy_timeout_seconds']),"utf-8"))
return
# 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()
self.send_response(response.status)
self.send_header('host', proxy_host_configuration['proxy_host'])
for header, value in response.getheaders():
self.send_header(header, value)
self.end_headers()
self.wfile.write(response.read())
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 {0}...'.format(configuration['proxy_port']))
httpd.serve_forever()