Minimal HTTP server with Werkzeug - Internal Server Error
Question: To demonstrate basics HTTP handling, I'm in the process of trying to define a
really minimal HTTP server demonstration. I have been using the excellent
[werkzeug](http://werkzeug.pocoo.org/) library that I'm trying to "dumb" down
a bit more. My current server does too much :)

    
    
    #!/usr/bin/env python2.7
    # encoding: utf-8
    
    if __name__ == '__main__':
        from werkzeug.serving import run_simple
        run_simple('127.0.0.1', 6969, application=None)
    

`run_simple` is handling already too many things. When making a request for
this server,

    
    
    → http GET http://127.0.0.1:6969/
    

we get:

    
    
    HTTP/1.0 500 INTERNAL SERVER ERROR
    Content-Type: text/html
    Content-Length: 291
    Server: Werkzeug/0.8.3 Python/2.7.1
    Date: Tue, 08 Jan 2013 07:45:46 GMT
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <title>500 Internal Server Error</title>
    <h1>Internal Server Error</h1>
    <p>The server encountered an internal error and was 
    unable to complete your request.  Either the server 
    is overloaded or there is an error in the application.</p>
    

I would love to reduce it to the bare minimum. And use the 500 Internal Server
Error as a catch all. Ideally the Response from the server should be 500 for
any HTTP requests and just that, because the server doesn't know anything
about the requests

    
    
    HTTP/1.0 500 INTERNAL SERVER ERROR
    

Then in a second stage I will probably add

    
    
    HTTP/1.0 500 INTERNAL SERVER ERROR
    Content-Type: text/plain
    
    Internal Server Error
    

Then start to handle requests by understanding them. The goal is to be
educative in the process. Any suggestions for taking over the default answers
is welcome.

**Update 001**

with:

    
    
    #!/usr/bin/env python2.7
    # encoding: utf-8
    
    from werkzeug.wrappers import BaseResponse as Response
    
    
    def application(environ, start_response):
        response = Response('Internal Server Error', status=500)
        return response(environ, start_response)
    
    if __name__ == '__main__':
        from werkzeug.serving import run_simple
        run_simple('127.0.0.1', 6969, application)
    

It will return

    
    
    HTTP/1.0 500 INTERNAL SERVER ERROR
    Content-Type: text/plain; charset=utf-8
    Content-Length: 21
    Server: Werkzeug/0.8.3 Python/2.7.1
    Date: Tue, 08 Jan 2013 07:55:10 GMT
    
    Internal Server Error
    

I want to remove at least the server and the date which are optional.


Answer: As basic example, I wouldn't use a third-party library. You can use the
BaseHTTPServer-module that comes with Python.

    
    
    import BaseHTTPServer
    
    PORT = 8000
    
    class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
        def send_response(self, code, message=None):
            """Send the response header and log the response code.
    
            In contrast to base class, do not send two standard headers 
            with the server software version and the current date.
            """
            self.log_request(code)
            if message is None:
                if code in self.responses:
                    message = self.responses[code][0]
                else:
                    message = ''
            if self.request_version != 'HTTP/0.9':
                self.wfile.write("%s %d %s\r\n" %
                                 (self.protocol_version, code, message))
    
        def do_GET(self):
            self.send_response(500)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write("Internal Server Error\n")
    
    
    httpd = BaseHTTPServer.HTTPServer(("", PORT), MyHandler)
    print "serving at port", PORT
    httpd.serve_forever()
    

This will give us the following response:

    
    
    HTTP/1.0 500 Internal Server Error
    Content-type: text/html
    
    Internal Server Error
    

The place where you can do all your changes now is in the do_GET-method. I
think it is quite obvious what each line does.

**Alternative 1:**

Even more basic is

    
    
    import SocketServer
    
    response = """HTTP/1.0 500 Internal Server Error
    Content-type: text/html
    
    Invalid Server Error"""
    
    class MyTCPHandler(SocketServer.BaseRequestHandler):
        """
        The RequestHandler class for our server.
    
        It is instantiated once per connection to the server, and must
        override the handle() method to implement communication to the
        client.
        """
    
    
        def handle(self):
            # self.request is the TCP socket connected to the client
            self.data = self.request.recv(1024).strip()
            self.request.sendall(response)
    
    if __name__ == "__main__":
        HOST, PORT = "localhost", 8000
        server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()
    

