~ubuntu-branches/ubuntu/gutsy/poco/gutsy

« back to all changes in this revision

Viewing changes to Net/samples/HTTPFormServer/src/HTTPFormServer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Burghardt
  • Date: 2007-04-27 18:33:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070427183348-xgnpct0qd6a2ip34
Tags: upstream-1.2.9
ImportĀ upstreamĀ versionĀ 1.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// HTTPFormServer.cpp
 
3
//
 
4
// $Id: //poco/Main/Net/samples/HTTPFormServer/src/HTTPFormServer.cpp#5 $
 
5
//
 
6
// This sample demonstrates the HTTPServer and HTMLForm classes.
 
7
//
 
8
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
 
9
// and Contributors.
 
10
//
 
11
// Permission is hereby granted, free of charge, to any person or organization
 
12
// obtaining a copy of the software and accompanying documentation covered by
 
13
// this license (the "Software") to use, reproduce, display, distribute,
 
14
// execute, and transmit the Software, and to prepare derivative works of the
 
15
// Software, and to permit third-parties to whom the Software is furnished to
 
16
// do so, all subject to the following:
 
17
// 
 
18
// The copyright notices in the Software and this entire statement, including
 
19
// the above license grant, this restriction and the following disclaimer,
 
20
// must be included in all copies of the Software, in whole or in part, and
 
21
// all derivative works of the Software, unless such copies or derivative
 
22
// works are solely in the form of machine-executable object code generated by
 
23
// a source language processor.
 
24
// 
 
25
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
26
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
27
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 
28
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 
29
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 
30
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
31
// DEALINGS IN THE SOFTWARE.
 
32
//
 
33
 
 
34
 
 
35
#include "Poco/Net/HTTPServer.h"
 
36
#include "Poco/Net/HTTPRequestHandler.h"
 
37
#include "Poco/Net/HTTPRequestHandlerFactory.h"
 
38
#include "Poco/Net/HTTPServerParams.h"
 
39
#include "Poco/Net/HTTPServerRequest.h"
 
40
#include "Poco/Net/HTTPServerResponse.h"
 
41
#include "Poco/Net/HTTPServerParams.h"
 
42
#include "Poco/Net/HTMLForm.h"
 
43
#include "Poco/Net/PartHandler.h"
 
44
#include "Poco/Net/MessageHeader.h"
 
45
#include "Poco/Net/ServerSocket.h"
 
46
#include "Poco/CountingStream.h"
 
47
#include "Poco/NullStream.h"
 
48
#include "Poco/StreamCopier.h"
 
49
#include "Poco/Exception.h"
 
50
#include "Poco/Util/ServerApplication.h"
 
51
#include "Poco/Util/Option.h"
 
52
#include "Poco/Util/OptionSet.h"
 
53
#include "Poco/Util/HelpFormatter.h"
 
54
#include <iostream>
 
55
 
 
56
 
 
57
using Poco::Net::ServerSocket;
 
58
using Poco::Net::HTTPRequestHandler;
 
59
using Poco::Net::HTTPRequestHandlerFactory;
 
60
using Poco::Net::HTTPServer;
 
61
using Poco::Net::HTTPServerRequest;
 
62
using Poco::Net::HTTPServerResponse;
 
63
using Poco::Net::HTTPServerParams;
 
64
using Poco::Net::MessageHeader;
 
65
using Poco::Net::HTMLForm;
 
66
using Poco::Net::NameValueCollection;
 
67
using Poco::Util::ServerApplication;
 
68
using Poco::Util::Application;
 
69
using Poco::Util::Option;
 
70
using Poco::Util::OptionSet;
 
71
using Poco::Util::HelpFormatter;
 
72
using Poco::CountingInputStream;
 
73
using Poco::NullOutputStream;
 
74
using Poco::StreamCopier;
 
75
 
 
76
 
 
77
class MyPartHandler: public Poco::Net::PartHandler
 
