xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oeqa/utils/httpserver.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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        def handle_error(self, request, client_address):
42            import traceback
43            exception = traceback.format_exc()
44            self.logger.warn("Exception when handling %s: %s" % (request, exception))
45        self.server.handle_error = handle_error
46
47        # The signal handler from testimage.bbclass can cause deadlocks here
48        # if the HTTPServer is terminated before it can restore the standard
49        #signal behaviour
50        orig = signal.getsignal(signal.SIGTERM)
51        signal.signal(signal.SIGTERM, signal.SIG_DFL)
52        self.process.start()
53        signal.signal(signal.SIGTERM, orig)
54
55        if self.logger:
56            self.logger.info("Started HTTPService on %s:%s" % (self.host, self.port))
57
58
59    def stop(self):
60        if hasattr(self, "server"):
61            self.server.server_close()
62        if hasattr(self, "process"):
63            self.process.terminate()
64            self.process.join()
65        if self.logger:
66            self.logger.info("Stopped HTTPService on %s:%s" % (self.host, self.port))
67
68