- Embedded Objects--An Internet Proposal
This chapter will attempt to explain some of the more advanced aspects of CGI programming and HTML in general. CGI programs, as you can probably tell, are very simple transaction-based programs that might perform a simple task. Suppose that you wanted to take that simple task further and do more heavy-duty type work. You will find that the CGI paradigm itself cannot handle some of the basic needs of more advanced applications without the help of some workarounds. There are also some new proposals under way to enhance the capability of HTML. Hopefully, after reading this chapter, you will have the necessary tools and information to perform robust operations using CGI and HTML.
As you have seen in previous chapters, one sorely missed concept in CGI programming is that of a session or preserved state among transactions. A simple example of this might be keeping track of items in a virtual shopping cart while the user happily goes searching for more items to buy. Each visit to a page is a single transaction, which means that once the CGI program is finished, it remembers nothing about what it just did. You will see that the need for an extended session is essential when you are implementing anything more than a simple fill-out form handler.
The Need for an Extended Session
Sessions can be thought of as a combination of one or more transactions. As we have seen, CGI programs are capable of nothing more than a single transaction. The shopping cart is a good example of this need. Another might be keeping track of the user information while the user is visiting your sight. Perhaps the .htaccess security on your Web pages isn't quite enough. Maybe you'd like the user to login to your site through a login CGI script. Another example might be to keep track of what the user is searching for if you are providing a search engine on the Web.
All of these examples show that there is a crucial need for maintaining an extended session across invocations of your CGI program. There are certain tricks that one can play to maintain a state across separate and distinct CGI transactions. One of these tricks has already been discussed in Chapter 4, "HTML Forms--The Foundation of an Interactive Web." Another trick is a bit more expensive in terms of performance although it is a more secure approach. We will show you the techniques as well as use them in some, hopefully, useful examples.
Data and State Preservation Between Transactions As we have seen in Chapter 4, there exists in the HTML form specification the concept of a hidden field. Obviously a hidden field serves no purpose other than to pass data from the HTML form back to the CGI script. In fact, all fields are for this general purpose. The main difference with the hidden field is that the user cannot alter this data and therefore it is a means by which you can send data back to yourself. This is the first and most obvious way to maintain a state across sessions. What you would do is simply put the data you wish to retain across transactions into a hidden field and then examine the contents of the hidden field the next time your CGI script is called. This is a neat trick, but remember that each transaction causes this data to travel across the wire for everyone to see! This is obviously not a good place to keep track of passwords and credit-card numbers.
Another way of preserving state between transactions is by using files on the server. What you can do is create a unique file instance perhaps based on either the
REMOTE_HOST environment variable or the
REMOTE_ADDR environment variable if
REMOTE_HOST is not available. By definition of the CGI specification, at least
REMOTE_ADDR should be set by the server prior to execution of the CGI program. You may also want to include the current date or time with this file as you may wish to control the expiration of a user's session. As you might guess, this method will most likely be slower due to the fact that you must always open the session file upon each script invocation. The overhead of doing this might be worthwhile depending on the amount of data you wish to preserve. Disk access is still faster than network transmission. There are other dangers of using a server-based session file that we will discuss.
A third approach is to use a combination of the first two approaches. You may wish to provide a login screen or use a protected script to obtain a userid when the user first enters your CGI session. You can then create a one-way hash of the userid perhaps again with the current date or time and pass this hash value back in a hidden field for continuous authentication between transactions.
Let's now take a look at a few examples using these methods of state preservation. Our first example will be a simple calculator, shown in Listing 16.1. We will maintain the current value and allow add, subtract, multiply, and divide operations. The data we will want to retain across transactions is the current value.