| Brad Bishop | c342db3 | 2019-05-15 21:57:59 -0400 | [diff] [blame^] | 1 | # | 
 | 2 | # SPDX-License-Identifier: MIT | 
 | 3 | # | 
 | 4 |  | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 5 | import http.server | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 6 | import multiprocessing | 
 | 7 | import os | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 8 | import traceback | 
 | 9 | import signal | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 10 | from socketserver import ThreadingMixIn | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 11 |  | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 12 | class HTTPServer(ThreadingMixIn, http.server.HTTPServer): | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 13 |  | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 14 |     def server_start(self, root_dir, logger): | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 15 |         os.chdir(root_dir) | 
 | 16 |         self.serve_forever() | 
 | 17 |  | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 18 | class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler): | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 19 |  | 
 | 20 |     def log_message(self, format_str, *args): | 
 | 21 |         pass | 
 | 22 |  | 
 | 23 | class HTTPService(object): | 
 | 24 |  | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 25 |     def __init__(self, root_dir, host='', logger=None): | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 26 |         self.root_dir = root_dir | 
 | 27 |         self.host = host | 
 | 28 |         self.port = 0 | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 29 |         self.logger = logger | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 30 |  | 
 | 31 |     def start(self): | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 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 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 36 |         self.server = HTTPServer((self.host, self.port), HTTPRequestHandler) | 
 | 37 |         if self.port == 0: | 
 | 38 |             self.port = self.server.server_port | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 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) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 46 |         self.process.start() | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 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 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 52 |  | 
 | 53 |     def stop(self): | 
| Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 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 |  |