test.cpp

Go to the documentation of this file.
00001 /* -*-mode:c++; c-file-style: "gnu";-*- */
00002 /*
00003  *  $Id: test_8cpp-source.html,v 1.3 2008/01/19 21:53:50 sebdiaz Exp $
00004  *
00005  *  Copyright (C) 1996 - 2004 Stephen F. Booth <sbooth@gnu.org>
00006  *                       2007 Sebastien DIAZ <sebastien.diaz@gmail.com>
00007  *  Part of the GNU cgicc library, http://www.gnu.org/software/cgicc
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU Lesser General Public
00011  *  License as published by the Free Software Foundation; either
00012  *  version 3 of the License, or (at your option) any later version.
00013  *
00014  *  This library is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  *  Lesser General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU Lesser General Public
00020  *  License along with this library; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 
00022  */
00023 
00030 #include <new>
00031 #include <string>
00032 #include <vector>
00033 #include <stdexcept>
00034 #include <iostream>
00035 #include <cstdlib>
00036 
00037 #include "cgicc/CgiDefs.h"
00038 #include "cgicc/Cgicc.h"
00039 #include "cgicc/HTTPHTMLHeader.h"
00040 #include "cgicc/HTMLClasses.h"
00041 
00042 #if HAVE_SYS_UTSNAME_H
00043 #  include <sys/utsname.h>
00044 #endif
00045 
00046 #if HAVE_SYS_TIME_H
00047 #  include <sys/time.h>
00048 #endif
00049 
00050 #include "styles.h"
00051 
00052 using namespace std;
00053 using namespace cgicc;
00054 
00055 // Function prototypes
00056 void dumpEnvironment(const CgiEnvironment& env);
00057 void dumpList(const Cgicc& formData);
00058 void showForm(const Cgicc& formData);
00059 
00060 // Print the form for this CGI
00061 void
00062 printForm(const Cgicc& cgi)
00063 {
00064   cout << "<form method=\"post\" action=\"" 
00065        << cgi.getEnvironment().getScriptName() << "\">" << endl;
00066     
00067   cout << "<table>" << endl;
00068 
00069   cout << "<tr><td class=\"title\">Your name</td>"
00070        << "<td class=\"form\">"
00071        << "<input type=\"text\" name=\"name\" value=\"Uncle Bob\" />"
00072        << "</td></tr>" << endl;
00073 
00074   cout << "<tr><td class=\"title\">Your salary in millions<br />(80-120)</td>"
00075        << "<td class=\"form\">"
00076        << "<input type=\"text\" name=\"bucks\" value=\"93\" />"
00077        << "</td></tr>" << endl;
00078 
00079   cout << "<tr><td class=\"title\">Hours you've wasted on the web</td>"
00080        << "<td class=\"form\">"
00081        << "<input type=\"text\" name=\"time\" value=\"100\" />"
00082        << "</td></tr>" << endl;
00083 
00084   cout << "<tr><td class=\"title\">Your thoughts (on anything)</td>"
00085        << "<td class=\"form\">"
00086        << "<textarea name=\"thoughts\" rows=\"4\" cols=\"40\">"
00087        << "I don't have any!</textarea>" << "</td></tr>" << endl;
00088 
00089   cout << "<tr><td class=\"title\">Are you hungry?</td>"
00090        << "<td class=\"form\">"
00091        << "<input type=\"checkbox\" name=\"hungry\" checked=\"checked\" />"
00092        << "Yes</td></tr>" << endl;
00093 
00094   cout << "<tr><td class=\"title\">Your favorite flavors of ice cream</td>"
00095        << "<td class=\"form\">"
00096        << "<select name=\"flavors\" multiple=\"multiple\">"
00097        << "<option value=\"cookie dough\">Cookie Dough</option>"
00098        << "<option value=\"rocky road\">Rocky Road</option>"
00099        << "<option value=\"chocolate\">Chocolate</option>"
00100        << "<option value=\"strawberry\">Strawberry</option>"
00101        << "<option value=\"vanilla\">Vanilla</option>"
00102        << "</select>" << "</td></tr>" << endl;
00103 
00104   cout << "<tr><td class=\"title\">Your hair color</td>"
00105        << "<td class=\"form\">"
00106        << "<select name=\"hair\">"
00107        << "<option value=\"blond\">Blond</option>"
00108        << "<option value=\"brown\">Brown</option>"
00109        << "<option value=\"red\">Red</option>"
00110        << "<option value=\"black\">Black</option>"
00111        << "<option value=\"white\">White</option>"
00112        << "<option value=\"green\">Green</option>"
00113        << "<option value=\"multicolored\">Multicolored</option>"
00114        << "</select>" << "</td></tr>" << endl;
00115 
00116   cout << "<tr><td class=\"title\">Your web browser</td>"
00117        << "<td class=\"form\">"
00118        << "<input type=\"radio\" name=\"browser\" value=\"Konqueror\""
00119        << " checked=\"checked\" />Konqeuror"
00120        << "<input type=\"radio\" name=\"browser\" value=\"Lynx\" />Lynx"
00121        << "<input type=\"radio\" name=\"browser\" value=\"Mozilla\" />Mozilla"
00122        << "<input type=\"radio\" name=\"browser\" value=\"IE\" />IE"
00123        << "<input type=\"radio\" name=\"browser\" value=\"Other\" />Other"
00124        << "</td></tr>" << endl;
00125 
00126   cout << "<tr><td class=\"title\">Your favorite authors</td>"
00127        << "<td class=\"form\">"
00128        << "<input type=\"checkbox\" name=\"authors\" value=\"O'Brian\" />"
00129        << "O'Brian"
00130        << "<input type=\"checkbox\" name=\"authors\" value=\"Feynman\" />" 
00131        << "Feynman"
00132        << "<input type=\"checkbox\" name=\"authors\" value=\"Camus\" />Camus"
00133        << "<input type=\"checkbox\" name=\"authors\" value=\"Conrad\" />Conrad"
00134        << "<input type=\"checkbox\" name=\"authors\" value=\"Vergil\" />Vergil"
00135        << "<input type=\"checkbox\" name=\"authors\" value=\"Plato\" />Plato"
00136        << "</td></tr>" << endl;
00137 
00138   cout << "<tr><td class=\"title\">In the output, show</td>"
00139        << "<td class=\"form\">"
00140        << "<input type=\"checkbox\" name=\"showEnv\" checked=\"checked\" />"
00141        << "Data from CgiEnvironment<br />"
00142        << "<input type=\"checkbox\" name=\"showFE\" checked=\"checked\" />"
00143        << "All FormEntries<br />"
00144        << "<input type=\"checkbox\" name=\"showForm\" checked=\"checked\" />"
00145        << "Data from Cgicc"
00146        << "</td></tr>" << endl;
00147 
00148   cout << "<tr><td class=\"title\">Exception Handling</td>"
00149        << "<td class=\"form\">"
00150        << "<input type=\"checkbox\" name=\"throw\" />"
00151        << "Throw an exception to test error handling"
00152        << "</td></tr>" << endl;
00153 
00154   cout << "<tr><td class=\"title\">Save and Restore</td>"
00155        << "<td class=\"form\">"
00156        << "<input type=\"checkbox\" name=\"save\" />"
00157        <<" Save submission to a file<br />"
00158        << "<input type=\"checkbox\" name=\"restore\" />"
00159        << "Restore data from the last saved submission"
00160        << "</td></tr>" << endl;
00161 
00162   cout << "</table>" << endl;
00163 
00164   cout << "<div class=\"center\"><p>"
00165        << "<input type=\"submit\" name=\"submit\"  value=\"Submit\" />"
00166        << "<input type=\"reset\" value=\"Nevermind\" />"
00167        << "</p></div></form>" << endl;
00168 }
00169 
00170 // Main Street, USA
00171 int
00172 main(int /*argc*/, 
00173      char ** /*argv*/)
00174 {
00175   try {
00176 #if HAVE_GETTIMEOFDAY
00177     timeval start;
00178     gettimeofday(&start, NULL);
00179 #endif
00180 
00181     // Create a new Cgicc object containing all the CGI data
00182     Cgicc cgi;
00183     
00184     // If the user wants to throw an exception, go ahead and do it
00185     if(cgi.queryCheckbox("throw") && ! cgi.queryCheckbox("restore"))
00186       throw std::runtime_error("User-requested Exception thrown in main()");
00187     
00188     // Output the HTTP headers for an HTML document, and the HTML 4.0 DTD info
00189     cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
00190     cout << html().set("lang", "en").set("dir", "ltr") << endl;
00191 
00192     // Set up the page's header and title.
00193     // I will put in lfs to ease reading of the produced HTML. 
00194     cout << head() << endl;
00195 
00196     // Output the style sheet portion of the header
00197     cout << style() << comment() << endl;
00198     cout << styles;
00199     cout << comment() << style() << endl;
00200 
00201     cout << title() << "GNU cgicc v" << cgi.getVersion() << " Test" 
00202          << title() << endl;
00203 
00204     cout << head() << endl;
00205     
00206     // Start the HTML body
00207     cout << body() << endl;
00208 
00209     cout << h1() << "GNU cgi" << span("cc").set("class","red")
00210          << " v"<< cgi.getVersion() << " Test" << h1() << endl;
00211     
00212     // Get a pointer to the environment
00213     const CgiEnvironment& env = cgi.getEnvironment();
00214     
00215     // Generic thank you message
00216     cout << comment() << "This page generated by cgicc for "
00217          << env.getRemoteHost() << comment() << endl;
00218     cout << h4() << "Thanks for using cgi" << span("cc").set("class", "red") 
00219          << ", " << env.getRemoteHost() 
00220          << '(' << env.getRemoteAddr() << ")!" << h4() << endl;  
00221     
00222     // If the user wants to save the submission, do it
00223     if(cgi.queryCheckbox("save")) {
00224       // Make sure the save file is readable and writable by the CGI process
00225       cgi.save("save");
00226       cout << p(h2("Data Saved")) << endl;
00227       
00228       cout << cgicc::div().set("class", "notice") << endl;
00229       cout << "Your data has been saved, and may be restored (by anyone) "
00230            << "via the same form." << endl << cgicc::div() << p() << endl;
00231     }
00232 
00233     // If the user wants to restore from the last submission, do it
00234     if(cgi.queryCheckbox("restore")) {
00235       cgi.restore("save");
00236       cout << p(h2("Data Restored")) << endl;
00237       
00238       cout << cgicc::div().set("class", "notice") << endl;
00239       cout << "The data displayed has been restored from a file on disk."
00240            << endl << cgicc::div() << p() << endl;
00241     }
00242     
00243     // If the user requested a dump of the environment,
00244     // create a simple table showing the values of the 
00245     // environment variables
00246     if(cgi.queryCheckbox("showEnv"))
00247       dumpEnvironment(env);
00248     
00249     // If the user requested, print out the raw form data from 
00250     // the vector of FormEntries.  This will contain every 
00251     // element in the list.
00252     // This is one of two ways to get at form data, the other
00253     // being the use of Cgicc's getElement() methods.  
00254     if(cgi.queryCheckbox("showFE"))
00255       dumpList(cgi);
00256     
00257     // If the user requested data via Cgicc's getElement() methods, do it.
00258     // This is different than the use of the list of FormEntries 
00259     // because it requires prior knowledge of the name of form elements.
00260     // Usually they will be known, but you never know.
00261     if(cgi.queryCheckbox("showForm"))
00262       showForm(cgi);
00263 
00264     // Print out the form to do it again
00265     cout << br() << endl;
00266     printForm(cgi);
00267     cout << hr().set("class", "half") << endl;
00268     
00269     // Information on cgicc
00270     cout << cgicc::div().set("align","center").set("class","smaller") << endl;
00271     cout << "GNU cgi" << span("cc").set("class","red") << " v";
00272     cout << cgi.getVersion() << br() << endl;
00273     cout << "Compiled at " << cgi.getCompileTime();
00274     cout << " on " << cgi.getCompileDate() << br() << endl;
00275 
00276     cout << "Configured for " << cgi.getHost();  
00277 #if HAVE_UNAME
00278     struct utsname info;
00279     if(uname(&info) != -1) {
00280       cout << ". Running on " << info.sysname;
00281       cout << ' ' << info.release << " (";
00282       cout << info.nodename << ")." << endl;
00283     }
00284 #else
00285     cout << "." << endl;
00286 #endif
00287 
00288 #if HAVE_GETTIMEOFDAY
00289     // Information on this query
00290     timeval end;
00291     gettimeofday(&end, NULL);
00292     long us = ((end.tv_sec - start.tv_sec) * 1000000)
00293       + (end.tv_usec - start.tv_usec);
00294 
00295     cout << br() << "Total time for request = " << us << " us";
00296     cout << " (" << static_cast<double>(us/1000000.0) << " s)";
00297 #endif
00298 
00299     // End of document
00300     cout << cgicc::div() << endl;
00301     cout << body() << html() << endl;
00302 
00303     // No chance for failure in this example
00304     return EXIT_SUCCESS;
00305   }
00306 
00307   // Did any errors occur?
00308   catch(const std::exception& e) {
00309 
00310     // This is a dummy exception handler, as it doesn't really do
00311     // anything except print out information.
00312 
00313     // Reset all the HTML elements that might have been used to 
00314     // their initial state so we get valid output
00315     html::reset();      head::reset();          body::reset();
00316     title::reset();     h1::reset();            h4::reset();
00317     comment::reset();   td::reset();            tr::reset(); 
00318     table::reset();     cgicc::div::reset();    p::reset(); 
00319     a::reset();         h2::reset();            colgroup::reset();
00320 
00321     // Output the HTTP headers for an HTML document, and the HTML 4.0 DTD info
00322     cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
00323     cout << html().set("lang","en").set("dir","ltr") << endl;
00324 
00325     // Set up the page's header and title.
00326     // I will put in lfs to ease reading of the produced HTML. 
00327     cout << head() << endl;
00328 
00329     // Output the style sheet portion of the header
00330     cout << style() << comment() << endl;
00331     cout << "body { color: black; background-color: white; }" << endl;
00332     cout << "hr.half { width: 60%; align: center; }" << endl;
00333     cout << "span.red, STRONG.red { color: red; }" << endl;
00334     cout << "div.notice { border: solid thin; padding: 1em; margin: 1em 0; "
00335          << "background: #ddd; }" << endl;
00336 
00337     cout << comment() << style() << endl;
00338 
00339     cout << title("GNU cgicc exception") << endl;
00340     cout << head() << endl;
00341     
00342     cout << body() << endl;
00343     
00344     cout << h1() << "GNU cgi" << span("cc", set("class","red"))
00345          << " caught an exception" << h1() << endl; 
00346   
00347     cout << cgicc::div().set("align","center").set("class","notice") << endl;
00348 
00349     cout << h2(e.what()) << endl;
00350 
00351     // End of document
00352     cout << cgicc::div() << endl;
00353     cout << hr().set("class","half") << endl;
00354     cout << body() << html() << endl;
00355     
00356     return EXIT_SUCCESS;
00357   }
00358 }
00359 
00360 // Print out a table of the CgiEnvironment
00361 void
00362 dumpEnvironment(const CgiEnvironment& env) 
00363 {
00364   // This is just a brain-dead dump of information.
00365   // Almost all of this code is for HTML formatting
00366   cout << h2("Environment information from CgiEnvironment") << endl;
00367   
00368   cout << cgicc::div().set("align","center") << endl;
00369   
00370   cout << table() << endl;
00371   
00372   cout << tr() << td("Request Method").set("class","title") 
00373        << td(env.getRequestMethod()).set("class","data") << tr() << endl;
00374   cout << tr() << td("Path Info").set("class","title") 
00375        << td(env.getPathInfo()).set("class","data") << tr() << endl;
00376   cout << tr() << td("Path Translated").set("class","title") 
00377        << td(env.getPathTranslated()).set("class","data") << tr() << endl;
00378   cout << tr() << td("Script Name").set("class","title") 
00379        << td(env.getScriptName()).set("class","data") << tr() << endl;
00380   cout << tr() << td("HTTP Referrer").set("class","title") 
00381        << td(env.getReferrer()).set("class","data") << tr() << endl;
00382   cout << tr() << td("HTTP Cookie").set("class","title") 
00383        << td(env.getCookies()).set("class","data") << tr() << endl;
00384   cout << tr() << td("Query String").set("class","title") 
00385        << td(env.getQueryString()).set("class","data") << tr() << endl;
00386   cout << tr() << td("Content Length").set("class","title") 
00387        << td().set("class","data") << env.getContentLength() 
00388        << td() << tr() << endl;
00389   cout << tr() << td("Post Data").set("class","title")
00390        << td().set("class","data")
00391        << pre(env.getPostData()).set("class","data") << td() 
00392        << tr() << endl;
00393   cout << tr() << td("Remote Host").set("class","title") 
00394        << td(env.getRemoteHost()).set("class","data") << tr() << endl;
00395   cout << tr() << td("Remote Address").set("class","title") 
00396        << td(env.getRemoteAddr()).set("class","data") << tr() << endl;
00397   cout << tr() << td("Authorization Type").set("class","title") 
00398        << td(env.getAuthType()).set("class","data") << tr() << endl;
00399   cout << tr() << td("Remote User").set("class","title") 
00400        << td(env.getRemoteUser()).set("class","data") << tr() << endl;
00401   cout << tr() << td("Remote Identification").set("class","title") 
00402        << td(env.getRemoteIdent()).set("class","data") << tr() << endl;
00403   cout << tr() << td("Content Type").set("class","title") 
00404        << td(env.getContentType()).set("class","data") << tr() << endl;
00405   cout << tr() << td("HTTP Accept").set("class","title") 
00406        << td(env.getAccept()).set("class","data") << tr() << endl;
00407   cout << tr() << td("User Agent").set("class","title") 
00408        << td(env.getUserAgent()).set("class","data") << tr() << endl;
00409   cout << tr() << td("Server Software").set("class","title") 
00410        << td(env.getServerSoftware()).set("class","data") << tr() << endl;
00411   cout << tr() << td("Server Name").set("class","title") 
00412        << td(env.getServerName()).set("class","data") << tr() << endl;
00413   cout << tr() << td("Gateway Interface").set("class","title") 
00414        << td(env.getGatewayInterface()).set("class","data") << tr() << endl;
00415   cout << tr() << td("Server Protocol").set("class","title") 
00416        << td(env.getServerProtocol()).set("class","data") << tr() << endl;
00417   cout << tr() << td("Server Port").set("class","title") 
00418        << td().set("class","data") << env.getServerPort() 
00419        << td() << tr() << endl;
00420   cout << tr() << td("HTTPS").set("class","title")
00421        << td().set("class","data") << (env.usingHTTPS() ? "true" : "false")
00422        << td() << tr() << endl;
00423   cout << tr() << td("Redirect Request").set("class","title") 
00424        << td(env.getRedirectRequest()).set("class","data") << tr() << endl;
00425   cout << tr() << td("Redirect URL").set("class","title") 
00426        << td(env.getRedirectURL()).set("class","data") << tr() << endl;
00427   cout << tr() << td("Redirect Status").set("class","title") 
00428        << td(env.getRedirectStatus()).set("class","data") << tr() << endl;
00429   
00430   cout << table() << cgicc::div() << endl;
00431 }
00432 
00433 // Print out the value of every form element
00434 void
00435 dumpList(const Cgicc& formData) 
00436 {
00437   cout << h2("Form Data via vector") << endl;
00438   
00439   cout << cgicc::div().set("align","center") << endl;
00440   
00441   cout << table()<< endl;
00442   
00443   cout << tr().set("class","title") << td("Element Name") 
00444        << td("Element Value") << tr() << endl;
00445   
00446   // Iterate through the vector, and print out each value
00447   const_form_iterator iter;
00448   for(iter = formData.getElements().begin(); 
00449       iter != formData.getElements().end(); 
00450       ++iter) {
00451     cout << tr().set("class","data") << td(iter->getName()) 
00452          << td(iter->getValue()) << tr() << endl;
00453   }
00454   cout << table() << cgicc::div() << endl;
00455 }
00456 
00457 // Print out information customized for each element
00458 void
00459 showForm(const Cgicc& formData) 
00460 {
00461 
00462   // I am using an if statement to check if each element is found
00463   cout << h2("Form Data via Cgicc") << endl;
00464   
00465   cout << cgicc::div().set("class","notice") << endl;
00466 
00467   //getElement
00468   const_form_iterator name = formData.getElement("name");
00469   if(name != (*formData).end() && ! name->isEmpty())
00470     cout << "Your name is " << **name << '.' << br() << endl;
00471   else
00472     cout << "You don't have a name." << br() << endl;
00473 
00474   // getElement and getDoubleValue
00475   const_form_iterator salary = formData.getElement("bucks");
00476   if(salary != (*formData).end() && ! salary->isEmpty())
00477     cout << "You make " << (*salary).getDoubleValue(80, 120) 
00478          << " million dollars." << br() << endl;
00479   else
00480     cout << "You don't have a salary." << br() << endl;
00481 
00482   // getElement and getIntegerValue
00483   const_form_iterator hours = formData.getElement("time");
00484   if(hours != (*formData).end() && ! (*hours).isEmpty())
00485     cout << "You've wasted " << (*hours).getIntegerValue() 
00486          << " hours on the web." << br() << endl;
00487   else
00488     cout << "You haven't wasted any time on the web." << br() << endl;
00489 
00490   // getElement and getStrippedValue
00491   const_form_iterator thoughts = formData.getElement("thoughts");
00492   if(thoughts != (*formData).end() && ! (*thoughts).isEmpty()) {
00493     std::string temp = (*thoughts).getStrippedValue();
00494     cout << "Your thoughts: " << temp << br() << endl;
00495   }
00496   else
00497     cout << "You don't have any thoughts!?" << br() << endl;
00498   
00499   // queryCheckbox
00500   if(formData.queryCheckbox("hungry"))
00501     cout << "You are hungry." << br() << endl;
00502   else
00503     cout << "You are not hungry." << br() << endl;
00504 
00505   // getElement
00506   std::vector<FormEntry> flavors;
00507   formData.getElement("flavors", flavors);
00508   if(! flavors.empty()) {
00509     cout << "You like ";
00510     for(std::string::size_type i = 0; i < flavors.size(); i++) {
00511       cout << flavors[i].getValue();
00512       if(i < flavors.size() - 2)
00513         cout << ", ";
00514       else if(i == flavors.size() - 2)
00515         cout << " and ";
00516     }
00517     cout << " ice cream." << br() << endl;
00518   }
00519   else
00520     cout << "You don't like ice cream!?" << br() << endl;
00521   
00522   // getElement
00523   const_form_iterator hair = formData.getElement("hair");
00524   if(hair != (*formData).end())
00525     cout << "Your hair is " << **hair << '.' << br() << endl;
00526   else
00527     cout << "You don't have any hair." << br() << endl;
00528   
00529   cout << "You surf the web with " << formData("browser") << '.' 
00530        << br() << endl;
00531   
00532   // getElement
00533   std::vector<FormEntry> authors;
00534   formData.getElement("authors", authors);
00535   if(! authors.empty()) {
00536     cout << "You like to read books by ";
00537     for(std::string::size_type i = 0; i < authors.size(); ++i) {
00538       cout << authors[i].getValue();
00539       if(i < authors.size() - 2)
00540         cout << ", ";
00541       else if(i == authors.size() - 2)
00542         cout << " and ";
00543     }
00544     cout << "." << br() << endl;
00545   }
00546   else
00547     cout << "You don't like to read!?" << br() << endl;
00548   
00549   cout << cgicc::div() << endl;
00550 }

GNU cgicc - A C++ class library for writing CGI applications
Copyright © 1996 - 2004 Stephen F. Booth
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front Cover Texts, and with no Back-Cover Texts.
Documentation generated Sat Jan 19 21:15:58 2008 for cgicc by doxygen 1.5.1