The http.server module decides the Content-Type header of a response from the file extension, using the mimetypes database. When the extension is not recognized, it falls back to application/octet-stream, which browsers treat as a download rather than something to display. Files with custom extensions, such as logs, data dumps or configuration written in a project-specific format, are therefore saved to disk instead of being shown.
Create an empty file notes.bin2 in the current directory and start the server:
python -m http.server 8000
curl -I http://127.0.0.1:8000/notes.bin2
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.14.10
Date: Tue, 03 Nov 2026 09:41:47 GMT
Content-type: application/octet-stream
Content-Length: 0
Last-Modified: Tue, 03 Nov 2026 09:24:03 GMT
Since Python 3.15, the --content-type option sets the type used for extensions which are not recognized:
python -m http.server 8000 --content-type text/plain
HTTP/1.0 200 OK
Server: SimpleHTTP Python/3.15.2
Date: Tue, 03 Nov 2026 09:41:47 GMT
Content-type: text/plain
Content-Length: 0
Last-Modified: Tue, 03 Nov 2026 09:24:03 GMT
The option applies only to unrecognized extensions. A request for index.html still returns text/html, because the extension is resolved and the fallback is never reached.
The same value can be set from Python with default_content_type attribute of SimpleHTTPRequestHandler:
import http.server
import socketserver
class Handler(http.server.SimpleHTTPRequestHandler):
default_content_type = 'text/plain'
with socketserver.TCPServer(('', 8000), Handler) as httpd:
httpd.serve_forever()
The attribute is defined on the class with a default of application/octet-stream, so a subclass can replace it directly. It is not a constructor argument, and passing it as one raises TypeError.
Leave a Comment
Cancel reply