00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00056 void dumpEnvironment(const CgiEnvironment& env);
00057 void dumpList(const Cgicc& formData);
00058 void showForm(const Cgicc& formData);
00059
00060
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
00171 int
00172 main(int ,
00173 char ** )
00174 {
00175 try {
00176 #if HAVE_GETTIMEOFDAY
00177 timeval start;
00178 gettimeofday(&start, NULL);
00179 #endif
00180
00181
00182 Cgicc cgi;
00183
00184
00185 if(cgi.queryCheckbox("throw") && ! cgi.queryCheckbox("restore"))
00186 throw std::runtime_error("User-requested Exception thrown in main()");
00187
00188
00189 cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
00190 cout << html().set("lang", "en").set("dir", "ltr") << endl;
00191
00192
00193
00194 cout << head() << endl;
00195
00196
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
00207 cout << body() << endl;
00208
00209 cout << h1() << "GNU cgi" << span("cc").set("class","red")
00210 << " v"<< cgi.getVersion() << " Test" << h1() << endl;
00211
00212
00213 const CgiEnvironment& env = cgi.getEnvironment();
00214
00215
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
00223 if(cgi.queryCheckbox("save")) {
00224
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
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
00244
00245
00246 if(cgi.queryCheckbox("showEnv"))
00247 dumpEnvironment(env);
00248
00249
00250
00251
00252
00253
00254 if(cgi.queryCheckbox("showFE"))
00255 dumpList(cgi);
00256
00257
00258
00259
00260
00261 if(cgi.queryCheckbox("showForm"))
00262 showForm(cgi);
00263
00264
00265 cout << br() << endl;
00266 printForm(cgi);
00267 cout << hr().set("class", "half") << endl;
00268
00269
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
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
00300 cout << cgicc::div() << endl;
00301 cout << body() << html() << endl;
00302
00303
00304 return EXIT_SUCCESS;
00305 }
00306
00307
00308 catch(const std::exception& e) {
00309
00310
00311
00312
00313
00314
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
00322 cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
00323 cout << html().set("lang","en").set("dir","ltr") << endl;
00324
00325
00326
00327 cout << head() << endl;
00328
00329
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
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
00361 void
00362 dumpEnvironment(const CgiEnvironment& env)
00363 {
00364
00365
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
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
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
00458 void
00459 showForm(const Cgicc& formData)
00460 {
00461
00462
00463 cout << h2("Form Data via Cgicc") << endl;
00464
00465 cout << cgicc::div().set("class","notice") << endl;
00466
00467
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
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
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
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
00500 if(formData.queryCheckbox("hungry"))
00501 cout << "You are hungry." << br() << endl;
00502 else
00503 cout << "You are not hungry." << br() << endl;
00504
00505
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
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
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 }