• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (C) 2024 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import logging
17import argparse
18import http.server
19import mimetypes
20import os
21import socket
22import socketserver
23import threading
24import time
25import urllib
26import webbrowser
27import signal
28
29logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
30
31
32class StaticFileServerHandler(http.server.SimpleHTTPRequestHandler):
33    def do_GET(self):
34        if self.path == '/get_filename':
35            self.handle_get_filename()
36        elif self.path.startswith('/download'):
37            self.handle_download()
38        else:
39            super().do_GET()
40
41    def guess_type(self, path):
42        base, ext = os.path.splitext(path)
43        mime_type = mimetypes.guess_type(path)[0] or 'application/octet-stream'
44        if ext.lower() == '.js':
45            mime_type = 'application/javascript'
46        return mime_type
47
48    def handle_download(self):
49        query_params = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query)
50        filename = query_params.get('filename', [None])[0]
51        if filename:
52            file_to_load = os.path.join(os.path.dirname(self.server.file_to_load), filename)
53            if os.path.exists(file_to_load):
54                file_to_load = os.path.abspath(file_to_load)
55                self.send_response(200)
56                self.send_header('Content-Type', 'application/octet-stream')
57                self.send_header('Content-Disposition', f'attachment; filename="{filename}"')
58                self.end_headers()
59
60                with open(file_to_load, 'rb') as file:
61                    self.wfile.write(file.read())
62            else:
63                self.send_error(404, "File not found")
64        else:
65            self.send_error(400, "Filename parameter is required")
66
67    def handle_get_filename(self):
68        filename = os.path.basename(self.server.file_to_load)
69        self.send_response(200)
70        self.send_header('Content-Type', 'text/plain')
71        self.end_headers()
72        self.wfile.write(filename.encode('utf-8'))
73
74
75class SimpleServer(socketserver.ThreadingTCPServer):
76    allow_reuse_address = True
77
78    def __init__(self, server_address, RequestHandlerClass, file_to_load):
79        self.file_to_load = file_to_load
80        super().__init__(server_address, RequestHandlerClass)
81
82
83def open_webpage(url):
84    webbrowser.open_new_tab(url)
85
86
87def start_server_with_webpage_opening():
88    parser = argparse.ArgumentParser(description="Start a simple HTTP server.")
89    parser.add_argument('--port', '-p', type=int, default=9000, help='Specify the port number.')
90    parser.add_argument('--file', type=str, help='Specify a file to handle.')
91    args = parser.parse_args()
92
93    if not args.file:
94        logging.error("No file specified using --file option.")
95        return
96
97    if not os.path.exists(args.file):
98        logging.error(f"The file '{args.file}' does not exist.")
99        return
100
101    server_address = ('', args.port)
102    with SimpleServer(server_address, StaticFileServerHandler, args.file) as httpd:
103        logging.info(f"Serving HTTP on port {args.port}...")
104        logging.info(f"Loading file from path: {args.file}")
105        server_thread = threading.Thread(target=httpd.serve_forever)
106        server_thread.daemon = True
107        server_thread.start()
108        time.sleep(1)
109        url = f'http://localhost:{args.port}/index.html'
110        open_webpage(url)
111        time.sleep(2)
112        httpd.shutdown()
113        httpd.server_close()
114
115
116if __name__ == '__main__':
117    start_server_with_webpage_opening()
118