Customized Static File Server in Python
2024-02-12 #web server, #web dev, 83 Words 0 Min

Frequently, I find myself needing to launch a local static file server, primarily for debugging frontend code. The default choice is the command:

python3 -m http.server

Since Python is widely deployed, there's no need for installation. However, this method lacks support for many configurations. Particularly, when encountering strict browser security rules, I often need to manipulate the response headers to bypass them. Unfortunately, the vanilla HTTP server doesn't provide this capability.

Here's my slightly modified version of the static file server that can inject custom headers:

from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse
import pathlib
import mimetypes

cur = pathlib.Path().resolve()

print(cur)

extra_headers = [('Cross-Origin-Opener-Policy', 'same-origin'),
                 ('Cross-Origin-Resource-Policy', 'same-site'),
                 ('Cross-Origin-Embedder-Policy', 'require-corp')]

class FileHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        parsed = urlparse(self.path)
        query_string = parsed.query
        path = cur.joinpath('.'+parsed.path)
        type = mimetypes.guess_type(path.as_uri())
        try:
            file = open(path, "rb")
        except FileNotFoundError:
            self.send_response(404)
            self.end_headers()
            self.wfile.write(bytes("Not Found!", "utf-8"))
            print(path, 'not found')
        else:
            with file:
                self.send_response(200)
                if type[0] != None:
                    self.send_header('Content-Type', type[0])
                if type[1] != None:
                    self.send_header('Content-Encoding', type[1])
                for extra_header in extra_headers:
                    self.send_header(extra_header[0], extra_header[1])
                
                self.end_headers()
                while (byte := file.read()):
                    self.wfile.write(byte)
                print('served', path)
        

httpd = HTTPServer(('localhost', 10000), FileHandler)
httpd.serve_forever()
Leave a Comment on Github