test.cpp Source File

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

# test.cpp

Go to the documentation of this file.

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