I have a bunch of files without extensions, so http.server is serving them all as application/octet-stream
and this is causing problems...
Rather than giving them extensions, I would like a way to define a dictionary that would be filename -> mimetype. And then have GET requests to http.server look up the filename in that dictionary object, and set the Content-type
header to its value.
Is there a way to do this?
You can use the extensions_map attribute of SimpleHTTPRequestHandler
.
When adding a mapping from the empty string to your preferred type, it will serve files without extension as that.
from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
def run():
Handler = SimpleHTTPRequestHandler
Handler.extensions_map = {'': 'text/plain'}
with TCPServer(('', 8000), Handler) as httpd:
httpd.serve_forever()
if __name__ == '__main__':
run()
Here's the output of curl -I localhost:8000/myfile
(with a corresponding file put in the appropriate place).
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.11.7
Date: Tue, 16 Jan 2024 23:35:28 GMT
Content-type: text/plain
Content-Length: 26
Last-Modified: Tue, 16 Jan 2024 23:33:49 GMT
If you want to serve different types and really map from individual file names to the types, it's somewhat more involved.
You have to subclass and overwrite the behaviour of SimpleHTTPRequestHandler.guess_type
. Start reading here.
Should probably be something like this:
def guess_type(self, path):
from pathlib import Path
path_name = Path(path).name
return self.extensions_map.get(path_name, 'application/octet-stream')
This is a sledgehammer job, and I suggest you don't use this example as is and do some sensible error handling instead. You get the idea.