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