In this post I show a simple and quick way to capture a basic HTTP POST using Python to provide a basic HTTP Web Server with cgi capability in just a few lines of code and in most cases, it is executable on almost any Python capable server.
Why I Used This Code
I used this successfully to test an interface which wasn’t particularly clear exactly what data it was going to POST to a target web server. Usually a developer could use real developer tools to do this analysis, however, the server doing the POST is POSTing to another server, and both servers sit behind firewalls. It was far quicker to create something simple that could be executed direct on the server.
What Does the Code Do?
The code simply creates a HTTP web server on the server on which it is executed. The web server serves the content that exists in the directory structures from the current working directory and below. The web server is also able to execute CGI scripts written in Python and stored in the cgi-bin subdirectory.
The Code
#!/usr/bin/python
#
import sys, os, cgi, cgitb
# Enable easy error reporting output.
cgitb.enable()
# Create a custom log output to print to stdout and a log file.
class CustomLogger(object):
def __init__(self):
self.terminal = sys.stdout
self.log = open("logfile.log", "a")
def write(self, message):
self.terminal.write(message)
self.log.write(message)
def flush(self):
pass
# Swap stdout for our custom log class.
sys.stdout = CustomLogger()
sys.stderr = sys.stdout
# Call the standard CGI test.
cgi.test()
### END OF SCRIPT ###
Deploying the Code
To install the code, we need to create a new temporary directory on our host server, I used ssh to do this:
mkdir -p /tmp/dmg/cgi-bin
Put the code into the file called form.py in the cgi-bin directory:
cd /tmp/dmg/cgi-bin
vi form.py
[insert code then press shift-ZZ]
chmod 755 form.py
Still on an ssh session, switch back to the dmg directory and execute the Python CGI handler to listen on port 8080:
cd /tmp/dmg
python -m CGIHTTPServer 8080
Call your HTTP tool to POST to the address:http://<your-server>:8080/cgi-bin/form.py
If the tool returns output, then you will see the output on your ssh session screen. The output response from the CGI script is also stored in the /tmp/dmg/logfile.log file.
To quit/end the HTTP web server, simply press CTRL+C multiple times until you are returned to the command prompt.
The output will look like:
Content-type: text/html
Current Working Directory:
/tmp/dmg
Command Line Arguments:
['/tmp/dmg/cgi-bin/form.py', '']
Form Contents:
parameter: <type 'instance'>
MiniFieldStorage('parameter', 'test')
Shell Environment:
...
You will see the POST content in the “Form Contents” section of the output. The values of fields are pre-fixed with “MiniFieldStorage “.
Also included in the output, is the execution environment which contains the environment variables that contain CGI related variables and their respective values such as HTTP_METHOD.
A Test Form
You can also deploy a simple form in order to test the CGI capability manually from a web browser (although this was not required in my case). The form is simple HTML that POSTs two text input fields to our form.py CGI script:
<html><body>
<div style="text-align: center;">
<h1>Test Form</h1>
<form action="/cgi-bin/form.py" method="POST">
f1 : <input style="text-align: center;" name="f1" type="text" />
f2 : <input style="text-align: center;" name="f2" type="text" />
<input type="submit" value="Submit" />
</form>
</div>
</body></html>
The form should be saved to a new file called index.html in the /tmp/dmg directory. You can then manually access the test web server using http://<your-server>:8080 and you will see the form. Enter two values into the form and click submit, to see the output from your CGI script.