upload.cpp
Go to the documentation of this file.
1/* -*-mode:c++; c-file-style: "gnu";-*- */
2/*
3 * $Id: upload.cpp,v 1.13 2007/07/02 18:48:19 sebdiaz Exp $
4 *
5 * Copyright (C) 1996 - 2004 Stephen F. Booth <sbooth@gnu.org>
6 * 2007 Sebastien DIAZ <sebastien.diaz@gmail.com>
7 * Part of the GNU cgicc library, http://www.gnu.org/software/cgicc
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 3 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
22 */
23
31#include <new>
32#include <string>
33#include <vector>
34#include <stdexcept>
35#include <iostream>
36#include <cstdlib>
37
38#include "cgicc/CgiDefs.h"
39#include "cgicc/Cgicc.h"
40#include "cgicc/HTTPHTMLHeader.h"
41#include "cgicc/HTMLClasses.h"
42
43#if HAVE_SYS_UTSNAME_H
44# include <sys/utsname.h>
45#endif
46
47#if HAVE_SYS_TIME_H
48# include <sys/time.h>
49#endif
50
51#include "styles.h"
52
53 using namespace std;
54 using namespace cgicc;
55
56// Print the form for this CGI
57 void
58printForm(const Cgicc& cgi)
59{
60 cout << "<form method=\"post\" action=\""
61 << cgi.getEnvironment().getScriptName()
62 << "\" enctype=\"multipart/form-data\">" << endl;
63
64 cout << "<table>" << endl;
65
66 cout << "<tr><td class=\"title\">Send a file</td>"
67 << "<td class=\"form\">"
68 << "<input type=\"file\" name=\"userfile\" accept=\"text/plain\" />"
69 << "</td></tr>" << endl;
70
71 cout << "<tr><td class=\"title\">Upload Redirection</td>"
72 << "<td class=\"form\">"
73 << "<input type=\"checkbox\" name=\"redirect\" />"
74 << "Bounce uploaded file back to browser"
75 << "</td></tr>" << endl;
76
77 cout << "</table>" << endl;
78
79 cout << "<div class=\"center\"><p>"
80 << "<input type=\"submit\" name=\"submit\" value=\"Send the file\" />"
81 << "<input type=\"reset\" value=\"Nevermind\" />"
82 << "</p></div></form>" << endl;
83}
84
85// Main Street, USA
86 int
87 main(int /*argc*/,
88 char ** /*argv*/)
89{
90 try {
91#if HAVE_GETTIMEOFDAY
92 timeval start;
93 gettimeofday(&start, NULL);
94#endif
95
96 // Create a new Cgicc object containing all the CGI data
97 Cgicc cgi;
98
99 // Redirect output, if desired
100 if(cgi.queryCheckbox("redirect")) {
101 const_file_iterator file = cgi.getFile("userfile");
102
103 // Only redirect a valid file
104 if(file != cgi.getFiles().end()) {
105 cout << HTTPContentHeader(file->getDataType());
106 file->writeToStream(cout);
107
108 return EXIT_SUCCESS;
109 }
110 }
111
112 // Output the HTTP headers for an HTML document, and the HTML 4.0 DTD info
113 cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
114 cout << html().set("lang", "en").set("dir", "ltr") << endl;
115
116 // Set up the page's header and title.
117 // I will put in lfs to ease reading of the produced HTML.
118 cout << head() << endl;
119
120 // Output the style sheet portion of the header
121 cout << style() << comment() << endl;
122 cout << styles;
123 cout << comment() << style() << endl;
124
125 cout << title() << "GNU cgicc v" << cgi.getVersion()
126 << " File Upload Test" << title() << endl;
127
128 cout << head() << endl;
129
130 // Start the HTML body
131 cout << body() << endl;
132
133 cout << h1() << "GNU cgi" << span("cc").set("class","red")
134 << " v"<< cgi.getVersion() << " File Upload Test"
135 << h1() << endl;
136
137 // Get a pointer to the environment
138 const CgiEnvironment& env = cgi.getEnvironment();
139
140 // Generic thank you message
141 cout << comment() << "This page generated by cgicc for "
142 << env.getRemoteHost() << comment() << endl;
143 cout << h4() << "Thanks for using cgi" << span("cc").set("class", "red")
144 << ", " << env.getRemoteHost()
145 << '(' << env.getRemoteAddr() << ")!" << h4() << endl;
146
147 // Show the uploaded file
148 const_file_iterator file;
149 file = cgi.getFile("userfile");
150
151 if(file != cgi.getFiles().end()) {
152
153 cout << table() << endl;
154
155 cout << tr() << td("Name").set("class","title")
156 << td(file->getName()).set("class","data") << tr() << endl;
157
158 cout << tr() << td("Data Type").set("class","title")
159 << td(file->getDataType()).set("class","data") << tr() << endl;
160
161 cout << tr() << td("Filename").set("class","title")
162 << td(file->getFilename()).set("class","data") << tr() << endl;
163
164 cout << tr() << td("Data Length").set("class","title")
165 << td().set("class","data") << file->getDataLength()
166 << td() << tr() << endl;
167
168 cout << tr() << td("File Data").set("class","title")
169 << td().set("class","data") << pre();
170 file->writeToStream(cout);
171 cout << pre() << td() << tr() << endl;
172
173 cout << table() << endl;
174 }
175
176 // Print out the form to do it again
177 cout << br() << endl;
178 printForm(cgi);
179 cout << hr().set("class", "half") << endl;
180
181 // Information on cgicc
182 cout << cgicc::div().set("align","center").set("class","smaller") << endl;
183 cout << "GNU cgi" << span("cc").set("class","red") << " v";
184 cout << cgi.getVersion() << br() << endl;
185 cout << "Compiled at " << cgi.getCompileTime();
186 cout << " on " << cgi.getCompileDate() << br() << endl;
187
188 cout << "Configured for " << cgi.getHost();
189#if HAVE_UNAME
190 struct utsname info;
191 if(uname(&info) != -1) {
192 cout << ". Running on " << info.sysname;
193 cout << ' ' << info.release << " (";
194 cout << info.nodename << ")." << endl;
195 }
196#else
197 cout << "." << endl;
198#endif
199
200#if HAVE_GETTIMEOFDAY
201 // Information on this query
202 timeval end;
203 gettimeofday(&end, NULL);
204 long us = ((end.tv_sec - start.tv_sec) * 1000000)
205 + (end.tv_usec - start.tv_usec);
206
207 cout << br() << "Total time for request = " << us << " us";
208 cout << " (" << static_cast<double>(us/1000000.0) << " s)";
209#endif
210
211 // End of document
212 cout << cgicc::div() << endl;
213 cout << body() << html() << endl;
214
215 // No chance for failure in this example
216 return EXIT_SUCCESS;
217 }
218
219 // Did any errors occur?
220 catch(const std::exception& e) {
221
222 // This is a dummy exception handler, as it doesn't really do
223 // anything except print out information.
224
225 // Reset all the HTML elements that might have been used to
226 // their initial state so we get valid output
227 html::reset(); head::reset(); body::reset();
228 title::reset(); h1::reset(); h4::reset();
229 comment::reset(); td::reset(); tr::reset();
230 table::reset(); cgicc::div::reset(); p::reset();
231 a::reset(); h2::reset(); colgroup::reset();
232
233 // Output the HTTP headers for an HTML document, and the HTML 4.0 DTD info
234 cout << HTTPHTMLHeader() << HTMLDoctype(HTMLDoctype::eStrict) << endl;
235 cout << html().set("lang","en").set("dir","ltr") << endl;
236
237 // Set up the page's header and title.
238 // I will put in lfs to ease reading of the produced HTML.
239 cout << head() << endl;
240
241 // Output the style sheet portion of the header
242 cout << style() << comment() << endl;
243 cout << "body { color: black; background-color: white; }" << endl;
244 cout << "hr.half { width: 60%; align: center; }" << endl;
245 cout << "span.red, strong.red { color: red; }" << endl;
246 cout << "div.notice { border: solid thin; padding: 1em; margin: 1em 0; "
247 << "background: #ddd; }" << endl;
248
249 cout << comment() << style() << endl;
250
251 cout << title("GNU cgicc exception") << endl;
252 cout << head() << endl;
253
254 cout << body() << endl;
255
256 cout << h1() << "GNU cgi" << span("cc", set("class","red"))
257 << " caught an exception" << h1() << endl;
258
259 cout << cgicc::div().set("align","center").set("class","notice") << endl;
260
261 cout << h2(e.what()) << endl;
262
263 // End of document
264 cout << cgicc::div() << endl;
265 cout << hr().set("class","half") << endl;
266 cout << body() << html() << endl;
267
268 return EXIT_SUCCESS;
269 }
270}
CgiDefs.h
Platform and operating system specific macro definitions.
Cgicc.h
The main header file for the GNU cgicc library.
HTMLClasses.h
The header file containing HTML output classes.
HTTPHTMLHeader.h
Shortcut to HTTPContentHeader for text/html.
main
int main(int argc, char **argv)
The main function.
Definition: cardgame.cpp:1483
cgicc::CgiEnvironment
Class encapsulating the CGI runtime environment.
Definition: CgiEnvironment.h:77
cgicc::CgiEnvironment::getScriptName
std::string getScriptName() const
Get the full path to this CGI application.
Definition: CgiEnvironment.h:305
cgicc::CgiEnvironment::getRemoteAddr
std::string getRemoteAddr() const
Get the IP address of the remote machine making this request.
Definition: CgiEnvironment.h:399
cgicc::CgiEnvironment::getRemoteHost
std::string getRemoteHost() const
Get the hostname of the remote machine making this request.
Definition: CgiEnvironment.h:389
cgicc::Cgicc
The main class of the GNU cgicc library.
Definition: Cgicc.h:103
cgicc::Cgicc::getCompileDate
const char * getCompileDate() const
Get the date on which this library was compiled.
cgicc::Cgicc::getEnvironment
const CgiEnvironment & getEnvironment() const
Definition: Cgicc.h:394
cgicc::Cgicc::queryCheckbox
bool queryCheckbox(const std::string &elementName) const
Query whether a checkbox is checked.
cgicc::Cgicc::getVersion
const char * getVersion() const
Get the version number of cgicc.
cgicc::Cgicc::getFile
file_iterator getFile(const std::string &name)
Find an uploaded file.
cgicc::Cgicc::getCompileTime
const char * getCompileTime() const
Get the time at which this library was compiled.
cgicc::Cgicc::getHost
const char * getHost() const
Get the platform for which Cgicc was configured.
cgicc::Cgicc::getFiles
const std::vector< FormFile > & getFiles() const
Definition: Cgicc.h:380
cgicc::HTMLDoctype
Specifies the DTD of the HTML 4 document.
Definition: HTMLDoctype.h:57
cgicc::HTMLElement::set
HTMLElement & set(const std::string &name)
Set an HTMLAttribute on this HTMLElement.
cgicc::HTTPContentHeader
HTTP header for data of a specified MIME type.
Definition: HTTPContentHeader.h:50
cgicc::HTTPHTMLHeader
Shortcut to HTTPContentHeader for text/html.
Definition: HTTPHTMLHeader.h:48
cgicc::comment
An HTML comment.
Definition: HTMLClasses.h:93
cgicc
The namespace containing the cgicc library.
Definition: Cgicc.h:52
cgicc::const_file_iterator
std::vector< FormFile >::const_iterator const_file_iterator
A vector of const FormFile objects.
Definition: Cgicc.h:73
cgicc::set
HTMLAttributeList set(const std::string &name)
Create a new HTMLAttributeList, and set an HTMLAttribute.
Definition: HTMLAttributeList.h:189