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
58 printForm(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 }

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 Thu Aug 8 2013 22:34:12 for cgicc by doxygen 1.8.3.1