Python

 

 

 

 

Python - HTTP - http.server

 

The http.server module in Python is part of the standard library and provides classes for implementing HTTP servers (Web servers). It can serve as a simple HTTP server for testing or prototyping web applications, serving static files, or developing small-scale web applications. This module supports HTTP/1.0 and HTTP/1.1.

 

There are several components in the http.server module and followings are the list and descriptions of those modules :

  • BaseHTTPRequestHandler: This is the base class for handling incoming HTTP requests. It provides methods for parsing requests, sending responses, and handling errors. You can extend this class and override its methods to customize the behavior of the HTTP server.
  • SimpleHTTPRequestHandler: This class is a subclass of BaseHTTPRequestHandler and provides a basic implementation for serving files from the local filesystem. It supports GET and HEAD methods, and automatically generates directory listings if the requested path is a directory.
  • ThreadingHTTPServer: This class extends the http.server.HTTPServer class and provides a multithreaded HTTP server. It creates a new thread for each incoming request, which can improve performance when handling multiple simultaneous connections.
  • CGIHTTPRequestHandler: This class is another subclass of BaseHTTPRequestHandler and provides support for serving CGI scripts. It can execute the script and return the output as the HTTP response.

 

 

NOTE 1 : All the examples in this page are written in Python 3.x. It may not work if you use Pyton 2.x

NOTE 2 : All the examples in this page are assumed to be written/run on Windows 10 unless specifically mentioned. You MAY (or may not) need to modify the syntax a little bit if you are running on other operating system.

 

 

< Example 01 > ========================================================

 

The http.server module also provides a command-line interface for running a simple HTTP server, which can be invoked using the following command:

    python -m http.server [port] [--bind address] [--directory path] [--cgi]

  • port: The port number on which the server will listen for incoming connections. The default is 8000.
  • --bind: The address to which the server will bind. The default is '0.0.0.0', which means the server will be accessible from any IP address.
  • --directory: The directory from which the server will serve files. The default is the current working directory.
  • --cgi: This flag enables the server to serve CGI scripts.

 

type in the command as follows with local ip and the port 8080

 

 

It prints a line of string indicating that the server is running

 

 

Open a browser and type in the server IP and port that you specified above. By default, the http.server would generate Directory listing as shown below.

 

 

 

 

< Example 02 > ========================================================

    http_server_Ex01.py

    #Import the necessary libraries

    import http.server

    import socketserver

    import datetime

     

    #Create a custom HTTP request handler class, inheriting from SimpleHTTPRequestHandler

    class Server(http.server.SimpleHTTPRequestHandler):

     

       # Define the GET request handler method

       def do_GET(self):

     

           # Get the current timestamp and print it

           timeStamp = self.log_date_time_string()

           print("\nDate / Time :------------------- \n", timeStamp)

     

           # Get the client's address and print it

           clinetAddress = self.client_address

           print("\nClient Address :------------------- \n", clinetAddress)

     

           # Get the client's address string and print it

           addressString = self.address_string()

           print("\nClient Address String :------------------- \n", addressString)

        

           # Get the request line and print it

           requestLine = self.requestline

           print("\nRequest Line :------------------- \n", requestLine)

     

           # Get the request headers and print them

           header = self.headers

           print("\nHeader :------------------- \n", header)

     

           # Get the command (HTTP method) and print it

           command = self.command

           print("\ncommand :------------------- \n", command)

     

           # Get the requested path and print it

           path = self.path

           print("\npath :------------------- \n", path)

     

           # Set the protocol version and send the response

           self.protocol_version = 'HTTP/1.1'

           self.send_response(200, 'OK')

           self.send_header('Content-type', 'text/html')

           self.end_headers()

        

           # Write the response body

           # The letter 'b' here indicates that the string is a bytes literal. In Python, a bytes literal is

           # a sequence of bytes that represents binary data, as opposed to a regular string which

           # represents textual data.

           # self.wfile is an attribute of the BaseHTTPRequestHandler class, which

           # http.server.SimpleHTTPRequestHandler inherits from. It represents a file-like object that provides

           # a binary output stream to write the response sent back to the client.

           # In the context of an HTTP server, self.wfile is used to write the HTTP response headers and body

           # that will be sent to the client making the request. By calling write() on self.wfile, you can write

           # bytes data directly to the output stream, which is then transmitted over the network to the client.

           self.wfile.write(b'<html>')

           self.wfile.write(b'<head><title> Python HTTP Server </title> </head>')

           self.wfile.write(b'<body> Welcome to Python HTTP Server</body>')

           self.wfile.write(b'</html>')

     

       # Define the serve_forever method for the custom server class

       def serve_forever(port):

           # Print the server starting timestamp

           print('[',str(datetime.datetime.now()),'] starting server...')

        

           # Start the server with the specified port and request handler class

           socketserver.TCPServer(('', port), Server).serve_forever()

     

    # If this script is the main entry point, start the server on port 8080

    if name == "main":

       Server.serve_forever(8080)

     

 

Now run the server as shown below

 

 

 

Open a browser and go to the server url as shown below. The webserver sends the contents of the html file that was generated by self.wfile.write().

 

 

The server console prints the client information that was retrieved by do_GET(self) function

 

 

 

< Example 03 > ========================================================

    http_server_Ex02.py

    import http.server

    import socketserver

    import datetime

    import os

     

    class Server(http.server.SimpleHTTPRequestHandler):

        def do_GET(self):

            timeStamp = self.log_date_time_string()

            print("\nDate / Time :------------------- \n", timeStamp)

     

            clinetAddress = self.client_address

            print("\nClient Address :------------------- \n", clinetAddress)

     

            addressString = self.address_string()

            print("\nClient Address String :------------------- \n", addressString)

     

            requestLine = self.requestline

            print("\nRequest Line :------------------- \n", requestLine)

     

            header = self.headers

            print("\nHeader :------------------- \n", header)

     

            command = self.command

            print("\ncommand :------------------- \n", command)

     

            path = self.path

            print("\npath :------------------- \n", path)

     

            # Check if the requested file exists

            file_path = path[1:]  # Remove the leading '/'

            if os.path.isfile(file_path):

                # Send a 200 OK response

                self.protocol_version = 'HTTP/1.1'

                self.send_response(200, 'OK')

                self.send_header('Content-type', 'text/html')

                self.end_headers()

     

                # Read the contents of the file and send it to the client

                with open(file_path, 'rb') as f:

                    content = f.read()

                    self.wfile.write(content)

            else:

                # If the file doesn't exist, send a 404 Not Found response

                self.send_error(404, 'File Not Found: %s' % file_path)

     

        def serve_forever(port):

            print('[',str(datetime.datetime.now()),'] starting server...')

            socketserver.TCPServer(('', port), Server).serve_forever()

     

    if __name__ == "__main__":

        Server.serve_forever(8080)