April 24, 2010: We are pleased to announce that Version 4 of this course is now under development. For updates and an early peek at the content, please check out the Software Carpentry blog at http://www.software-carpentry.org/blog/.
Figure 24.1: CGI Data Processing Cycle
| Name | Purpose | Example |
|---|---|---|
REQUEST_METHOD |
What kind of HTTP request is being handled | GET or POST |
SCRIPT_NAME |
The path to the script that's executing | /cgi-bin/post_photo.py |
QUERY_STRING |
The query parameters following "?" in the URL |
name=mydog.jpg&expires=never |
CONTENT_TYPE |
The type of any extra data being sent with the request | img/jpeg |
CONTENT_LENGTH |
How much extra data is being sent with the request (in bytes) | 17290 |
Table 24.1: Important CGI Environment Variables
CONTENT_LENGTH bytes to the CGI on standard input
"Content-Type" header to specify the MIME type of the data being sent| Family | Specific Type | Describes |
|---|---|---|
| Text | text/html |
Web pages |
| Image | image/jpeg |
JPEG-format image |
| Audio | audio/x-mp3 |
MP3 audio file |
| Video | video/quicktime |
Apple Quicktime video format |
| Application-specific data | application/pdf |
Adobe PDF document |
Table 24.2: Example Mime Types
Content-Type header to tell the client to expect HTML...#!/usr/bin/env python # Headers and an extra blank line print 'Content-type: text/html' print # Body print '<html><body><p>Hello, CGI!</p></body></html>'
http://www.yourserver.com/cgi-bin/hello_cgi.py
cgi-bin directory
Figure 24.2: Basic CGI Output
#!/usr/bin/env python
import os, cgi
# Headers and an extra blank line
print 'Content-type: text/html'
print
# Body
print '<html><body>'
keys = os.environ.keys()
keys.sort()
for k in keys:
print '<p>%s: %s</p>' % (cgi.escape(k), cgi.escape(os.environ[k]))
print '</body></html>'
Figure 24.3: Environment Variable Output
form... element
action attribute specifies the URL to send data tomethod attribute specifies the type of HTTP request to send
"POST" for HTML formsselect elements to let users choose values from a list
option elementsinput elements for other kind of data
type is "text", get a one-line text entry boxtype is "checkbox", get an on/off checkbox"submit" and "reset" create buttons to submit the form, or re-set the data to initial values<html>
<body>
<form action="http://www.third-bit.com/cgi-bin/simple_form.py" method="POST">
<p>Sequence: <input name="sequence" type="text" value="GATTACA"/>
Search type:
<select name="search_type">
<option>Exact match</option>
<option selected="selected">Similarity match</option>
<option>Sub-match</option>
</select>
</p>
<p>Programs:
<input checked="checked" name="program" type="checkbox" value="FROG-11">
FROG (version 1.1)
</input>
<input name="program" type="checkbox" value="FROG-beta">
FROG (2.0 beta)
</input>
<input checked="checked" name="program" type="checkbox" value="Bayes-Hart">
Bayes-Hart
</input>
</p>
<p>
<input type="submit"/>
<input type="reset"/>
</p>
</form>
</body>
</html>
Figure 24.4: A Simple Form
input element has a name attribute
os.environ['REQUEST_METHOD']: "POST"os.environ['SCRIPT_NAME']: "/cgi-bin/simple_form.py"os.environ['CONTENT_TYPE']: "application/x-www-form-urlencoded"os.environ['REQUEST_LENGTH']: "80"sequence=GATTACA&search_type=Similarity+match&program=FROG-11&program=Bayes-Hartcgi module instead
FieldStorage
FieldStorage object is created, it reads and stores information contained in the URL and environment
sys.stdin#!/usr/bin/env python
import cgi
print 'Content-type: text/html'
print
print '<html><body>'
form = cgi.FieldStorage()
for key in form.keys():
value = form.getvalue(key)
if isinstance(value, list):
value = '[' + ', '.join(value) + ']'
print '<p>%s: %s</p>' % (cgi.escape(key), cgi.escape(value))
print '</body></html>'
| URL | Value of a |
Value of b |
|---|---|---|
http://www.third-bit.com/swc/show_params.py?a=0 |
"0" |
None |
http://www.third-bit.com/swc/show_params.py?a=0&b=hello |
"0" |
"hello" |
http://www.third-bit.com/swc/show_params.py?a=0&b=hello&a=22 |
[0, 22] |
"hello" |
Table 24.3: Example Parameter Values
import cgitb; cgitb.enable() to the top of the program
cgitb is the CGI traceback moduleFieldStorage value is a string or a list is tedious
FieldStorage.getfirst(name) to get the unique value
FieldStorage.getlist(name) always returns a list of values
name
Figure 24.5: Three Tier Architecture
Hi, is anyone reading this site? I was wondering the same thing. I wasn't sure if we were supposed to post here. Good point. Is there way to delete messages?
newmessage is there, append it, and display resultsnewmessage isn't there, someone's visiting the page, rather than submitting the form# Get existing messages.
infile = open('messages.txt', 'r')
lines = [x.rstrip() for x in infile.readlines()]
infile.close()
# Add more data?
form = cgi.FieldStorage()
if form.has_key('newmessage'):
lines.append(form.getfirst('newmessage'))
outfile = open('messages.txt', 'w')
for line in lines:
print >> outfile, line
outfile.close()
# Display.
print 'Content-Type: text/html'
print
print '<html><body>'
for line in lines:
print '<p>' + line + '</p>'
print '''
<form action="http://www.third-bit.com/swc/message_form.py" method="post">
<p>Your message:
<input name="newmessage" type="text"/>
</p>
<p>
<input type="submit"/>
<input type="reset"/>
</p>
</form>
'''
print '</body></html>'
message_form.py opens messages.txt, reads lines, closes filemessages.txt, reads the same lines, closes file# Get existing messages.
msgfile = open('messages.txt', 'r+')
fcntl.flock(msgfile.fileno(), fcntl.LOCK_EX)
lines = [x.rstrip() for x in msgfile.readlines()]
# Add more data?
form = cgi.FieldStorage()
if form.has_key('newmessage'):
lines.append(form.getfirst('newmessage'))
msgfile.seek(0)
for line in lines:
print >> msgfile, line
# Unlock and close.
fcntl.flock(msgfile.fileno(), fcntl.LOCK_UN)
msgfile.close()
Figure 24.6: Cookies
Cookie.SimpleCookie
SmartCookie: it is potentially insecure"HTTP_COOKIE"SimpleCookie"HTTP_COOKIE" value to the cookie's load method# Get old count.
count = 0
if os.environ.has_key('HTTP_COOKIE'):
cookie = Cookie.SimpleCookie()
cookie.load(os.environ['HTTP_COOKIE'])
if cookie.has_key('count'):
count = int(cookie['count'].value)
# Create new count.
count += 1
cookie = Cookie.SimpleCookie()
cookie['count'] = count
# Display.
print 'Content-Type: text/html'
print cookie
print
print '<html><body>'
print '<p>Visits: %d</p>' % count
print '</body></html>'
time.asctime(time.gmtime()) to create the valueCopyright © 2005-09 Python Software Foundation.
Created Thu Aug 6 21:56:06 2009 UTC