source: box/trunk/lib/httpserver/HTTPServer.cpp @ 2504

Revision 2504, 6.1 KB checked in by chris, 3 years ago (diff)

Move S3Simulator into its own class, like S3Client, for reuse elsewhere.

Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    HTTPServer.cpp
5//              Purpose: HTTP server class
6//              Created: 26/3/04
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <stdio.h>
13
14#include "HTTPServer.h"
15#include "HTTPRequest.h"
16#include "HTTPResponse.h"
17#include "IOStreamGetLine.h"
18
19#include "MemLeakFindOn.h"
20
21
22// --------------------------------------------------------------------------
23//
24// Function
25//              Name:    HTTPServer::HTTPServer()
26//              Purpose: Constructor
27//              Created: 26/3/04
28//
29// --------------------------------------------------------------------------
30HTTPServer::HTTPServer()
31        : mTimeout(20000)       // default timeout leaves a little while for clients to get the second request in.
32{
33}
34
35
36// --------------------------------------------------------------------------
37//
38// Function
39//              Name:    HTTPServer::~HTTPServer()
40//              Purpose: Destructor
41//              Created: 26/3/04
42//
43// --------------------------------------------------------------------------
44HTTPServer::~HTTPServer()
45{
46}
47
48
49// --------------------------------------------------------------------------
50//
51// Function
52//              Name:    HTTPServer::DaemonName()
53//              Purpose: As interface, generic name for daemon
54//              Created: 26/3/04
55//
56// --------------------------------------------------------------------------
57const char *HTTPServer::DaemonName() const
58{
59        return "generic-httpserver";
60}
61
62
63// --------------------------------------------------------------------------
64//
65// Function
66//              Name:    HTTPServer::GetConfigVerify()
67//              Purpose: As interface -- return most basic config so it's only necessary to
68//                               provide this if you want to add extra directives.
69//              Created: 26/3/04
70//
71// --------------------------------------------------------------------------
72const ConfigurationVerify *HTTPServer::GetConfigVerify() const
73{
74        static ConfigurationVerifyKey verifyserverkeys[] = 
75        {
76                HTTPSERVER_VERIFY_SERVER_KEYS(ConfigurationVerifyKey::NoDefaultValue) // no default addresses
77        };
78
79        static ConfigurationVerify verifyserver[] = 
80        {
81                {
82                        "Server",
83                        0,
84                        verifyserverkeys,
85                        ConfigTest_Exists | ConfigTest_LastEntry,
86                        0
87                }
88        };
89       
90        static ConfigurationVerifyKey verifyrootkeys[] = 
91        {
92                HTTPSERVER_VERIFY_ROOT_KEYS
93        };
94
95        static ConfigurationVerify verify =
96        {
97                "root",
98                verifyserver,
99                verifyrootkeys,
100                ConfigTest_Exists | ConfigTest_LastEntry,
101                0
102        };
103
104        return &verify;
105}
106
107
108// --------------------------------------------------------------------------
109//
110// Function
111//              Name:    HTTPServer::Run()
112//              Purpose: As interface.
113//              Created: 26/3/04
114//
115// --------------------------------------------------------------------------
116void HTTPServer::Run()
117{
118        // Do some configuration stuff
119        const Configuration &conf(GetConfiguration());
120        HTTPResponse::SetDefaultURIPrefix(conf.GetKeyValue("AddressPrefix"));
121
122        // Let the base class do the work
123        ServerStream<SocketStream, 80>::Run();
124}
125
126
127// --------------------------------------------------------------------------
128//
129// Function
130//              Name:    HTTPServer::Connection(SocketStream &)
131//              Purpose: As interface, handle connection
132//              Created: 26/3/04
133//
134// --------------------------------------------------------------------------
135void HTTPServer::Connection(SocketStream &rStream)
136{
137        // Create a get line object to use
138        IOStreamGetLine getLine(rStream);
139
140        // Notify dervived claases
141        HTTPConnectionOpening();
142
143        bool handleRequests = true;
144        while(handleRequests)
145        {
146                // Parse the request
147                HTTPRequest request;
148                if(!request.Receive(getLine, mTimeout))
149                {
150                        // Didn't get request, connection probably closed.
151                        break;
152                }
153       
154                // Generate a response
155                HTTPResponse response(&rStream);
156               
157                try
158                {
159                        Handle(request, response);
160                }
161                catch(BoxException &e)
162                {
163                        char exceptionCode[256];
164                        ::sprintf(exceptionCode, "%s (%d/%d)", e.what(),
165                                e.GetType(), e.GetSubType());
166                        SendInternalErrorResponse(exceptionCode, response);
167                }
168                catch(...)
169                {
170                        SendInternalErrorResponse("unknown", response);
171                }
172               
173                // Keep alive?
174                if(request.GetClientKeepAliveRequested())
175                {
176                        // Mark the response to the client as supporting keepalive
177                        response.SetKeepAlive(true);
178                }
179                else
180                {
181                        // Stop now
182                        handleRequests = false;
183                }
184       
185                // Send the response (omit any content if this is a HEAD method request)
186                response.Send(request.GetMethod() == HTTPRequest::Method_HEAD);
187        }
188
189        // Notify derived classes
190        HTTPConnectionClosing();
191}
192
193
194// --------------------------------------------------------------------------
195//
196// Function
197//              Name:    HTTPServer::SendInternalErrorResponse(const char*,
198//                       HTTPResponse&)
199//              Purpose: Generates an error message in the provided response
200//              Created: 26/3/04
201//
202// --------------------------------------------------------------------------
203void HTTPServer::SendInternalErrorResponse(const std::string& rErrorMsg,
204        HTTPResponse& rResponse)
205{
206        #define ERROR_HTML_1 "<html><head><title>Internal Server Error</title></head>\n" \
207                        "<h1>Internal Server Error</h1>\n" \
208                        "<p>An error, type "
209        #define ERROR_HTML_2 " occured when processing the request.</p>" \
210                        "<p>Please try again later.</p>" \
211                        "</body>\n</html>\n"
212
213        // Generate the error page
214        // rResponse.SetResponseCode(HTTPResponse::Code_InternalServerError);
215        rResponse.SetContentType("text/html");
216        rResponse.Write(ERROR_HTML_1, sizeof(ERROR_HTML_1) - 1);
217        rResponse.IOStream::Write(rErrorMsg.c_str());
218        rResponse.Write(ERROR_HTML_2, sizeof(ERROR_HTML_2) - 1);
219}
220
221
222// --------------------------------------------------------------------------
223//
224// Function
225//              Name:    HTTPServer::HTTPConnectionOpening()
226//              Purpose: Override to get notifications of connections opening
227//              Created: 22/12/04
228//
229// --------------------------------------------------------------------------
230void HTTPServer::HTTPConnectionOpening()
231{
232}
233
234
235// --------------------------------------------------------------------------
236//
237// Function
238//              Name:    HTTPServer::HTTPConnectionClosing()
239//              Purpose: Override to get notifications of connections closing
240//              Created: 22/12/04
241//
242// --------------------------------------------------------------------------
243void HTTPServer::HTTPConnectionClosing()
244{
245}
246
247
Note: See TracBrowser for help on using the repository browser.