cgicc: upload.cpp Source File

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

# upload.cpp

Go to the documentation of this file.

    00001 /* -*-mode:c++; c-file-style: "gnu";-*- */
    00002 /*
    00003  *  $Id: upload.cpp,v 1.13 2007/07/02 18:48:19 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
    00031 #include <new>
    00032 #include <string>
    00033 #include <vector>
    00034 #include <stdexcept>
    00035 #include <iostream>
    00036 #include <cstdlib>
    00037
    00038 #include "cgicc/CgiDefs.h"
    00039 #include "cgicc/Cgicc.h"
    00040 #include "cgicc/HTTPHTMLHeader.h"
    00041 #include "cgicc/HTMLClasses.h"
    00042
    00043 #if HAVE_SYS_UTSNAME_H
    00044 #  include <sys/utsname.h>
    00045 #endif
    00046
    00047 #if HAVE_SYS_TIME_H
    00048 #  include <sys/time.h>
    00049 #endif
    00050
    00051 #include "styles.h"
    00052
    00053 using namespace std;
    00054 using namespace cgicc;
    00055
    00056 // Print the form for this CGI
    00057 void
    00058 printForm(const Cgicc& cgi)
    00059 {
    00060   cout << "<form method=\"post\" action=\""
    00061        << cgi.getEnvironment().getScriptName()
    00062        << "\" enctype=\"multipart/form-data\">" << endl;
    00063
    00064   cout << "<table>" << endl;
    00065
    00066   cout << "<tr><td class=\"title\">Send a file</td>"
    00067        << "<td class=\"form\">"
    00068        << "<input type=\"file\" name=\"userfile\" accept=\"text/plain\" />"
    00069        << "</td></tr>" << endl;
    00070
    00071   cout << "<tr><td class=\"title\">Upload Redirection</td>"
    00072        << "<td class=\"form\">"
    00073        << "<input type=\"checkbox\" name=\"redirect\" />"
    00074        << "Bounce uploaded file back to browser"
    00075        << "</td></tr>" << endl;
    00076
    00077   cout << "</table>" << endl;
    00078
    00079   cout << "<div class=\"center\"><p>"
    00080        << "<input type=\"submit\" name=\"submit\" value=\"Send the file\" />"
    00081        << "<input type=\"reset\" value=\"Nevermind\" />"
    00082        << "</p></div></form>" << endl;
    00083 }
    00084
    00085 // Main Street, USA
    00086 int
    00087 main(int /*argc*/,
    00088      char ** /*argv*/)
    00089 {
    00090   try {
    00091 #if HAVE_GETTIMEOFDAY
    00092     timeval start;
    00093     gettimeofday(&start, NULL);
    00094 #endif
    00095
    00096     // Create a new Cgicc object containing all the CGI data
    00097     Cgicc cgi;
    00098
    00099     // Redirect output, if desired
    00100     if(cgi.queryCheckbox("redirect")) {
    00101       const_file_iterator file = cgi.getFile("userfile");
    00102
    00103       // Only redirect a valid file
    00104       if(file != cgi.getFiles().end()) {
    00105         cout << HTTPContentHeader(file->getDataType());
    00106         file->writeToStream(cout);
    00107
    00108         return EXIT_SUCCESS;
    00109       }
    00110     }
    00111
    00112     // Output the HTTP headers for an HTML document, and the HTML 4.0 DTD info
    00113     cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
    00114     cout << html().set("lang", "en").set("dir", "ltr") << endl;
    00115
    00116     // Set up the page's header and title.
    00117     // I will put in lfs to ease reading of the produced HTML.
    00118     cout << head() << endl;
    00119
    00120     // Output the style sheet portion of the header
    00121     cout << style() << comment() << endl;
    00122     cout << styles;
    00123     cout << comment() << style() << endl;
    00124
    00125     cout << title() << "GNU cgicc v" << cgi.getVersion()
    00126          << " File Upload Test" << title() << endl;
    00127
    00128     cout << head() << endl;
    00129
    00130     // Start the HTML body
    00131     cout << body() << endl;
    00132
    00133     cout << h1() << "GNU cgi" << span("cc").set("class","red")
    00134          << " v"<< cgi.getVersion() << " File Upload Test"
    00135          << h1() << endl;
    00136
    00137     // Get a pointer to the environment
    00138     const CgiEnvironment& env = cgi.getEnvironment();
    00139
    00140     // Generic thank you message
    00141     cout << comment() << "This page generated by cgicc for "
    00142          << env.getRemoteHost() << comment() << endl;
    00143     cout << h4() << "Thanks for using cgi" << span("cc").set("class", "red")
    00144          << ", " << env.getRemoteHost()
    00145          << '(' << env.getRemoteAddr() << ")!" << h4() << endl;
    00146
    00147     // Show the uploaded file
    00148     const_file_iterator file;
    00149     file = cgi.getFile("userfile");
    00150
    00151     if(file != cgi.getFiles().end()) {
    00152
    00153       cout << table() << endl;
    00154
    00155       cout << tr() << td("Name").set("class","title")
    00156            << td(file->getName()).set("class","data") << tr() << endl;
    00157
    00158       cout << tr() << td("Data Type").set("class","title")
    00159            << td(file->getDataType()).set("class","data") << tr() << endl;
    00160
    00161       cout << tr() << td("Filename").set("class","title")
    00162            << td(file->getFilename()).set("class","data") << tr() << endl;
    00163
    00164       cout << tr() << td("Data Length").set("class","title")
    00165            << td().set("class","data") << file->getDataLength()
    00166            << td() << tr() << endl;
    00167
    00168       cout << tr() << td("File Data").set("class","title")
    00169            << td().set("class","data") << pre();
    00170       file->writeToStream(cout);
    00171       cout << pre() << td() << tr() << endl;
    00172
    00173       cout << table() << endl;
    00174     }
    00175
    00176     // Print out the form to do it again
    00177     cout << br() << endl;
    00178     printForm(cgi);
    00179     cout << hr().set("class", "half") << endl;
    00180
    00181     // Information on cgicc
    00182     cout << cgicc::div().set("align","center").set("class","smaller") << endl;
    00183     cout << "GNU cgi" << span("cc").set("class","red") << " v";
    00184     cout << cgi.getVersion() << br() << endl;
    00185     cout << "Compiled at " << cgi.getCompileTime();
    00186     cout << " on " << cgi.getCompileDate() << br() << endl;
    00187
    00188     cout << "Configured for " << cgi.getHost();
    00189 #if HAVE_UNAME
    00190     struct utsname info;
    00191     if(uname(&info) != -1) {
    00192       cout << ". Running on " << info.sysname;
    00193       cout << ' ' << info.release << " (";
    00194       cout << info.nodename << ")." << endl;
    00195     }
    00196 #else
    00197     cout << "." << endl;
    00198 #endif
    00199
    00200 #if HAVE_GETTIMEOFDAY
    00201     // Information on this query
    00202     timeval end;
    00203     gettimeofday(&end, NULL);
    00204     long us = ((end.tv_sec - start.tv_sec) * 1000000)
    00205       + (end.tv_usec - start.tv_usec);
    00206
    00207     cout << br() << "Total time for request = " << us << " us";
    00208     cout << " (" << static_cast<double>(us/1000000.0) << " s)";
    00209 #endif
    00210
    00211     // End of document
    00212     cout << cgicc::div() << endl;
    00213     cout << body() << html() << endl;
    00214
    00215     // No chance for failure in this example
    00216     return EXIT_SUCCESS;
    00217   }
    00218
    00219   // Did any errors occur?
    00220   catch(const std::exception& e) {
    00221
    00222     // This is a dummy exception handler, as it doesn't really do
    00223     // anything except print out information.
    00224
    00225     // Reset all the HTML elements that might have been used to
    00226     // their initial state so we get valid output
    00227     html::reset();      head::reset();          body::reset();
    00228     title::reset();     h1::reset();            h4::reset();
    00229     comment::reset();   td::reset();            tr::reset();
    00230     table::reset();     cgicc::div::reset();    p::reset();
    00231     a::reset();         h2::reset();            colgroup::reset();
    00232
    00233     // Output the HTTP headers for an HTML document, and the HTML 4.0 DTD info
    00234     cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
    00235     cout << html().set("lang","en").set("dir","ltr") << endl;
    00236
    00237     // Set up the page's header and title.
    00238     // I will put in lfs to ease reading of the produced HTML.
    00239     cout << head() << endl;
    00240
    00241     // Output the style sheet portion of the header
    00242     cout << style() << comment() << endl;
    00243     cout << "body { color: black; background-color: white; }" << endl;
    00244     cout << "hr.half { width: 60%; align: center; }" << endl;
    00245     cout << "span.red, strong.red { color: red; }" << endl;
    00246     cout << "div.notice { border: solid thin; padding: 1em; margin: 1em 0; "
    00247          << "background: #ddd; }" << endl;
    00248
    00249     cout << comment() << style() << endl;
    00250
    00251     cout << title("GNU cgicc exception") << endl;
    00252     cout << head() << endl;
    00253
    00254     cout << body() << endl;
    00255
    00256     cout << h1() << "GNU cgi" << span("cc", set("class","red"))
    00257          << " caught an exception" << h1() << endl;
    00258
    00259     cout << cgicc::div().set("align","center").set("class","notice") << endl;
    00260
    00261     cout << h2(e.what()) << endl;
    00262
    00263     // End of document
    00264     cout << cgicc::div() << endl;
    00265     cout << hr().set("class","half") << endl;
    00266     cout << body() << html() << endl;
    00267
    00268     return EXIT_SUCCESS;
    00269   }
    00270 }