2022-07-18 23:59:14 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2019-11-10 21:42:04 +00:00
|
|
|
import http.server
|
2016-05-16 23:48:31 +00:00
|
|
|
import threading
|
|
|
|
import ssl
|
2016-06-04 07:13:38 +00:00
|
|
|
import os
|
|
|
|
import sys
|
2019-11-10 21:42:04 +00:00
|
|
|
from http.server import BaseHTTPRequestHandler
|
2020-11-15 23:42:28 +00:00
|
|
|
from time import sleep
|
2016-12-15 07:28:00 +00:00
|
|
|
from cme.helpers.logger import highlight
|
2016-06-04 05:42:26 +00:00
|
|
|
from cme.logger import CMEAdapter
|
2016-05-16 23:48:31 +00:00
|
|
|
|
2023-03-30 20:36:58 +00:00
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
class RequestHandler(BaseHTTPRequestHandler):
|
|
|
|
|
|
|
|
def log_message(self, format, *args):
|
2023-03-30 20:36:58 +00:00
|
|
|
server_logger = CMEAdapter(extra={'module_name': self.server.module.name.upper(), 'host': self.client_address[0]})
|
|
|
|
server_logger.display("- - %s" % (format % args))
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
def do_GET(self):
|
|
|
|
if hasattr(self.server.module, 'on_request'):
|
2023-03-30 20:36:58 +00:00
|
|
|
server_logger = CMEAdapter(extra={'module_name': self.server.module.name.upper(), 'host': self.client_address[0]})
|
2016-05-16 23:48:31 +00:00
|
|
|
self.server.context.log = server_logger
|
2016-12-15 07:28:00 +00:00
|
|
|
self.server.module.on_request(self.server.context, self)
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
def do_POST(self):
|
|
|
|
if hasattr(self.server.module, 'on_response'):
|
2023-03-30 20:36:58 +00:00
|
|
|
server_logger = CMEAdapter(extra={'module_name': self.server.module.name.upper(), 'host': self.client_address[0]})
|
2016-05-16 23:48:31 +00:00
|
|
|
self.server.context.log = server_logger
|
|
|
|
self.server.module.on_response(self.server.context, self)
|
|
|
|
|
|
|
|
def stop_tracking_host(self):
|
2023-03-30 20:36:58 +00:00
|
|
|
"""
|
|
|
|
This gets called when a module has finshed executing, removes the host from the connection tracker list
|
|
|
|
"""
|
2016-05-16 23:48:31 +00:00
|
|
|
try:
|
|
|
|
self.server.hosts.remove(self.client_address[0])
|
2017-03-27 21:09:36 +00:00
|
|
|
if hasattr(self.server.module, 'on_shutdown'):
|
|
|
|
self.server.module.on_shutdown(self.server.context, self.server.connection)
|
2016-05-16 23:48:31 +00:00
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
|
2023-03-30 20:36:58 +00:00
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
class CMEServer(threading.Thread):
|
|
|
|
|
2023-04-12 04:25:38 +00:00
|
|
|
def __init__(self, module, context, logger, srv_host, port, server_type="https"):
|
2016-05-16 23:48:31 +00:00
|
|
|
try:
|
|
|
|
threading.Thread.__init__(self)
|
|
|
|
|
2019-11-12 19:42:45 +00:00
|
|
|
self.server = http.server.HTTPServer((srv_host, int(port)), RequestHandler)
|
2023-03-30 20:36:58 +00:00
|
|
|
self.server.hosts = []
|
|
|
|
self.server.module = module
|
2016-05-16 23:48:31 +00:00
|
|
|
self.server.context = context
|
2023-04-12 04:25:38 +00:00
|
|
|
self.server.log = CMEAdapter(extra={"module_name": self.server.module.name.upper()})
|
|
|
|
self.cert_path = os.path.join(os.path.expanduser("~/.cme"), "cme.pem")
|
2016-12-15 07:28:00 +00:00
|
|
|
self.server.track_host = self.track_host
|
2016-05-16 23:48:31 +00:00
|
|
|
|
2023-03-30 03:59:22 +00:00
|
|
|
logger.debug('CME server type: ' + server_type)
|
2016-05-16 23:48:31 +00:00
|
|
|
if server_type == 'https':
|
2016-06-04 07:13:38 +00:00
|
|
|
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=self.cert_path, server_side=True)
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
except Exception as e:
|
2016-06-04 07:13:38 +00:00
|
|
|
errno, message = e.args
|
|
|
|
if errno == 98 and message == 'Address already in use':
|
2023-04-12 04:25:38 +00:00
|
|
|
logger.error(
|
|
|
|
"Error starting HTTP(S) server: the port is already in use, try specifying a diffrent port using --server-port"
|
|
|
|
)
|
2016-06-04 07:13:38 +00:00
|
|
|
else:
|
2023-04-12 04:25:38 +00:00
|
|
|
logger.error(f"Error starting HTTP(S) server: {message}")
|
2016-06-04 07:13:38 +00:00
|
|
|
|
|
|
|
sys.exit(1)
|
2016-05-16 23:48:31 +00:00
|
|
|
|
|
|
|
def base_server(self):
|
|
|
|
return self.server
|
|
|
|
|
2016-09-12 06:52:50 +00:00
|
|
|
def track_host(self, host_ip):
|
|
|
|
self.server.hosts.append(host_ip)
|
|
|
|
|
2016-05-16 23:48:31 +00:00
|
|
|
def run(self):
|
2016-12-15 07:28:00 +00:00
|
|
|
try:
|
2016-05-16 23:48:31 +00:00
|
|
|
self.server.serve_forever()
|
2016-12-15 07:28:00 +00:00
|
|
|
except:
|
2016-05-16 23:48:31 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
def shutdown(self):
|
|
|
|
try:
|
|
|
|
while len(self.server.hosts) > 0:
|
2023-04-12 04:25:38 +00:00
|
|
|
self.server.log.info(f"Waiting on {highlight(len(self.server.hosts))} host(s)")
|
2016-05-16 23:48:31 +00:00
|
|
|
sleep(15)
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# shut down the server/socket
|
|
|
|
self.server.shutdown()
|
|
|
|
self.server.socket.close()
|
|
|
|
self.server.server_close()
|
|
|
|
|
|
|
|
# make sure all the threads are killed
|
|
|
|
for thread in threading.enumerate():
|
2021-01-29 23:15:03 +00:00
|
|
|
if thread.is_alive():
|
2016-05-16 23:48:31 +00:00
|
|
|
try:
|
2020-01-18 12:20:10 +00:00
|
|
|
thread._stop()
|
2016-05-16 23:48:31 +00:00
|
|
|
except:
|
|
|
|
pass
|