Open Lighting Architecture 0.10.9
Loading...
Searching...
No Matches
HTTPServer.h
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * HTTPServer.h
17 * The Base HTTP Server class.
18 * Copyright (C) 2005 Simon Newton
19 */
20
21
22#ifndef INCLUDE_OLA_HTTP_HTTPSERVER_H_
23#define INCLUDE_OLA_HTTP_HTTPSERVER_H_
24
25#include <ola/Callback.h>
26#include <ola/base/Macro.h>
27#include <ola/io/Descriptor.h>
28#include <ola/io/SelectServer.h>
29#include <ola/thread/Thread.h>
30#include <ola/web/Json.h>
31// 0.4.6 of microhttp doesn't include stdarg so we do it here.
32#include <stdarg.h>
33#include <stdint.h>
34#include <stdlib.h>
35#ifdef _WIN32
36#define WIN32_LEAN_AND_MEAN
37#include <ola/win/CleanWinSock2.h>
38#else
39#include <sys/select.h>
40#include <sys/socket.h>
41#endif // _WIN32
42#include <microhttpd.h>
43#include <map>
44#include <set>
45#include <string>
46#include <vector>
47
48// Beginning with v0.9.71, libmicrohttpd changed the return type of most
49// functions from int to enum MHD_Result
50// https://git.gnunet.org/gnunet.git/tree/src/include/gnunet_mhd_compat.h
51// proposes to define a constant for the return type so it works well
52// with all versions of libmicrohttpd
53#if MHD_VERSION >= 0x00097002
54#define MHD_RESULT enum MHD_Result
55#else
56#define MHD_RESULT int
57#endif
58
59namespace ola {
60namespace http {
61
62/*
63 * Represents the HTTP request
64 */
66 public:
67 HTTPRequest(const std::string &url,
68 const std::string &method,
69 const std::string &version,
70 struct MHD_Connection *connection);
72 bool Init();
73
74 // accessors
75 const std::string Url() const { return m_url; }
76 const std::string Method() const { return m_method; }
77 const std::string Version() const { return m_version; }
78
79 void AddHeader(const std::string &key, const std::string &value);
80 void AddPostParameter(const std::string &key, const std::string &value);
81 void ProcessPostData(const char *data, size_t *data_size);
82 const std::string GetHeader(const std::string &key) const;
83 bool CheckParameterExists(const std::string &key) const;
84 const std::string GetParameter(const std::string &key) const;
85 const std::string GetPostParameter(const std::string &key) const;
86
87 bool InFlight() const { return m_in_flight; }
88 void SetInFlight() { m_in_flight = true; }
89
90 private:
91 std::string m_url;
92 std::string m_method;
93 std::string m_version;
94 struct MHD_Connection *m_connection;
95 std::map<std::string, std::string> m_headers;
96 std::map<std::string, std::string> m_post_params;
97 struct MHD_PostProcessor *m_processor;
98 bool m_in_flight;
99
100 static const unsigned int K_POST_BUFFER_SIZE = 1024;
101
102 HTTPRequest(const HTTPRequest &) = delete;
103 const HTTPRequest &operator=(const HTTPRequest &) = delete;
104};
105
106
107/*
108 * Represents the HTTP Response
109 */
111 public:
112 explicit HTTPResponse(struct MHD_Connection *connection):
113 m_connection(connection),
114 m_status_code(MHD_HTTP_OK) {}
115
116 void Append(const std::string &data) { m_data.append(data); }
117 void SetContentType(const std::string &type);
118 void SetHeader(const std::string &key, const std::string &value);
119 void SetStatus(unsigned int status) { m_status_code = status; }
120 void SetNoCache();
121 int SendJson(const ola::web::JsonValue &json);
122 int Send();
123 struct MHD_Connection *Connection() const { return m_connection; }
124 private:
125 std::string m_data;
126 struct MHD_Connection *m_connection;
127 typedef std::multimap<std::string, std::string> HeadersMultiMap;
128 HeadersMultiMap m_headers;
129 unsigned int m_status_code;
130
131 HTTPResponse(const HTTPResponse &) = delete;
132 const HTTPResponse &operator=(const HTTPResponse &) = delete;
133};
134
135
158 public:
161
163 public:
164 // The port to listen on
165 uint16_t port;
166 // The root for content served with ServeStaticContent();
167 std::string data_dir;
168
170 : port(0),
171 data_dir("") {
172 }
173 };
174
175 explicit HTTPServer(const HTTPServerOptions &options);
176 virtual ~HTTPServer();
177 bool Init();
178 void *Run();
179 void Stop();
180 void UpdateSockets();
181
186 void HandleHTTPIO() {}
187
188 int DispatchRequest(const HTTPRequest *request, HTTPResponse *response);
189
190 // Register a callback handler.
191 bool RegisterHandler(const std::string &path, BaseHTTPCallback *handler);
192
193 // Register a file handler.
194 bool RegisterFile(const std::string &path,
195 const std::string &content_type);
196 bool RegisterFile(const std::string &path,
197 const std::string &file,
198 const std::string &content_type);
199 // Set the default handler.
200 void RegisterDefaultHandler(BaseHTTPCallback *handler);
201
202 void Handlers(std::vector<std::string> *handlers) const;
203 const std::string DataDir() const { return m_data_dir; }
204
205 // Return an error
206 int ServeError(HTTPResponse *response, const std::string &details = "");
207 int ServeNotFound(HTTPResponse *response);
208 static int ServeRedirect(HTTPResponse *response, const std::string &location);
209
210 // Return the contents of a file.
211 int ServeStaticContent(const std::string &path,
212 const std::string &content_type,
213 HTTPResponse *response);
214
215 static const char CONTENT_TYPE_PLAIN[];
216 static const char CONTENT_TYPE_HTML[];
217 static const char CONTENT_TYPE_GIF[];
218 static const char CONTENT_TYPE_PNG[];
219 static const char CONTENT_TYPE_CSS[];
220 static const char CONTENT_TYPE_JS[];
221 static const char CONTENT_TYPE_OCT[];
222
223 // Expose the SelectServer
224 ola::io::SelectServer *SelectServer() { return m_select_server.get(); }
225
226 static struct MHD_Response *BuildResponse(void *data, size_t size);
227
228 private :
229 typedef struct {
230 std::string file_path;
231 std::string content_type;
232 } static_file_info;
233
234 struct DescriptorState {
235 public:
236 explicit DescriptorState(ola::io::UnmanagedFileDescriptor *_descriptor)
237 : descriptor(_descriptor), read(0), write(0) {}
238
240 uint8_t read : 1;
241 uint8_t write : 1;
242 uint8_t : 6;
243 };
244
245 struct Descriptor_lt {
246 bool operator()(const DescriptorState *d1,
247 const DescriptorState *d2) const {
248 return d1->descriptor->ReadDescriptor() <
249 d2->descriptor->ReadDescriptor();
250 }
251 };
252
253 typedef std::set<DescriptorState*, Descriptor_lt> SocketSet;
254
255 struct MHD_Daemon *m_httpd;
256 std::auto_ptr<ola::io::SelectServer> m_select_server;
257 SocketSet m_sockets;
258
259 std::map<std::string, BaseHTTPCallback*> m_handlers;
260 std::map<std::string, static_file_info> m_static_content;
261 BaseHTTPCallback *m_default_handler;
262 unsigned int m_port;
263 std::string m_data_dir;
264
265 int ServeStaticContent(static_file_info *file_info,
266 HTTPResponse *response);
267
268 void InsertSocket(bool is_readable, bool is_writeable, int fd);
269 void FreeSocket(DescriptorState *state);
270
271 HTTPServer(const HTTPServer &) = delete;
272 const HTTPServer &operator=(const HTTPServer &) = delete;
273};
274} // namespace http
275} // namespace ola
276#endif // INCLUDE_OLA_HTTP_HTTPSERVER_H_
Basic data types used to represent elements in a JSON document.
Helper macros.
A 2 argument callback which can be called multiple times.
Definition Callback.h:1895
Definition HTTPServer.h:65
void AddPostParameter(const std::string &key, const std::string &value)
Add a post parameter.
Definition HTTPServer.cpp:269
void AddHeader(const std::string &key, const std::string &value)
Add a header to the request object.
Definition HTTPServer.cpp:256
void ProcessPostData(const char *data, size_t *data_size)
Process post data.
Definition HTTPServer.cpp:284
const std::string GetParameter(const std::string &key) const
Return the value of a url parameter.
Definition HTTPServer.cpp:310
bool CheckParameterExists(const std::string &key) const
Return whether an url parameter exists.
Definition HTTPServer.cpp:326
const std::string GetPostParameter(const std::string &key) const
Lookup a post parameter in this request.
Definition HTTPServer.cpp:349
const std::string GetHeader(const std::string &key) const
Return the value of the header sent with this request.
Definition HTTPServer.cpp:294
Definition HTTPServer.h:110
void SetHeader(const std::string &key, const std::string &value)
Set a header in the response.
Definition HTTPServer.cpp:384
int SendJson(const ola::web::JsonValue &json)
Send a JsonObject as the response.
Definition HTTPServer.cpp:394
int Send()
Send the HTTP response.
Definition HTTPServer.cpp:415
void SetNoCache()
Set the appropriate headers so this response isn't cached.
Definition HTTPServer.cpp:373
void SetContentType(const std::string &type)
Set the content-type header.
Definition HTTPServer.cpp:365
The base HTTP Server.
Definition HTTPServer.h:157
static int ServeRedirect(HTTPResponse *response, const std::string &location)
Serve a redirect.
Definition HTTPServer.cpp:776
void UpdateSockets()
This is run every loop iteration to update the list of sockets in the SelectServer from MHD.
Definition HTTPServer.cpp:550
int ServeError(HTTPResponse *response, const std::string &details="")
Serve an error.
Definition HTTPServer.cpp:744
void * Run()
The entry point into the new thread.
Definition HTTPServer.cpp:504
void RegisterDefaultHandler(BaseHTTPCallback *handler)
Set the default handler.
Definition HTTPServer.cpp:718
bool RegisterFile(const std::string &path, const std::string &content_type)
Register a static file. The root of the URL corresponds to the data dir.
Definition HTTPServer.cpp:676
void HandleHTTPIO()
Definition HTTPServer.h:186
virtual ~HTTPServer()
Destroy this object.
Definition HTTPServer.cpp:452
int DispatchRequest(const HTTPRequest *request, HTTPResponse *response)
Call the appropriate handler.
Definition HTTPServer.cpp:629
int ServeStaticContent(const std::string &path, const std::string &content_type, HTTPResponse *response)
Return the contents of a file.
Definition HTTPServer.cpp:789
void Handlers(std::vector< std::string > *handlers) const
Return a list of all handlers registered.
Definition HTTPServer.cpp:726
bool Init()
Setup the HTTP server.
Definition HTTPServer.cpp:476
bool RegisterHandler(const std::string &path, BaseHTTPCallback *handler)
Register a handler.
Definition HTTPServer.cpp:659
void Stop()
Stop the HTTP server.
Definition HTTPServer.cpp:535
int ServeNotFound(HTTPResponse *response)
Serve a 404.
Definition HTTPServer.cpp:762
HTTPServer(const HTTPServerOptions &options)
Setup the HTTP server.
Definition HTTPServer.cpp:435
A single threaded I/O event management system.
Definition SelectServer.h:63
Allows a FD created by a library to be used with the SelectServer.
Definition Descriptor.h:247
Definition Thread.h:52
The base class for JSON values.
Definition Json.h:119
The namespace containing all OLA symbols.
Definition Credentials.cpp:44
Definition HTTPServer.h:162