6

I have recently been using Python's SimpleHTTPServer to host files on my network. I want a custom 404 Page, so I researched this and got some answers, but I want to still use this script I have. So, what do I have to add to get a 404 page to this script?

import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler


HandlerClass = SimpleHTTPRequestHandler
ServerClass  = BaseHTTPServer.HTTPServer
Protocol     = "HTTP/1.0"

if sys.argv[1:]:
    port = int(sys.argv[1])
else:
    port = 80
server_address = ('192.168.1.100', port)

HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)

sa = httpd.socket.getsockname()
print "Being served on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
1
  • Try this answer - for your question you'll need to do something like HandlerClass.error_message_format = .... Commented Mar 18, 2014 at 0:42

2 Answers 2

5

You implement your own request handler class and override the send_error method to change the error_message_format only when code is 404:

import os
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

class MyHandler(SimpleHTTPRequestHandler):
    def send_error(self, code, message=None):
        if code == 404:
            self.error_message_format = "Does not compute!"
        SimpleHTTPRequestHandler.send_error(self, code, message)


if __name__ == '__main__':
    httpd = HTTPServer(('', 8000), MyHandler)
    print("Serving app on port 8000 ...")
    httpd.serve_forever()

The default error_message_format is:

# Default error message template
DEFAULT_ERROR_MESSAGE = """\
<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>
<p>Error code %(code)d.
<p>Message: %(message)s.
<p>Error code explanation: %(code)s = %(explain)s.
</body>
"""
Sign up to request clarification or add additional context in comments.

Comments

1

As soon as you create the HTTPServer instance, you can access its handler and then from its handler you can access its error_message_format property, which you can change to whatever HTML you want, or read it from a file as shown here.

I do highly recommend using ThreadingHTTPServer instead of HTTPServer though, because otherwise you won't be able to Ctrl+C (keyboard interrupt) to stop the server, and instead will have to either close the terminal altogether, or close your browser. FWIW, the built-in python3 -m http.server script also uses a (modified version of) ThreadingHTTPServer, as seen here. It does not use HTTPServer.

Note that this is better than creating a custom handler class and overriding the set_error method because when we do it like this, the program doesn't have to read the 404.html file every time it is used. Rather it is just read once just before the server starts. That said, I wouldn't have figured this out if it weren't for the other answer by Nicu, so thanks for that.

import http.server

PORT = 8080

if __name__ == "__main__":
    try:
        with http.server.ThreadingHTTPServer(("", PORT), http.server.SimpleHTTPRequestHandler) as httpd:
            with open("404.html") as html_file:
                httpd.RequestHandlerClass.error_message_format = html_file.read()
            print(f"Serving at http://127.0.0.1:{PORT}/ (Ctrl+C to stop)")
            httpd.serve_forever()
    except KeyboardInterrupt:
        print("Keyboard interrupt detected")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.