Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

test.cpp

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

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 Jun 19 00:36:23 2004 for cgicc by doxygen 1.3.6