Академический Документы
Профессиональный Документы
Культура Документы
Outline 16.1 16.2 16.3 16.4 16.5 16.6 16.7 16.8 16.9 16.10 16.11 16.12 16.13 16.14 16.15 16.16 16.17 Introduction HTTP Request Types Multi-Tier Architecture Accessing Web Servers Apache HTTP Server Requesting XHTML Documents Introduction to CGI Simple HTTP Transaction Simple CGI Script Sending Input to a CGI Script Using XHTML Forms to Send Input Other Headers Case Study: An Interactive Web Page Cookies Server-Side Files Case Study: Shopping Cart Internet and Web Resources
URL is a request for a document Web server maps URL (Uniform Resource Locator) to file
Returns requested document
HTTP
Hypertext Transfer Protocol Platform independent Transfer requests and files over Internet
Get
Used to send data to server; part of URL
www.searchsomething.com/search?query=userquery
Info after ? is user input (query string) Max limit on size (depends on server)
Post
User cannot see query fields Fields can exceed get size limit
2003 Prentice Hall, Inc. All rights reserved.
Middle tier
Business and presentation logic Controls interaction of clients and data What is and is not allowed Processes data from information tier, presents to client
Client tier
Middle tier
Application
Information tier
Database
10
"Common"
Not specific to any operating system or language Can use C, C++, Perl, Python, Visual Basic
11
Web page
Simplest form, XHTML document Plain text file, has markings (markup) to describe data <title>My Web Page</title> Indicates text between markup elements is title of web page
Hyperlinks
When user clicks, Web browser loads new page
12
http://
Use the HTTP protocol
www.deitel.com
Hostname of server
/books/downloads.html
Name of resource (downloads.html) Path (/books) Often a virtual directory, hides real location
13
14
15
16
To execute program
Put C++ executable in cgi-bin directory Changed extension from .exe to .cgi
localtime.cgi
To run script
http://localhost/cgi-bin/localtime.cgi
2003 Prentice Hall, Inc. All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 16.5: localtime.cpp // Displays the current date and time in a Web browser. #include <iostream> using std::cout; #include <ctime>
17
Outline
localtime.cpp (1 of 2)
Most of program creates the text HTTP response, containing the contents of the XHTML file. text/html\n\n";
// output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">";
time( ¤tTime );
25 26 27 28 29 30 31 32 33
// output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Current date and time</title></head>" << "<body><p>" << asctime( localtime( ¤tTime ) ) << "</p></body></html>"; return 0;
18
Outline
localtime.cpp (2 of 2) localtime.cpp output (1 of 1)
19
16.9 Simple CGI Script Program sends output to client via HTTP
Client treats it like a server response Reads header, XHTML elements, etc.
Step 2: Server runs script Step 3: Output of script goes to Web server Step 4: Server adds header (HTTP/1.1 200 OK)
Sends entire output to client, which processes and displays
2003 Prentice Hall, Inc. All rights reserved.
20
Content-Type: text/html <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Current date and time</title> </head> <body> <p>Mon Jul 15 13:52:45 2002</p> </body> </html>
21
Outline
localtime.cgi output (1 of 1)
22
Tables in XHTML
<tr> table row start
Ends with </tr>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// Fig. 16.8: environment.cpp // Program to display CGI environment variables. #include <iostream> using std::cout; #include <string> using std::string; #include <cstdlib>
23
Outline
environment.cpp (1 of 2)
int main() { string environmentVariables[ 24 ] = { "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", "HTTP_HOST", "HTTP_USER_AGENT", "PATH", "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT", "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN", "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL", "SERVER_SIGNATURE","SERVER_SOFTWARE" }; // output header cout << "Content-Type: text/html\n\n";
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
// output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Environment Variables</title></head>" << "<body>"; // begin outputting table cout << "<table border = \"0\" cellspacing = \"2\">"; // iterate through environment variables Use string function data for ( int i = 0; i < 24; i++ ) to output a C-style char *. cout << "<tr><td>" << environmentVariables[ i ] << "</td><td>" << getenv( environmentVariables[ i ].data() ) << "</td></tr>"; cout << "</table></body></html>"; return 0; } // end main
24
Outline
environment.cpp (2 of 2)
25
Outline
environment.cpp output (1 of 2)
26
Outline
environment.cpp output (2 of 2)
27
16.10 Sending Input to a CGI Script Supply any data to CGI script
Environment variable QUERY_STRING
Upcoming example
Have user entry query string name=Jill&age=22
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// Fig. 16.9: querystring.cpp // Demonstrating QUERY_STRING. #include <iostream> using std::cout; #include <string> using std::string; #include <cstdlib> int main() { string query = getenv( "QUERY_STRING" ); // output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">";
28
Outline
querystring.cpp (1 of 2)
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
// output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Name/Value Pairs</title></head>" << "<body>"; cout << "<h2>Name/Value Pairs</h2>"; // if query contained no data Link to URL with if ( query == "" ) cout << "Please add some name-value pairs to the string URL "inserted. << "above.<br/>Or try " << "<a href=\"querystring.cgi?name=Joe&age=29\">" << "this</a>."; // user entered query string else cout << "<p>The query string is: " << query << "</p>"; cout << "</body></html>"; return 0;
29
Outline
querystring.cpp (2 of 2) query
} // end main
30
Outline
querystring.cpp output (1 of 2)
31
Outline
querystring.cpp output (2 of 2)
32
16.11 Using XHTML Forms to Send Input Typing input into URLs clumsy
Forms on Web pages Easy way to input information
Form element
action
Occurs when user submits form For us, will call CGI script
method
Type of HTTP request to use (GET, POST) Will demonstrate both types
33
Like text, but each character typed by the user appears as an asterisk (*). checkbox Displays a checkbox that can be checked (true) or unchecked (false). radio Radio buttons are like checkboxes, except that only one radio button in a group of radio buttons can be selected at a time. button A push button. submit A push button that submits form data according to the forms action. image The same as submit, but displays an image rather than a push button. reset A push button that resets form fields to their default values. file Displays a text field and button that allow the user to specify a file to upload to a Web server. When clicked, the button opens a file dialog that allows the user to select a file. hidden Hidden form data that can be used by the form handler on the server. These inputs are not visible to the user. Fig. 16.10 XHTML form elements.
2003 Prentice Hall, Inc. All rights reserved.
34
Description
Drop-down menu or selection box. This element is used with the option element to specify a series of selectable items. This is a multiline text field in which text can be input or displayed. XHTML form elements.
35
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// Fig. 16.11: getquery.cpp // Demonstrates GET method with XHTML form. #include <iostream> using std::cout; #include <string> using std::string; #include <cstdlib> int main() { string nameString = ""; string wordString = ""; string query = getenv( "QUERY_STRING" ); // output header cout << "Content-Type: text/html\n\n";
36
Outline
getquery.cpp (1 of 3)
Get query string, if any. If this is the first time the page is loaded, this will be empty.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
// output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Using GET with Forms</title></head>" Create form. Note that << "<body>";
37
Outline
getquery.cpp (2 of 3)
// output xhtml form cout << "<p>Enter one of your favorite words here:</p>" << "<form method = \"get\" action = \"getquery.cgi\">" << "<input type = \"text\" name = \"word\"/>" << "<input type = \"submit\" value = \"Submit Word\"/>" << "</form>";
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
// user entered query string else { int wordLocation = query.find_first_of( "word=" ) + 5; wordString = query.substr( wordLocation ); // no word was entered if ( wordString == "" ) cout << "<p>Please enter a word.</p>";
On the first execution of this Outline script, query is empty. When the user enters a word, the script is run again. getquery.cpp (3 of 3)
38
// word was entered else cout << "<p>Your word is: " << wordString << "</p>"; } cout << "</body></html>"; return 0; } // end main
39
Outline
getquery.cpp output (1 of 2)
40
Outline
getquery.cpp output (2 of 2)
41
Other issues
URLs do not allow certain characters Spaces replaced by plus signs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// Fig. 16.12: post.cpp // Demonstrates POST method with XHTML form. #include <iostream> using std::cout; using std::cin; #include <string>
42
Outline
post.cpp (1 of 3)
using std::string;
#include <cstdlib> int main() { char postString[ 1024 ] = ""; // variable to hold POST data string dataString = ""; string nameString = ""; string wordString = ""; Read CONTENT_LENGTH int contentLength = 0;
// content was submitted if ( getenv( "CONTENT_LENGTH" ) ) { contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); cin.read( postString, contentLength ); dataString = postString; } // end if
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
43
// output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output XHTML element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Using POST with Forms</title></head>" Create form as before, << "<body>";
Outline
post.cpp (2 of 3)
but use
method post.
// output XHTML form cout << "<p>Enter one of your favorite words here:</p>" << "<form method = \"post\" action = \"post.cgi\">" << "<input type = \"text\" name = \"word\" />" << "<input type = \"submit\" value = \"Submit Word\" />" << "</form>";
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
// data was sent using POST if ( contentLength > 0 ) { int nameLocation = dataString.find_first_of( "word=" ) + 5; int endLocation = dataString.find_first_of( "&" ) - 1; // retrieve entered word wordString = dataString.substr( nameLocation, endLocation - nameLocation ); // no data was entered in text field if ( wordString == "" ) cout << "<p>Please enter a word.</p>"; // output word else cout << "<p>Your word is: " << wordString << "</p>"; } // end if // no data was sent else cout << "<p>Please enter a word.</p>"; cout << "</body></html>"; return 0; } // end main
44
Outline
post.cpp (3 of 3)
45
Outline
post.cpp output (1 of 2)
46
Outline
post.cpp output (2 of 2)
47
48
POST data
Standard input
49
16.13 Case Study: An Interactive Web Page Web page to display weekly specials
Query for name and password For simplicity, does not encrypt Opening page static XHTML
POSTs data to portal.cgi portal.cgi display specials, if password correct
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
<?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- Fig. 16.13: travel.html <!-- Bug2Bug Travel Homepage --> -->
50
Outline
travel.html (1 of 1)
<html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Bug2Bug Travel</title> </head> <body> <h1>Welcome to Bug2Bug Travel</h1> <form method = "post" action = "/cgi-bin/portal.cgi"> <p>Please enter your name:</p> <input type = "text" name = "namebox" /> <input type = "password" name = "passwordbox" /> <p>password is not encrypted</p> <input type = "submit" name = "button" /> </form> </body> </html>
51
Outline
travel.html output (1 of 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// Fig. 16.14: portal.cpp // Handles entry to Bug2Bug Travel. #include <iostream> using std::cout; using std::cin; #include <string>
52
Outline
portal.cpp (1 of 3)
using std::string;
#include <cstdlib> int main() { char postString[ 1024 ] = ""; string dataString = ""; string nameString = ""; string passwordString = ""; int contentLength = 0; // data was posted if ( getenv( "CONTENT_LENGTH" ) ) contentLength = atoi( getenv( "CONTENT_LENGTH" ) );
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
53
// search string for input data int namelocation = dataString.find( "namebox=" ) + 8; int endNamelocation = dataString.find( "&" );
Outline
portal.cpp (2 of 3)
int password = dataString.find( "passwordbox=" ) + 12; int endPassword = dataString.find( "&button" ); // get values for name and password nameString = dataString.substr( namelocation, endNamelocation - namelocation ); passwordString = dataString.substr( password, endPassword password ); // output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">";
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
// output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Bug2Bug Travel</title></head>" << "<body>"; // output specials cout << "<h1>Welcome " << nameString << "!</h1>" << "<p>Here are our weekly specials:</p>" << "<ul><li>Boston to Taiwan ($875)</li>" << "<li>San Diego to Hong Kong ($750)</li>" Check password, display << "<li>Chicago to Mexico City ($568)</li></ul>";
54
Outline
portal.cpp (3 of 3)
special if correct.
// password is correct if ( passwordString == "coast2coast" ) cout << "<hr /><p>Current member special: " << "Seattle to Tokyo ($400)</p>"; // password was incorrect else cout << "<p>Sorry. You have entered an incorrect " << "password</p>";
55
Outline
portal.cpp output (1 of 2)
56
Outline
portal.cpp output (2 of 2)
57
58
Expiration date
expires=+30d; Last for 30 days expires=Friday, 14-MAY-10 16:00:00 GMT;
Path
Specifies which servers in domain can read cookie If empty, any server in domain can read path=\n
2003 Prentice Hall, Inc. All rights reserved.
59
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
<?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- Fig. 16.15: cookieform.html --> <!-- Cookie Demonstration --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Writing a cookie to the client computer</title> </head> <body> <h1>Click Write Cookie to save your cookie data.</h1> <form method = "post" action = "/cgi-bin/writecookie.cgi"> <p>Name:<br /> <input type = "text" name = "name" /> </p>
60
Outline
cookieform.html (1 of 2)
26 27 28 29 30 31 32 33 34 35 36 37
61
<p>Favorite Color:<br /> <input type = "text" name = "color" /> </p> <p> <input type = "submit" name = "button" /> </p> </form> </body> </html>
Outline
cookieform.html (2 of 2)
62
Outline
cookieform.html output (1 of 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// Fig. 16.16: writecookie.cpp // Program to write a cookie to a client's machine. #include <iostream> using std::cout; using std::cin; #include <cstdlib> #include <string> using std::string; int main() { char query[ 1024 ] = ""; string dataString = ""; string nameString = ""; string ageString = ""; string colorString = ""; int contentLength = 0;
63
Outline
writecookie.cpp (1 of 4)
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// data was entered if ( getenv( "CONTENT_LENGTH" ) ) { contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); // read data from standard input cin.read( query, contentLength ); dataString = query; // search string for data and store locations int nameLocation = dataString.find( "name=" ) + 5; int endName = dataString.find( "&" ); int ageLocation = dataString.find( "age=" ) + 4; int endAge = dataString.find( "&color" ); int colorLocation = dataString.find( "color=" ) + 6; int endColor = dataString.find( "&button" ); // get value for user's name nameString = dataString.substr( nameLocation, endName nameLocation );
64
Outline
writecookie.cpp (2 of 4)
// get value for user's age if ( ageLocation > 0 ) ageString = dataString.substr( ageLocation, endAge ageLocation );
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
// get value for user's favorite color if ( colorLocation > 0 ) colorString = dataString.substr( colorLocation, Set cookie data (comes endColor - colorLocation );
65
Outline
before
writecookie.cpp (3 of 4)
other headers).
// set cookie cout << "Set-Cookie: Name=" << nameString << "age:" << ageString << "color:" << colorString << "; expires=" << expires << "; path=\n"; } // end if // output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Cookie Saved</title></head>" << "<body>";
79 80 81 82 83 84 85 86 87 88 89 90 91
// output user's information cout << "<p>The cookies have been set with the following" << " data:</p>" << "<p>Name: " << nameString << "<br/></p>" << "<p>Age:" << ageString << "<br/></p>" << "<p>Color:" << colorString << "<br/></p>" << "<p>Click <a href=\"/cgi-bin/read_cookie.cgi\">" << "here</a> to read saved cookie data:</p>" << "</body></html>"; return 0; } // end main
66
Outline
writecookie.cpp (4 of 4)
67
Outline
writecookie.cpp output (1 of 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// Fig. 16.17: readcookie.cpp // Program to read cookie data. #include <iostream> using std::cout; using std::cin; #include <cstdlib> #include <string> using std::string; int main() { string dataString = ""; string nameString = ""; string ageString = ""; string colorString = "";
68
Outline
readcookie.cpp (1 of 3)
dataString = getenv( "HTTP_COOKIE" ); // search through cookie data string int nameLocation = dataString.find( "Name=" ) + 5; int endName = dataString.find( "age:" );
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
int ageLocation = dataString.find( "age:" ) + 4; int endAge = dataString.find( "color:" ); int colorLocation = dataString.find( "color:" ) + 6; // store cookie data in strings nameString = dataString.substr( nameLocation, endName nameLocation ); ageString = dataString.substr( ageLocation, endAge ageLocation); colorString = dataString.substr( colorLocation ); // output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Read Cookies</title></head>" << "<body>";
69
Outline
readcookie.cpp (2 of 3)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// data was found if ( dataString != "" ) cout << "<h3>The following data is saved in a cookie on" << " your computer</h3>" << "<p>Name: " << nameString << "<br/></p>" << "<p>Age: " << ageString << "<br/></p>" << "<p>Color: " << colorString << "<br/></p>"; // no data was found else cout << "<p>No cookie data.</p>"; cout << "</body></html>"; return 0; } // end main
70
Outline
readcookie.cpp (3 of 3)
71
Outline
readcookie.cpp output (1 of 1)
72
Example
Post data to clients.dat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- Fig. 16.18: savefile.html <!-- Form to input client information --> -->
73
Outline
savefile.html output (1 of 2)
<html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Please enter your contact information</title> </head> <body> <p>Please enter your information in the form below.</p> <p>Note: You must fill in all fields.</p> <form method = "post" action = "/cgi-bin/savefile.cgi"> <p> First Name: <input type = "text" name = "firstname" size = "10" /> Last Name: <input type = "text" name = "lastname" size = "15" /> </p>
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
<p> Address: <input type = "text" name = "address" size = "25" /> <br /> Town: <input type = "text" name = "town" size = "10" /> State: <input type = "text" name = "state" size = "2" /> <br/> Zip Code: <input type = "text" name = "zipcode" size = "5" /> Country: <input type = "text" name = "country" size = "10" /> </p> <p> E-mail Address: <input type = "text" name = "email" /> </p> <input type = "submit" value = "Enter" /> <input type = "reset" value = "Clear" /> </form> </body> </html>
74
Outline
savefile.html output (2 of 2)
75
Outline
savefile.html output (1 of 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// Fig. 16.19: savefile.cpp // Program to enter user's contact information into a // server-side file. #include <iostream> using using using using std::cerr; std::cout; std::cin; std::ios;
76
Outline
savefile.cpp (1 of 7)
#include <fstream> using std::ofstream; #include <string> using std::string; #include <cstdlib> int main() { char postString[ 1024 ] = ""; int contentLength = 0;
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// variables to store user data string dataString = ""; string firstname = ""; string lastname = ""; string address = ""; string town = ""; string state = ""; string zipcode = ""; string country = ""; string email = ""; // data was posted if ( getenv( "CONTENT_LENGTH" ) ) contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); cin.read( postString, contentLength ); dataString = postString; // search for first '+' character int charLocation = dataString.find( "+" ); // search for next '+' character while ( charLocation < string::npos ) { dataString.replace( charLocation, 1, " " ); charLocation = dataString.find( "+", charLocation + 1 ); } // end while
77
Outline
savefile.cpp (2 of 7)
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
78
// find location of firstname int firstStart = dataString.find( "firstname=" ) + 10; int endFirst = dataString.find( "&lastname" ); firstname = dataString.substr( firstStart, endFirst - firstStart ); // find location of lastname int lastStart = dataString.find( "lastname=" ) + 9; int endLast = dataString.find( "&address" ); lastname = dataString.substr( lastStart, endLast - lastStart ); // find location of address int addressStart = dataString.find( "address=" ) + 8; int endAddress = dataString.find( "&town" ); address = dataString.substr( addressStart, endAddress - addressStart );
Outline
savefile.cpp (3 of 7)
// find location of town int townStart = dataString.find( "town=" ) + 5; int endTown = dataString.find( "&state" );
town = dataString.substr( townStart, endTown - townStart);
// find location of state int stateStart = dataString.find( "state=" ) + 6; int endState = dataString.find( "&zipcode" ); state = dataString.substr( stateStart, endState - stateStart ); // find location of zip code int zipStart = dataString.find( "zipcode=" ) + 8; int endZip = dataString.find( "&country" ); zipcode = dataString.substr( zipStart, endZip - zipStart ); // find location of country int countryStart = dataString.find( "country=" ) + 8; int endCountry = dataString.find( "&email" ); country = dataString.substr( countryStart, endCountry - countryStart ); // find location of e-mail address int emailStart = dataString.find( "email=" ) + 6; int endEmail = dataString.find( "&submit" ); email = dataString.substr( emailStart, endEmail - emailStart );
79
Outline
savefile.cpp (4 of 7)
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
// output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">";
80
Outline
savefile.cpp (5 of 7)
// output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Contact Information entered" Open clients.txt << "</title></head><body>";
for
writing.
// output to file ofstream outFile( "clients.txt", ios::app ); // file was not opened properly if ( !outFile ) { cerr << "Error: could not open contact file."; exit( 1 ); } // end if
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
81
// append data to clients.txt file outFile << firstname << " " << lastname << "\n" << address << "\n" << town << " " << state << " " << country << " " << zipcode << "\n" << email << "\n\n"; // output data to user cout << "<table><tbody>" << "<tr><td>First Name:</td><td>" << firstname << "</td></tr>" << "<tr><td>Last Name:</td><td>" << lastname << "</td></tr>" << "<tr><td>Address:</td><td>" << address << "</td></tr>" << "<tr><td>Town:</td><td>" << town << "</td></tr>" << "<tr><td>State:</td><td>" << state << "</td></tr>" << "<tr><td>Zip Code:</td><td>" << zipcode << "</td></tr>" << "<tr><td>Country:</td><td>" << country << "</td></tr>" << "<tr><td>Email:</td><td>" << email << "</td></tr>" << "</tbody></table>" << "</body>\n</html>\n";
Outline
savefile.cpp (6 of 7)
82
Outline
savefile.cpp (7 of 7) savefile.cpp output (1 of 1)
clients.dat: Jane Doe 123 Main Street Boston MA USA 12345 jane@doe.com
83
This example
Buy books from virtual bookstore Four scripts, 2 server-side files, cookies First script: user login
Option to create new membership Add name/password pairs to userdata.txt
Password validation
2003 Prentice Hall, Inc. All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 16.21: login.cpp // Program to output an XHTML form, verify the // username and password entered, and add members. #include <iostream> using using using using std::cerr; std::cout; std::cin; std::ios;
84
Outline
login.cpp (1 of 11)
#include <fstream> using std::ifstream; using std::ofstream; #include <string> using std::string; #include <cstdlib> void header(); void writeCookie();
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
int main() { char query[ 1024 ] = ""; string dataString = ""; // strings to store username and password string userName = ""; string passWord = ""; string newCheck = ""; int contentLength = 0; int endPassword = 0; // data was posted if ( getenv( "CONTENT_LENGTH" ) ) { // retrieve query string contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); cin.read( query, contentLength ); dataString = query; // find username location int userLocation = dataString.find( "user=" ) + 5; int endUser = dataString.find( "&" );
85
Outline
login.cpp (2 of 11)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
// find password location int passwordLocation = dataString.find( "password=" ) + 9; endPassword = dataString.find( "&new" ); // new membership requested if ( endPassword > 0 ) passWord = dataString.substr( passwordLocation, endPassword - passwordLocation ); // existing member else passWord = dataString.substr( passwordLocation ); userName = dataString.substr( userLocation, endUser userLocation ); } // end if
86
Outline
login.cpp (3 of 11)
// no data was retrieved if ( dataString == "" ) { header(); cout << "<p>Please login.</p>";
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
// output login form cout << "<form method = \"post\" " << "action = \"/cgi-bin/login.cgi\"><p>" << "User Name: " << "<input type = \"text\" name = \"user\"/><br/>" << "Password: " << "<input type = \"password\" " << "name = \"password\"/><br/>" << "New? <input type = \"checkbox\"" << " name = \"new\" " << "value = \"1\"/></p>" << "<input type = \"submit\" value = \"login\"/>" << "</form>"; } // end if
87
Outline
login.cpp (4 of 11)
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
// process entered data else { // add new member if ( endPassword > 0 ) { string fileUsername = ""; string filePassword = ""; bool nameTaken = false;
88
Outline
login.cpp (5 of 11)
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
89
// user name is taken if ( nameTaken ) { header(); cout << "<p>This name has already been taken.</p>" << "<a href=\"/cgi-bin/login.cgi\">" << "Try Again</a>"; } // end if
Outline
login.cpp (6 of 11)
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
// could not open file if ( !userData ) { cerr << "Could not open database."; exit( 1 ); } // end if
90
Outline
After password saved login.cpp to file, (7 of 11) provide link for next page.
// write user data to file userData << "\n" << userName << "\n" << passWord;
cout << "<p>Your information has been processed." << "<a href=\"/cgi-bin/shop.cgi\">" << "Start Shopping</a></p>";
} // end else } // end if // search for password if entered else { // strings to store username and password from file string fileUsername = ""; string filePassword = ""; bool authenticated = false; bool userFound = false;
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
// open password file ifstream userData( "userdata.txt", ios::in ); // could not open file if ( !userData ) { cerr << "Could not open database."; exit( 1 ); } // end if
91
Outline
login.cpp (8 of 11)
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
cout << "<p>Thank you for returning, " << userName << "!</p>" << "<a href=\"/cgi-bin/shop.cgi\">" << "Start Shopping</a>"; } // end if // user not authenticated else { header();
92
Outline
login.cpp (9 of 11)
// password is incorrect if ( userFound ) cout << "<p>You have entered an incorrect " << "password. Please try again.</p>" << "<a href=\"/cgi-bin/login.cgi\">" << "Back to login</a>"; // user is not registered else cout << "<p>You are not a registered user.</p>" << "<a href=\"/cgi-bin/login.cgi\">" << "Register</a>"; } // end else } // end else } // end if
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
93
cout << "</body>\n</html>\n"; return 0; } // end main // function to output header void header() { // output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Login Page</title></head>" << "<body>"; } // end header
Outline
login.cpp (10 of 11)
// function to write cookie data void writeCookie() { string expires = "Friday, 14-MAY-04 16:00:00 GMT"; cout << "Set-Cookie: CART=; expires=" << expires << "; path=\n"; } // end writeCookie
94
Outline
login.cpp (11 of 11)
login.cpp output (1 of 3)
95
Outline
login.cpp output (2 of 3)
96
Outline
login.cpp output (3 of 3)
97
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 16.22: shop.cpp // Program to display available books. #include <iostream> using using using using std::cerr; std::cout; std::cin; std::ios;
98
Outline
shop.cpp (1 of 5)
#include <istream>
#include <fstream> using std::ifstream; using std::ofstream; #include <string> using std::string; #include <cstdlib>
void header();
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
int main() { // variables to store product information char book[ 50 ] = ""; char year[ 50 ] = ""; char isbn[ 50 ] = ""; char price[ 50 ] = ""; string string string string bookString = ""; yearString = ""; isbnString = ""; priceString = "";
99
Outline
shop.cpp (2 of 5)
bool nameTaken = false; // open file for input ifstream userData( "catalog.txt", ios::in ); // file could not be opened if ( !userData ) { cerr << "Could not open database."; exit( 1 ); } // end if header(); // output header
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// output available books cout << "<center><br/>Books available for sale<br/>" << "<a href=\"/cgi-bin/logout.cgi\">Sign Out" << "</a><br/><br/>" << "<table border = \"1\" cellpadding = \"7\" >"; // file is open while ( userData ) {
100
Outline
shop.cpp (3 of 5)
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
101
<< << << << bookString << "</td>" yearString << "</td>" isbnString << "</td>" priceString << "</td>";
Outline
shop.cpp (4 of 5)
// output form with buy button cout << "<td><form method=\"post\" " << "action=\"/cgi-bin/viewcart.cgi\">" << "<input type=\"hidden\" name=\"add\"" << "value=\"true\"/>" << "<input type=\"hidden\" name=\"isbn\"" << "value=\"" << isbnString << "\"/>" << "<input type=\"submit\"" << "value=\"Buy\"/>\n" << "</form></td>\n";
cout << "</tr>\n";
} // end while
cout << "</table></center></body></html>"; return 0; }
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
102
// function to output header information void header() { // output header cout << "Content-Type: text/html\n\n"; // output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" << "/DTD/xhtml1-transitional.dtd\">"; // output html element and some of its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Login Page</title></head>" << "<body>"; } // end header
Outline
shop.cpp (5 of 5)
103
Outline
shop.cpp output (1 of 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 16.23: viewcart.cpp // Program to view books in the shopping cart. #include <iostream> using using using using std::cerr; std::cout; std::cin; std::ios;
104
Outline
viewcart.cpp (1 of 7)
#include <istream>
#include <fstream> using std::ifstream; using std::ofstream; #include <string> using std::string; #include <cstdlib>
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
int main() { // variable to store query string char query[ 1024 ] = ""; char *cartData; // variable to hold contents of cart string dataString = ""; string cookieString = ""; string isbnEntered = ""; int contentLength = 0; // retrieve cookie data if ( getenv( "HTTP_COOKIE" ) ) { cartData = getenv( "HTTP_COOKIE" ); cookieString = cartData; } // end if // data was entered if ( getenv( "CONTENT_LENGTH" ) ) { contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); cin.read( query, contentLength ); dataString = query; // find location of isbn value int addLocation = dataString.find( "add=" ) + 4; int endAdd = dataString.find( "&isbn" ); int isbnLocation = dataString.find( "isbn=" ) + 5;
105
Outline
viewcart.cpp (2 of 7)
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
// retrieve isbn number to add to cart isbnEntered = dataString.substr( isbnLocation ); // write cookie string expires = "Friday, 14-MAY-10 16:00:00 GMT"; int cartLocation = cookieString.find( "CART=" ) + 5; // cookie exists if ( cartLocation > 0 ) cookieString = cookieString.substr( cartLocation ); // no cookie data exists if ( cookieString == "" ) cookieString = isbnEntered; // cookie data exists else cookieString += "," + isbnEntered; // set cookie cout << "Set-Cookie: CART=" << cookieString << "; expires=" << expires << "; path=\n"; } // end if
106
Outline
viewcart.cpp (3 of 7)
78 // output header 79 cout << "Content-Type: text/html\n\n"; 80 81 // output XML declaration and DOCTYPE 82 cout << "<?xml version = \"1.0\"?>" 83 << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " 84 << "Transitional//EN\" \"http://www.w3.org/TR/xhtml1" 85 << "/DTD/xhtml1-transitional.dtd\">"; 86 87 // output html element and some of its contents 88 cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" 89 << "<head><title>Shopping Cart</title></head>" 90 << "<body><center>" 91 << "<p>Here is your current order:</p>"; 92 93 // cookie data exists 94 if ( cookieString != "" ) 95 outputBooks( cookieString, isbnEntered ); 96 97 cout << "</body></html>\n"; 98 return 0; 99 100 } // end main
107
Outline
viewcart.cpp (4 of 7)
101 102 // function to output books in catalog.txt 103 void outputBooks( const string &cookieRef, const string &isbnRef ) 104 { 105 char book[ 50 ] = ""; 106 char year[ 50 ] = ""; 107 char isbn[ 50 ] = ""; 108 char price[ 50 ] = ""; 109 110 string bookString = ""; 111 string yearString = ""; 112 string isbnString = ""; 113 string priceString = ""; 114 115 // open file for input 116 ifstream userData( "catalog.txt", ios::in ); 117 118 // file could not be opened 119 if ( !userData ) { 120 cerr << "Could not open database."; 121 exit( 1 ); 122 } // end if 123
108
Outline
viewcart.cpp (5 of 7)
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
// output link to log out and table to display books cout << "<a href=\"/cgi-bin/logout.cgi\">Sign Out"; cout << "</a><br><br>"; cout << "<table border = 1 cellpadding = 7 >"; // file is open while ( userData ) { // retrieve book information userData.getline( book, 50 ); bookString = book; // retrieve year information userData.getline( year, 50 ); yearString = year; // retrieve isbn number userData.getline( isbn, 50 ); isbnString = isbn; // retrieve price userData.getline( price, 50 ); priceString = price;
109
Outline
viewcart.cpp (6 of 7)
148 int match = cookieRef.find( isbn ); 149 150 // match has been made 151 if ( match > 0 || isbnRef == isbnString ) { 152 153 // output table row with book information 154 cout << "<tr>" 155 << "<form method=\"post\"" 156 << "action=\"/cgi-bin/viewcart.cgi\">" 157 << "<td>" << bookString << "</td>" 158 << "<td>" << yearString << "</td>" 159 << "<td>" << isbnString << "</td>" 160 << "<td>" << priceString << "</td>"; 161 162 } // end if 163 164 cout << "</form></tr>"; 165 166 } // end while 167 168 // output link to add more books 169 cout << "<a href=\"/cgi-bin/shop.cgi\">Back to book list</a>"; 170 } // end outputBooks
110
Outline
viewcart.cpp (7 of 7)
111
Outline
viewcart.cpp output (1 of 1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 16.24: logout.cpp // Program to log out of the system. #include <iostream> using std::cout; #include <string> using std::string; #include <ctime> #include <cstdlib> void writeCookie(); int main() { // write the cookie writeCookie();
112
Outline
logout.cpp (1 of 3)
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
// output XML declaration and DOCTYPE cout << "<?xml version = \"1.0\"?>" << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 " << "Transitional//EN\""; // output html element and its contents cout << "<html xmlns = \"http://www.w3.org/1999/xhtml\">" << "<head><title>Logged Out</title></head>" << "<body>" << "<center><p>You are now logged out<br>" << "You will be billed accordingly<br>" << "To login again, " << "<a href=\"/cgi-bin/login.cgi\">click here</a>" << "</body></html>\n"; return 0; } // end main
113
Outline
logout.cpp (2 of 3)
44 45 46 47 48 49 50 51 52 53 54
// function to write cookie void writeCookie() { // string containing expiration date string expires = "Friday, 14-MAY-10 16:00:00 GMT"; // set cookie cout << "Set-Cookie: CART=; expires=" << expires << "; path=\n"; } // end writeCookie
114
Outline
logout.cpp (3 of 3) logout.cpp output (1 of 1)