1# 2# SPDX-License-Identifier: MIT 3# 4 5import http.server 6import multiprocessing 7import os 8import traceback 9import signal 10from socketserver import ThreadingMixIn 11 12class HTTPServer(ThreadingMixIn, http.server.HTTPServer): 13 14 def server_start(self, root_dir, logger): 15 os.chdir(root_dir) 16 self.serve_forever() 17 18class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler): 19 20 def log_message(self, format_str, *args): 21 pass 22 23class HTTPService(object): 24 25 def __init__(self, root_dir, host='', port=0, logger=None): 26 self.root_dir = root_dir 27 self.host = host 28 self.port = port 29 self.logger = logger 30 31 def start(self): 32 if not os.path.exists(self.root_dir): 33 self.logger.info("Not starting HTTPService for directory %s which doesn't exist" % (self.root_dir)) 34 return 35 36 self.server = HTTPServer((self.host, self.port), HTTPRequestHandler) 37 if self.port == 0: 38 self.port = self.server.server_port 39 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger]) 40 41 # The signal handler from testimage.bbclass can cause deadlocks here 42 # if the HTTPServer is terminated before it can restore the standard 43 #signal behaviour 44 orig = signal.getsignal(signal.SIGTERM) 45 signal.signal(signal.SIGTERM, signal.SIG_DFL) 46 self.process.start() 47 signal.signal(signal.SIGTERM, orig) 48 49 if self.logger: 50 self.logger.info("Started HTTPService on %s:%s" % (self.host, self.port)) 51 52 53 def stop(self): 54 if hasattr(self, "server"): 55 self.server.server_close() 56 if hasattr(self, "process"): 57 self.process.terminate() 58 self.process.join() 59 if self.logger: 60 self.logger.info("Stopped HTTPService on %s:%s" % (self.host, self.port)) 61 62