CGI III: Maintaining State

If one form invokes another form, it is often the case that information from the first form must be send to the second form. This is part of "maintaining state", i.e. maintaining accurate information between different CGI scripts invoked by one user. There are three possibilities to maintain state:
a) send hidden text,
b) write information to a file (on the server),
c) set cookies (on the client).

1) Hidden text


1.1 Create a form that asks a user for his/her name and some comments. Then create two CGI scripts that create a response. The first script displays the information which the user has submitted ("Hello", name, ". These are your comments:", comments) and asks the user whether he/she really wants to submit the information. The second script is invoked by the first one and displays "Thank you", name, ". Your comments have been submitted:", comments.

To implement this add a form and hidden tags to the first CGI script, such as

print "<input type='hidden' name='hiddenname' value='",name,"'>"
print "<input type='hidden' name='hiddencomments' value='", comments,"'>"

The second CGI script retrieves these strings via

name = form.getvalue('hiddenname')
comments = form.getvalue('hiddencomments')

2) Cookies


2.1 Use a cookie instead of hidden text in the previous exercise.

The following code in the first CGI script sets a cookie. Note that the cookie needs to be set before printing the Content-Type line but after reading the form values.

import Cookie
C = Cookie.SimpleCookie()
C["cookie_name"] = name
C["cookie_comments"] = comments
print C
print "Content-Type: text/html\n"

The second CGI script retrieves the cookie:

import Cookie
import os

C = Cookie.SimpleCookie()

name = C["cookie_name"].value
comments = C["cookie_comments"].value

(Note: The example above refers to session cookies that are not permanently stored on the computer. I could not get the code above to work for cookies that are stored on the computer, mainly because on a PC the newline character is "\r\n" instead of "\n" and because stored cookies need an expiration time. Something like the following should work:

import time
temp = time.strftime("%a, %d-%b-%Y ", time.gmtime())
hour = time.strftime("%H", time.gmtime())
hour = str(int(hour) + 1)
if len(hour) <2 : hour = "0" + hour
temp = temp + hour + time.strftime(":%M:%S GMT", time.gmtime())

cookiedata = name + "|" + comments
print "Set-Cookie: nameandcomments="+cookiedata+"; expires=" + temp +"\r"
print "Content-Type: text/html\r\n\r"

3) Writing to a file


3.1 A hit counter: create a file that contains only the number "0". Your CGI script must open that file for reading; read the first line of the file into an integer; increase the number by one; close the file; open the file again for writing (not appending); write the number to the file; close the file.

3.2 (Optional) Create yet another version of exercise 1.1 but this time save the information to a file.

There are several problems involved with saving to a file because several users can look at the CGI script at the same time. To keep track of which user wrote which comments, write user name and comments to the file; send the user name as hidden text and use the name to retrieve the correct comments from the file.