78
{
 
79
public:
 
80
        MyPartHandler():
 
81
                _length(0)
 
82
        {
 
83
        }
 
84
        
 
85
        void handlePart(const MessageHeader& header, std::istream& stream)
 
86
        {
 
87
                _type = header.get("Content-Type", "(unspecified)");
 
88
                if (header.has("Content-Disposition"))
 
89
                {
 
90
                        std::string disp;
 
91
                        NameValueCollection params;
 
92
                        MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
 
93
                        _name = params.get("name", "(unnamed)");
 
94
                        _fileName = params.get("filename", "(unnamed)");
 
95
                }
 
96
                
 
97
                CountingInputStream istr(stream);
 
98
                NullOutputStream ostr;
 
99
                StreamCopier::copyStream(istr, ostr);
 
100
                _length = istr.chars();
 
101
        }
 
102
        
 
103
        int length() const
 
104
        {
 
105
                return _length;
 
106
        }
 
107
        
 
108
        const std::string& name() const
 
109
        {
 
110
                return _name;
 
111
        }
 
112
 
 
113
        const std::string& fileName() const
 
114
        {
 
115
                return _fileName;
 
116
        }
 
117
        
 
118
        const std::string& contentType() const
 
119
        {
 
120
                return _type;
 
121
        }
 
122
        
 
123
private:
 
124
        int _length;
 
125
        std::string _type;
 
126
        std::string _name;
 
127
        std::string _fileName;
 
128
};
 
129
 
 
130
 
 
131
class FormRequestHandler: public HTTPRequestHandler
 
132
        /// Return a HTML document with the current date and time.
 
133
{
 
134
public:
 
135
        FormRequestHandler() 
 
136
        {
 
137
        }
 
138
        
 
139
        void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
 
140
        {
 
141
                Application& app = Application::instance();
 
142
                app.logger().information("Request from " + request.clientAddress().toString());
 
143
 
 
144
                MyPartHandler partHandler;
 
145
                HTMLForm form(request, request.stream(), partHandler);
 
146
 
 
147
                response.setChunkedTransferEncoding(true);
 
148
                response.setContentType("text/html");
 
149
 
 
150
                std::ostream& ostr = response.send();
 
151
                
 
152
                ostr <<
 
153
                        "<html>\n"
 
154
                        "<head>\n"
 
155
                        "<title>POCO Form Server Sample</title>\n"
 
156
                        "</head>\n"
 
157
                        "<body>\n"
 
158
                        "<h1>POCO Form Server Sample</h1>\n"
 
159
                        "<h2>GET Form</h2>\n"
 
160
                        "<form method=\"GET\" action=\"/form\">\n"
 
161
                        "<input type=\"text\" name=\"text\" size=\"31\">\n"
 
162
                        "<input type=\"submit\" value=\"GET\">\n"
 
163
                        "</form>\n"
 
164
                        "<h2>POST Form</h2>\n"
 
165
                        "<form method=\"POST\" action=\"/form\">\n"
 
166
                        "<input type=\"text\" name=\"text\" size=\"31\">\n"
 
167
                        "<input type=\"submit\" value=\"POST\">\n"
 
168
                        "</form>\n"
 
169
                        "<h2>File Upload</h2>\n"
 
170
                        "<form method=\"POST\" action=\"/form\" enctype=\"multipart/form-data\">\n"
 
171
                        "<input type=\"file\" name=\"file\" size=\"31\"> \n"
 
172
                        "<input type=\"submit\" value=\"Upload\">\n"
 
173
                        "</form>\n";
 
174
                        
 
175
                ostr << "<h2>Request</h2><p>\n";
 
176
                ostr << "Method: " << request.getMethod() << "<br>\n";
 
177
                ostr << "URI: " << request.getURI() << "<br>\n";
 
178
                NameValueCollection::ConstIterator it = request.begin();
 
179
                NameValueCollection::ConstIterator end = request.end();
 
180
                for (; it != end; ++it)
 
181
                {
 
182
                        ostr << it->first << ": " << it->second << "<br>\n";
 
183
                }
 
184
                ostr << "</p>";
 
185
 
 
186
                if (!form.empty())
 
187
                {
 
188
                        ostr << "<h2>Form</h2><p>\n";
 
189
                        it = form.begin();
 
190
                        end = form.end();
 
191
                        for (; it != end; ++it)
 
192
                        {
 
193
                                ostr << it->first << ": " << it->second << "<br>\n";
 
194
                        }
 
195
                        ostr << "</p>";
 
196
                }
 
197
                
 
198
                if (!partHandler.name().empty())
 
199
                {
 
200
                        ostr << "<h2>Upload</h2><p>\n";
 
201
                        ostr << "Name: " << partHandler.name() << "<br>\n";
 
202
                        ostr << "File Name: " << partHandler.fileName() << "<br>\n";
 
203
                        ostr << "Type: " << partHandler.contentType() << "<br>\n";
 
204
                        ostr << "Size: " << partHandler.length() << "<br>\n";
 
205
                        ostr << "</p>";
 
206
                }
 
207
                ostr << "</body>\n";
 
208
        }
 
209
};
 
