| prev | Version 1107 (Mon Nov 27 20:46:08 2006) | next |
![[CGI Data Processing Cycle]](./img/server/cgi_round_trip.png)
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.pycgi-bin directory![[Basic CGI Output]](./img/server/hello_cgi.png)
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>'
![[Environment Variable Output]](./img/server/show_env.png)
Figure 24.3: Environment Variable Output
<form>…</form> elementaction attribute specifies the URL to send data tomethod attribute specifies the type of HTTP request to send"POST" for HTML forms<select/> elements to let users choose values from a list<option/> elements<input/> elements for other kind of datatype 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![[A Simple Form]](./img/server/simple_form.png)
Figure 24.4: A Simple Form
<input/> element has a name attributeos.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 insteadFieldStorageFieldStorage object is created, it reads and stores information contained in the URL and environmentsys.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 programcgitb is the CGI traceback moduleFieldStorage value is a string or a list is tediousFieldStorage.getfirst(name) to get the unique valueFieldStorage.getlist(name) always returns a list of valuesname![[Three Tier Architecture]](./img/server/three_tier_architecture.png)
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>'Kid in Pythonmessage_form.py opens messages.txt, reads lines, closes filemessages.txt, reads the same lines, closes filePython Cookbook includes a generic file locking function that works on both Unix and Windows# 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()![[Cookies]](./img/server/cookies.png)
Figure 24.6: Cookies
Cookie.SimpleCookieSmartCookie: 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 valueExercise 24.1:
One way to test a CGI application is to send it HTTP requests, and examine the responses. Write a program that takes a hostname, port, and partial URL as command-line parameters, and sends the URL to the server identified by the hostname and port. The program should display the status code, reason, headers, and response page (if any) that are returned by the web server.
For example, if your program is run as httptest
localhost 80 /greeting.html, it should send a request for
/greeting.html to a web server running on port 80 on the
local machine, and display something like:
STATUS: 200
REASON: OK
HEADERS:
content-length [49]
server ['Apache/2.0.54 (Debian GNU/Linux) DAV/2 SVN/1.1.4 mod_python/3.1.3 Python/2.3.5]
last-modified ['Wed, 19 Apr 2006 13:59:19 GMT']
date ['Sun, 30 Apr 2006 14:12:13 GMT']
content-type ['text/html']
PAGE:
<html>
<body>
<h1>Hello, CGI!</h1>
</body>
</html>
What are the pros and cons of testing a CGI application this way?
Exercise 24.2:
Another way to test a CGI application is to construct a mock
container to take the place of the web server. As described in
the lecture, CGI applications read data from environment
variables and standard input; by using the subprocess
module described in the integration
lecture, you can run the CGI yourself, passing it
whatever test data you want. Write a program that does this.
(For bonus marks, explain how you would test the mock
container…)
Exercise 24.3:
The third way to test a CGI application is to construct a
mock container that calls the CGI directly, rather than creating
a new process and passing it data through environment variables
and standard input. In order for this to work, the CGI program
must import specially-crafted versions of the sys and
os libraries that provide the CGI with data from the
testing program, rather than reading it from the real
sources:
if testing:
import test_sys as sys
import test_os as os
else:
import sys, os
What other changes must be made to the CGI application to allow it to be tested this way? What are the pros and cons of making such changes?
| prev | Copyright © 2005-06 Python Software Foundation. | next |