Specifies the way in which a program receives its parameters from a client via a Web server.
How does the program get input from the client?
How does the output of the program get returned to the client?
CGI passes client data in Environment Variables or via standard input.
Data is returned to the client via standard output.
CGI programs can be written in any programming language.
Interpreted languages (Perl, TCL, Python, Ruby) are often preferred to compiled languages (C, C++)
Not CGI: Java is a common server side language, usually as part of a larger Java application server (Tomcat, Websphere)
Not CGI: Languages like PHP and ASP use a different interface technology between server and script (server module)
Web server needs to differentiate between content and programs.
Common convention is to use the cgi-bin directory: files in here are programs.
Since CGI scripts are executable, anyone can run a CGI script installed on your system.
Security Risk
Servers often restrict who or what can have CGI scripts.
When a server recieves a request for a CGI resource:
<html>
<head>
<title>Demo static HTML page</title>
</head>
<body>
<h1>Hello COMP249!</h1>
</body>
</html>
#!/usr/local/bin/python
print "Content-type: text/html\n\n"
print "<html>"
print "<head>"
print "<title>Demo static HTML page</title>"
print "</head>"
print "<body>"
print "<h1>Hello COMP249!</h1>"
print "</body>"
print "</html>"
http://platypus.ics.mq.edu.au/~cassidy/cgi-bin/demo.py
The first print statement is the Content-type line that specifies the media type of the output that is generated. This line is actually part of the HTTP response header sent back to the client.
This line is immediately followed by a blank line which must not contain any spaces or tabs (the '\n\n' bit). Remember the HTTP protocol.
CGI programs often fail since the programmer forgot the blank line.
After the blank line comes the HTML encoded text which is displayed on the user's browser.
The OS (or web server) uses the hashbang line to find out how to run the program:
Windows: #!C:/Python25/python
Unix: #!/usr/local/bin/python
On Unix, the Python script needs to be made executable with chmod (or use WinSCP):
chmod 755 demo.py # or equivalently chmod a+rx demo.py
You can also test the script on the command line:
> cd ~/html/cgi-bin cgi-bin> ./demo.py
>>> 1+2 3 >>> #add comments ... >>>7/2 3 >>>7./2 3.5
>>> 'a tring' 'a tring' >>> "a string" 'a string' >>> print 'This is', 'a test' This is a testMulti-line string can be written as
>>> str="line 1 \n\ line 2 \n\ line 3" >>> print str line 1 line 2 line 3 >>>Alternatively, use triple-quotes """ or ''' to surround the string.
>>> str="""line 1 line 2 line 3""" >>> print str line 1 line 2 line 3 >>>
>>> a=['hi', 10, 'hello', 200] >>> a ['hi', 10, 'hello', 200] >>> a[0] 'hi' >>> a[1] 10 >>> a[:2] ['hi', 10] >>> a[2:] ['hello', 200] >>> a. append(300) >>> a ['hi', 10, 'hello', 200, 300] >>> a[4]=3 >>> a ['hi', 10, 'hello', 200, 3] >>>a.remove(3) >>> a ['hi', 10, 'hello', 200] >>> 200 in a True >>> a.index(200) 3
>>> a='hi', 10, 'hello', 200
>>> a
('hi', 10, 'hello', 200)
>>> a[0]
'hi'
>>> a[1]
10
>>> a[:2]
('hi', 10)
>>> a[2:]
('hello', 200)
>>> len(a)
4
>>> 200 in a
True
>>> print "Hello %s! How do you like %s?" % ('COMP249 students', "today's topic") # %s is the placeholder
# what is the output?
Dictionaries are indexed by keys, which can be any immutable type, e.g. string or numbers.
A dictionary is an unordered set of key:value pairs.
>>> dic={'hi': 101, 'hello': 200}
>>> dic
{'hi': 101, 'hello': 200}
>>> dic['hi']
101
>>> dic.keys()
['hi', 'hello']
>>> dic.has_key('hello')
Ture
>>> 'hello' in dic
True
>>> 200 in dic
False
>>> for k, v in dic.iteritems():
print k, v
...
hi 101
hello 200
>>> for x in dic:
print x, dic[x]
...
hi 101
hello 200
x = int(raw_input("Enter an integer: "))
if x < 0:
print "negative"
elif x == 0:
print "zero"
else:
print "positive"
l = ['COMP125', 'COMP249', 'COMP344'] for x in l: print x, l.index(x) output: COMP125 0 COMP249 1 COMP344 2
l = ['COMP125', 'COMP249', 'COMP344'] for i in range(len(l)): print i, l[i] output: 0 COMP125 1 COMP249 2 COMP344 >>>range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>>range(2:5) [2, 3, 4]
def fib1(n):
a, b = 0, 1
while b < n:
print b
a, b = b, a+b
>>>fib1(10)
1
1
2
3
5
8
or
def fib2(n):
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return result
>> l = fib2(10)
>>> l
[1, 1, 2, 3, 5, 8]
#!/usr/local/bin/python
print "Content-type: text/html\n\n"
print """
<html>
<head><title>Table Demo</title></head>
<body>
<h3>COMP249 Staff</h3>
<table>
<tr><th>Lecturer</th><th>Unit</th></tr>
"""
dict = {'Yan':'COMP249','Steve':'COMP249'}
for key, value in dict.items():
print " <tr><td>", key, "</td><td>", value, "</td></tr>"
print """
</table>
</body>
</html>
"""
<html>
<head><title>A simple HTML Form Page</title><head>
<body>
<h3> A simple HTML Form Page</h3>
<hr>
<form action="cgi-bin/process.py">
<p><strong>Enter your name:</strong></p>
<p><input type=text name=user></p>
<p><input type=submit></p>
</form>
<body>
<html>
The CGI script receives the form data via the query string.
In the previous example:
user=Rona+Bates
Spaces are replaced with + or %20
Other special characters are scaped with % plus the ASCII code
Information from different form widgets is separated with &
user=Rona+Bates&gender=female
If a GET method:
The query string is encoded in the URL:
http://.../cgi-bin/process.py?user=Rona+Bates
The server places the information in the environment variable QUERY_STRING.
If a POST method:
GET encodes the query string in the URL
Easy to see what's being passed to the script
Can bookmark/link to a form submission, eg. a Google search
POST encodes query as a message in the HTTP request.
No information in the URL about the form data.
Data is not hidden, but not stored in server logs.
Allows larger payloads to be sent (eg. file upload).
#!/usr/local/bin/python
import cgi # imports cgi module
import cgitb; cgitb.enable() # traceback manager, displays
# errors in the Web browser
form = cgi.FieldStorage() # retrieves form input
print "Content_type: text/html\n\n" # output MIME type
html = """
<html>
<head><title>Greetings</title></head>
<body>
<h3>Greetings</h3>
<p>%s</p>
</body>
</html>
"""
if not form.has_key('user'):
print html % "Who are you?"
else:
print html % ("Hello, %s." % form.getvalue('user'))
Examples: client_py.html process.py
The string expressions (%) are used to insert the input text into a reply string, and the reply string into the triple-quoted HTML string block.
Much of the additional information needed by CGI programs is available via HTTP environment variables.
How is this information transmitted?
For example:
In Python, HTTP environment variables are available (when set) via the os.environ dictionary.
#!/usr/local/bin/python
import os
print 'Content-type: text/html\n\n'
if os.environ.has_key('SERVER_PORT'):
server_port = os.environ['SERVER_PORT']
print '<p> SERVER_PORT:', server_port, '</p>'
else:
print '<p> SERVER_PORT: unknown </p>'
The QUERY_STRING variable always appears in the os.environ dictionary, even though its value is '' (the empty string).
#!/usr/local/bin/python
import os
print 'Content-type: text/html\n\n'
if os.environ.has_key('QUERY_STRING') and \
os.environ['QUERY_STRING'] != '':
query_string = os.environ['QUERY_STRING']
print '<h3> QUERY_STRING:', query_string, '</h3>'
else:
print '<h3> QUERY_STRING: unknown </h3>'
Examples: name=Steve, name=Steve&age=21
#!/usr/local/bin/python import cgi import cgitb cgitb.enable() # cgi.enable(display=0, logdir="/temp") print "Content-type: text/html\n\n" print "<h3>Hello</h3>" print xxx # Here is a name error
refer to http://epydoc.sourceforge.net/stdlib/cgitb-module.html