210
 
 
211
 
 
212
class FormRequestHandlerFactory: public HTTPRequestHandlerFactory
 
213
{
 
214
public:
 
215
        FormRequestHandlerFactory()
 
216
        {
 
217
        }
 
218
 
 
219
        HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
 
220
        {
 
221
                return new FormRequestHandler;
 
222
        }
 
223
};
 
224
 
 
225
 
 
226
class HTTPFormServer: public Poco::Util::ServerApplication
 
227
        /// The main application class.
 
228
        ///
 
229
        /// This class handles command-line arguments and
 
230
        /// configuration files.
 
231
        /// Start the HTTPFormServer executable with the help
 
232
        /// option (/help on Windows, --help on Unix) for
 
233
        /// the available command line options.
 
234
        ///
 
235
        /// To use the sample configuration file (HTTPFormServer.properties),
 
236
        /// copy the file to the directory where the HTTPFormServer executable
 
237
        /// resides. If you start the debug version of the HTTPFormServer
 
238
        /// (HTTPFormServerd[.exe]), you must also create a copy of the configuration
 
239
        /// file named HTTPFormServerd.properties. In the configuration file, you
 
240
        /// can specify the port on which the server is listening (default
 
241
        /// 9980) and the format of the date/Form string sent back to the client.
 
242
        ///
 
243
        /// To test the FormServer you can use any web browser (http://localhost:9980/).
 
244
{
 
245
public:
 
246
        HTTPFormServer(): _helpRequested(false)
 
247
        {
 
248
        }
 
249
        
 
250
        ~HTTPFormServer()
 
251
        {
 
252
        }
 
253
 
 
254
protected:
 
255
        void initialize(Application& self)
 
256
        {
 
257
                loadConfiguration(); // load default configuration files, if present
 
258
                ServerApplication::initialize(self);
 
259
        }
 
260
                
 
261
        void uninitialize()
 
262
        {
 
263
                ServerApplication::uninitialize();
 
264
        }
 
265
 
 
266
        void defineOptions(OptionSet& options)
 
267
        {
 
268
                ServerApplication::defineOptions(options);
 
269
                
 
270
                options.addOption(
 
271
                        Option("help", "h", "display help information on command line arguments")
 
272
                                .required(false)
 
273
                                .repeatable(false));
 
274
        }
 
275
 
 
276
        void handleOption(const std::string& name, const std::string& value)
 
277
        {
 
278
                ServerApplication::handleOption(name, value);
 
279
 
 
280
                if (name == "help")
 
281
                        _helpRequested = true;
 
282
        }
 
283
 
 
284
        void displayHelp()
 
285
        {
 
286
                HelpFormatter helpFormatter(options());
 
287
                helpFormatter.setCommand(commandName());
 
288
                helpFormatter.setUsage("OPTIONS");
 
289
                helpFormatter.setHeader("A web server that shows how to work with HTML forms.");
 
290
                helpFormatter.format(std::cout);
 
291
        }
 
292
 
 
293
        int main(const std::vector<std::string>& args)
 
294
        {
 
295
                if (_helpRequested)
 
296
                {
 
297
                        displayHelp();
 
298
                }
 
299
                else
 
300
                {
 
301
                        unsigned short port = (unsigned short) config().getInt("HTTPFormServer.port", 9980);
 
302
                        
 
303
                        // set-up a server socket
 
304
                        ServerSocket svs(port);
 
305
                        // set-up a HTTPServer instance
 
306
                        HTTPServer srv(new FormRequestHandlerFactory, svs, new HTTPServerParams);
 
307
                        // start the HTTPServer
 
308
                        srv.start();
 
309
                        // wait for CTRL-C or kill
 
310
                        waitForTerminationRequest();
 
311
                        // Stop the HTTPServer
 
312
                        srv.stop();
 
313
                }
 
314
                return Application::EXIT_OK;
 
315
        }
 
316
        
 
317
private:
 
318
        bool _helpRequested;
 
319
};
 
320
 
 
321
 
 
322
int main(int argc, char** argv)
 
323
{
 
324
        HTTPFormServer app;
 
325
        return app.run(argc, argv);
 
326
}