Case Study: An Interactive Web Page

Case Study An Interactive Web Page

Figures 19.1319.14 show the implementation of a simple interactive portal for the fictitious Bug2Bug Travel Web site. The example queries the client for a name and password, then displays information about weekly travel specials based on the data entered. For simplicity, the example does not encrypt the data sent to the server. Ideally, sensitive data like a password should be encrypted. Encryption is beyond the scope of this book.

Figure 19.13. Interactive portal to create a password-protected Web page.

(This item is displayed on pages 939 - 940 in the print version)

"http://www.w3.org/1999/xhtml"> 9 10

1 6 7 8

Bug2Bug Travel 11 12 13 14

Welcome to Bug2Bug Travel

15 16 method = "post" action = "/cgi-bin/portal.cgi"> 17

Please enter your name and password:

18 "text" name = "namebox" /> 19 "password" name = "passwordbox" /> 20

password is not encrypted

21 "submit" name = "button" /> 22 23 24

Figure 19.14. Interactive portal handler.

(This item is displayed on pages 940 - 942 in the print version)

1 // Fig. 19.14: portal.cpp 2 // Handles entry to Bug2Bug Travel. 3 #include 4 using std::cout; 5 using std::cin; 6 7 #include 8 using std::string; 9 10 #include 11 using std::getenv; 12 using std::atoi; 13 14 int main() 15 { 16 char postString[ 1024 ] = ""; 17 string dataString = ""; 18 string nameString = ""; 19 string passwordString = ""; 20 int contentLength = 0; 21 22 // data was posted 23 if ( getenv( "CONTENT_LENGTH" ) ) 24 contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); 25 26 cin.read( postString, contentLength ); 27 dataString = postString; 28 29 // search string for input data 30 int namelocation = dataString.find( "namebox=" ) + 8; 31 int endNamelocation = dataString.find( "&" ); 32 int password = dataString.find( "passwordbox=" ) + 12; 33 int endPassword = dataString.find( "&button" ); 34 35 // get values for name and password 36 nameString = dataString.substr( 37 namelocation, endNamelocation - namelocation ); 38 passwordString = dataString.substr( password, endPassword - password ); 39 40 cout << "Content-Type: text/html "; // output HTTP header 41 42 // output XML declaration and DOCTYPE 43 cout << "" 44 << " 45 << ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">"; 46 47 // output html element and some of its contents 48 cout << "" 49 << "Bug2Bug Travel"; 50 51 // output specials 52 cout << "

Welcome " << nameString << "!

" 53 << "

Here are our weekly specials:

" 54 << "
  • Boston to Taiwan ($875)
  • " 55 << "
    • San Diego to Hong Kong ($750)
    • " 56 << "
      • Chicago to Mexico City ($568)
      "; 57 58 if ( passwordString == "coast2coast" ) // password is correct 59 cout << "

      Current member special: " 60 << "Seattle to Tokyo ($400)

      "; 61 else // password was incorrect 62 cout << "

      Sorry. You have entered an incorrect password

      "; 63 64 cout << ""; 65 return 0; 66 } // end main
 

Figure 19.13 displays the opening page. It is a static XHTML document containing a form that POSTs data to the portal.cgi CGI script (line 16). The form contains one field to collect the user's name (line 18) and one to collect the user's password (line 19). [Note: Not like the CGI scripts, which are placed in the cgi-bin directory of the Web server, this XHTML document was placed in the htdocs directory of the Web server.]


Figure 19.14 contains the CGI script. First, let us examine how the user's name and password are retrieved from standard input and stored in strings. The string library find function searches dataString (line 30) for an occurrence of namebox=. Function find returns a location in the string where namebox= was found. To retrieve the value associated with namebox=the value entered by the userwe move the position in the string forward 8 characters. The program now contains an integer "pointing" to the starting location. Recall that a query string contains name-value pairs separated by equals signs and ampersands. To find the ending location for the data we wish to retrieve, we search for the & character (line 31). The length of the entered word is determined by the calculation endNamelocation - namelocation. We use a similar approach to determine the start and end locations of the password (lines 3233). Lines 3638 assign the form-field values to variables nameString and passwordString. We use nameString in line 52 to output a personalized greeting to the user. The current weekly specials are displayed in lines 5356.


If the member password is correct, lines 5960 output additional specials. If the password is incorrect, the client is informed that the password was invalid and no additional specials are displayed.

Note that we use a static Web page and a separate CGI script here. We could have incorporated the opening XHTML form and the processing of the data into a single CGI script, as we did in previous examples in this chapter. We ask the reader to do this in Exercise 19.8.


Performance Tip 19.1

It is always much more efficient for the server to provide static content rather than execute a CGI script, because it takes time for the server to load the script from hard disk into memory and execute the script (whereas an XHTML file needs to be sent only to the client). It is a good practice to use a mix of static XHTML (for content that generally remains unchanged) and CGI scripting (for dynamic content). This practice allows the Web server to respond to clients more efficiently than if only CGI scripting were used.

Категории