Simple python web server to demonstrate GET/POST handling

This blog describes a simple open source (MIT licensed) web server that demonstrates how browser/server interactions work for GET and POST requests using the python BaseHTTPServer package. It was updated to version 1.2 on 20-May-2015. This software is licensed under the term of the MIT license. Feel free to use it however you wish.

Use it as a starting point to understand the package when creating your own custom web server for handling specific types of requests but recognize that it is not suitable for a production environment. To use it in such an environment you would, at the very least, want to add improve the error handling and add threading support. You would probably also want to add SSL/TLS support.

Download

To use the simple web server download one of the archives and extract the files.

Archive Checksum Description
webserver.tar.bz2 28050 Bzip2 format.
webserver.tar.gz 38095 Gzip format.
webserver.zip 11861 Zip format.

The files in the archives are shown below.

File Description
webserver.css Sample CSS file referenced by webserver.html.
webserver.html Sample HTML file.
webserver.js Sample Javascript file referenced by webserver.html.
webserver.png Sample PNG file referenced by webserver.html.
webserver.py The web server program for python 2.7.
webserver-start.sh Example script to start the web server.
webserver-stop.sh Example script to stop the web server.

The example below shows how to download and install using the zip archive.

NOTE: You may have to change the first line of the source file to correctly reference your installed version of python.

Running the Server

After you download the server, you simply run it by typing “./webserver.py” or “python2.7 ./webserver.py“. That will start the server on your local host using port 8080. If that port is already in use, then use the -p option to specify another port like this “./webserver.py -p 9000“. Do not try to use port 80. It will interfere with the normal operation of your system.

As the simple web server runs, it will print out informational messages as it is running to show you what is happening.

This is the list of options available from the server.

File Description
-d DIR, –daemonize DIR Daemonize this process, store the 3 run files (.log, .err, .pid) in DIR (default “.”). Version 1.2 or later.
-h, –help Help message.
-H host, –host host The hostname (e.g. localhost).
-l LEVEL, –level LEVEL Logging level: noset, debug, info, warning, error, critical. Version 1.2 or later.
–no-dirlist Disable directory listings. Version 1.2 or later.
-p port, –port port The port (e.g. 8080).
-r dir, –rootdir dir The web files root directory.
-v, –verbosity Increase verbosity. Not used.
-V, –version Print the version number and exit.

Accessing the Server

Now that the server is running you can access the webserver.html page by entering the following URL: http://127.0.0.1/webserver.html (you can also use 0.0.0.0 if that is easier to type). If server is running properly you will see something like this:

Screen Shot 2015-02-07 at 1.36.40 PM

If you enter data in the “Form Using GET” fieldset, the argument values will appear in the webserver output log. If you enter data in the “Form Using POST” fieldset, the argument values will in the webserver output log and on a new page. In both case, you inspect the source code to see how the form data was captured and processed from the browser request.

Now try entering “http://127.0.0.1:8080/info” and you will see internal server information. This shows, in a crude way, how you can enter custom URLs.

Screen Shot 2015-02-09 at 7.06.09 AM

At this point you have verified that the simple web server is working. If you want to go further, you try creating your own HTML or javascript files.

Implementation Discussion

This implementation uses the BaseHTTPServer and cgi packages for creating the server and processing browser requests. It uses argparse to manage the command lines arguments. There are a number of interesting features of this example.

The first is the use of the class factory make_request_handler_class to allow the request object to have access to the command line options, specifically the root directory for accessing files to display for GET requests. You could add any arbitrary class arguments this way. For example you add the content headers for handling different file extensions which in the current implementation are in the do_GET() handler method.

Another interesting feature is setting the content type based on the file extension.

Yet another interesting feature is that the POST request handler redirects to a custom page with a back button. This is simply to demonstrate that it can be done.

The source code for webserver.py is presented in full below for interactive reference but it probably makes more sense to download it so that you can search through it in your favorite editor.

Enjoy!

6 thoughts on “Simple python web server to demonstrate GET/POST handling”

  1. Hi Joe,

    Thank a lot for your tutorial! May I use it for my project?

    When I checked your code with my editor, it informed this function

    is deprecated in this module. Use

    instead. You may want to update your code later.

     

    Did you think about to use some template for html part? Because write it directly in web server file is not really a good way.

  2. Hi!

    I just tried running this and I have a couple of questions.

    1) When I first load, I get a warning:

    “WARNING: Unobtrusive Javascript not working!” and Javascript is not working. How would you fix that?

     

    2) When I enter something in the POST entries in the form, I get an error.
    Error response
    Error code 501.

    Message: Unsupported method (‘POST’).

    Error code explanation: 501 = Server does not support this operation.

     

    Do you have an idea of what might be causing those errors? all I did was copy and run the code.

    3) I am trying to quit ./webserver.py, but I can’t find it in my processes. How do you stop the server from running? I wanted to run ./webserver.py again, but I got this error:
    ERROR: pid file exists, cannot continue: <filename>. 

    Thanks!

Leave a Reply