blob: 8ce1dd42f495a9f90561ccb5de744317277bf17f [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
Patrick Williams92b42cb2022-09-03 06:53:57 -05002# Copyright OpenEmbedded Contributors
3#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: MIT
5#
6
Patrick Williamsc0f7c042017-02-23 20:41:17 -06007import http.server
Patrick Williamsc124f4f2015-09-15 14:41:29 -05008import multiprocessing
9import os
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080010import traceback
11import signal
Patrick Williamsc0f7c042017-02-23 20:41:17 -060012from socketserver import ThreadingMixIn
Patrick Williamsc124f4f2015-09-15 14:41:29 -050013
Patrick Williamsc0f7c042017-02-23 20:41:17 -060014class HTTPServer(ThreadingMixIn, http.server.HTTPServer):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080016 def server_start(self, root_dir, logger):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017 os.chdir(root_dir)
18 self.serve_forever()
19
Patrick Williamsc0f7c042017-02-23 20:41:17 -060020class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021
22 def log_message(self, format_str, *args):
23 pass
24
25class HTTPService(object):
26
Andrew Geissler82c905d2020-04-13 13:39:40 -050027 def __init__(self, root_dir, host='', port=0, logger=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028 self.root_dir = root_dir
29 self.host = host
Andrew Geissler82c905d2020-04-13 13:39:40 -050030 self.port = port
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080031 self.logger = logger
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032
33 def start(self):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080034 if not os.path.exists(self.root_dir):
35 self.logger.info("Not starting HTTPService for directory %s which doesn't exist" % (self.root_dir))
36 return
37
Patrick Williamsc124f4f2015-09-15 14:41:29 -050038 self.server = HTTPServer((self.host, self.port), HTTPRequestHandler)
39 if self.port == 0:
40 self.port = self.server.server_port
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080041 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger])
42
43 # The signal handler from testimage.bbclass can cause deadlocks here
44 # if the HTTPServer is terminated before it can restore the standard
45 #signal behaviour
46 orig = signal.getsignal(signal.SIGTERM)
47 signal.signal(signal.SIGTERM, signal.SIG_DFL)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050048 self.process.start()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080049 signal.signal(signal.SIGTERM, orig)
50
51 if self.logger:
52 self.logger.info("Started HTTPService on %s:%s" % (self.host, self.port))
53
Patrick Williamsc124f4f2015-09-15 14:41:29 -050054
55 def stop(self):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080056 if hasattr(self, "server"):
57 self.server.server_close()
58 if hasattr(self, "process"):
59 self.process.terminate()
60 self.process.join()
61 if self.logger:
62 self.logger.info("Stopped HTTPService on %s:%s" % (self.host, self.port))
63