Open Lighting Architecture  0.10.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 namespace ola {
49 namespace http {
50 
51 /*
52  * Represents the HTTP request
53  */
54 class HTTPRequest {
55  public:
56  HTTPRequest(const std::string &url,
57  const std::string &method,
58  const std::string &version,
59  struct MHD_Connection *connection);
60  ~HTTPRequest();
61  bool Init();
62 
63  // accessors
64  const std::string Url() const { return m_url; }
65  const std::string Method() const { return m_method; }
66  const std::string Version() const { return m_version; }
67 
68  void AddHeader(const std::string &key, const std::string &value);
69  void AddPostParameter(const std::string &key, const std::string &value);
70  void ProcessPostData(const char *data, size_t *data_size);
71  const std::string GetHeader(const std::string &key) const;
72  bool CheckParameterExists(const std::string &key) const;
73  const std::string GetParameter(const std::string &key) const;
74  const std::string GetPostParameter(const std::string &key) const;
75 
76  bool InFlight() const { return m_in_flight; }
77  void SetInFlight() { m_in_flight = true; }
78 
79  private:
80  std::string m_url;
81  std::string m_method;
82  std::string m_version;
83  struct MHD_Connection *m_connection;
84  std::map<std::string, std::string> m_headers;
85  std::map<std::string, std::string> m_post_params;
86  struct MHD_PostProcessor *m_processor;
87  bool m_in_flight;
88 
89  static const unsigned int K_POST_BUFFER_SIZE = 1024;
90 
92 };
93 
94 
95 /*
96  * Represents the HTTP Response
97  */
98 class HTTPResponse {
99  public:
100  explicit HTTPResponse(struct MHD_Connection *connection):
101  m_connection(connection),
102  m_status_code(MHD_HTTP_OK) {}
103 
104  void Append(const std::string &data) { m_data.append(data); }
105  void SetContentType(const std::string &type);
106  void SetHeader(const std::string &key, const std::string &value);
107  void SetStatus(unsigned int status) { m_status_code = status; }
108  void SetNoCache();
109  int SendJson(const ola::web::JsonValue &json);
110  int Send();
111  struct MHD_Connection *Connection() const { return m_connection; }
112  private:
113  std::string m_data;
114  struct MHD_Connection *m_connection;
115  typedef std::multimap<std::string, std::string> HeadersMultiMap;
116  HeadersMultiMap m_headers;
117  unsigned int m_status_code;
118 
120 };
121 
122 
145  public:
148 
150  public:
151  // The port to listen on
152  uint16_t port;
153  // The root for content served with ServeStaticContent();
154  std::string data_dir;
155 
157  : port(0),
158  data_dir("") {
159  }
160  };
161 
162  explicit HTTPServer(const HTTPServerOptions &options);
163  virtual ~HTTPServer();
164  bool Init();
165  void *Run();
166  void Stop();
167  void UpdateSockets();
168 
173  void HandleHTTPIO() {}
174 
175  int DispatchRequest(const HTTPRequest *request, HTTPResponse *response);
176 
177  // Register a callback handler.
178  bool RegisterHandler(const std::string &path, BaseHTTPCallback *handler);
179 
180  // Register a file handler.
181  bool RegisterFile(const std::string &path,
182  const std::string &content_type);
183  bool RegisterFile(const std::string &path,
184  const std::string &file,
185  const std::string &content_type);
186  // Set the default handler.
187  void RegisterDefaultHandler(BaseHTTPCallback *handler);
188 
189  void Handlers(std::vector<std::string> *handlers) const;
190  const std::string DataDir() const { return m_data_dir; }
191 
192  // Return an error
193  int ServeError(HTTPResponse *response, const std::string &details = "");
194  int ServeNotFound(HTTPResponse *response);
195  static int ServeRedirect(HTTPResponse *response, const std::string &location);
196 
197  // Return the contents of a file.
198  int ServeStaticContent(const std::string &path,
199  const std::string &content_type,
200  HTTPResponse *response);
201 
202  static const char CONTENT_TYPE_PLAIN[];
203  static const char CONTENT_TYPE_HTML[];
204  static const char CONTENT_TYPE_GIF[];
205  static const char CONTENT_TYPE_PNG[];
206  static const char CONTENT_TYPE_CSS[];
207  static const char CONTENT_TYPE_JS[];
208  static const char CONTENT_TYPE_OCT[];
209 
210  // Expose the SelectServer
211  ola::io::SelectServer *SelectServer() { return m_select_server.get(); }
212 
213  static struct MHD_Response *BuildResponse(void *data, size_t size);
214 
215  private :
216  typedef struct {
217  std::string file_path;
218  std::string content_type;
219  } static_file_info;
220 
221  struct DescriptorState {
222  public:
223  explicit DescriptorState(ola::io::UnmanagedFileDescriptor *_descriptor)
224  : descriptor(_descriptor), read(0), write(0) {}
225 
227  uint8_t read : 1;
228  uint8_t write : 1;
229  uint8_t : 6;
230  };
231 
232  struct Descriptor_lt {
233  bool operator()(const DescriptorState *d1,
234  const DescriptorState *d2) const {
235  return d1->descriptor->ReadDescriptor() <
236  d2->descriptor->ReadDescriptor();
237  }
238  };
239 
240  typedef std::set<DescriptorState*, Descriptor_lt> SocketSet;
241 
242  struct MHD_Daemon *m_httpd;
243  std::auto_ptr<ola::io::SelectServer> m_select_server;
244  SocketSet m_sockets;
245 
246  std::map<std::string, BaseHTTPCallback*> m_handlers;
247  std::map<std::string, static_file_info> m_static_content;
248  BaseHTTPCallback *m_default_handler;
249  unsigned int m_port;
250  std::string m_data_dir;
251 
252  int ServeStaticContent(static_file_info *file_info,
253  HTTPResponse *response);
254 
255  void InsertSocket(bool is_readable, bool is_writeable, int fd);
256  void FreeSocket(DescriptorState *state);
257 
259 };
260 } // namespace http
261 } // namespace ola
262 #endif // INCLUDE_OLA_HTTP_HTTPSERVER_H_
The base HTTP Server.
Definition: HTTPServer.h:144
The base class for JSON values.
Definition: Json.h:119
void AddHeader(const std::string &key, const std::string &value)
Add a header to the request object.
Definition: HTTPServer.cpp:248
HTTPServer(const HTTPServerOptions &options)
Setup the HTTP server.
Definition: HTTPServer.cpp:422
int ServeStaticContent(const std::string &path, const std::string &content_type, HTTPResponse *response)
Return the contents of a file.
Definition: HTTPServer.cpp:768
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Creates dummy copy constructor and assignment operator declarations.
Definition: Macro.h:44
int ServeNotFound(HTTPResponse *response)
Serve a 404.
Definition: HTTPServer.cpp:741
int ServeError(HTTPResponse *response, const std::string &details="")
Serve an error.
Definition: HTTPServer.cpp:723
Definition: HTTPServer.h:54
const std::string GetHeader(const std::string &key) const
Return the value of the header sent with this request.
Definition: HTTPServer.cpp:286
Definition: HTTPServer.h:149
void SetContentType(const std::string &type)
Set the content-type header.
Definition: HTTPServer.cpp:354
bool Init()
Setup the HTTP server.
Definition: HTTPServer.cpp:462
void * Run()
The entry point into the new thread.
Definition: HTTPServer.cpp:490
void SetNoCache()
Set the appropriate headers so this response isn't cached.
Definition: HTTPServer.cpp:362
void ProcessPostData(const char *data, size_t *data_size)
Process post data.
Definition: HTTPServer.cpp:276
Definition: Thread.h:52
Definition: HTTPServer.h:98
int SendJson(const ola::web::JsonValue &json)
Send a JsonObject as the response.
Definition: HTTPServer.cpp:383
void Stop()
Stop the HTTP server.
Definition: HTTPServer.cpp:521
bool CheckParameterExists(const std::string &key) const
Return whether an url parameter exists.
Definition: HTTPServer.cpp:316
A single threaded I/O event management system.
Definition: SelectServer.h:63
virtual ~HTTPServer()
Destroy this object.
Definition: HTTPServer.cpp:439
bool RegisterHandler(const std::string &path, BaseHTTPCallback *handler)
Register a handler.
Definition: HTTPServer.cpp:642
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:658
int DispatchRequest(const HTTPRequest *request, HTTPResponse *response)
Call the appropriate handler.
Definition: HTTPServer.cpp:615
static int ServeRedirect(HTTPResponse *response, const std::string &location)
Serve a redirect.
Definition: HTTPServer.cpp:755
Helper macros.
A 2 argument callback which can be called multiple times.
Definition: Callback.h:1895
const std::string GetParameter(const std::string &key) const
Return the value of a url parameter.
Definition: HTTPServer.cpp:301
void Handlers(std::vector< std::string > *handlers) const
Return a list of all handlers registered.
Definition: HTTPServer.cpp:707
Allows a FD created by a library to be used with the SelectServer.
Definition: Descriptor.h:247
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
void AddPostParameter(const std::string &key, const std::string &value)
Add a post parameter.
Definition: HTTPServer.cpp:261
void RegisterDefaultHandler(BaseHTTPCallback *handler)
Set the default handler.
Definition: HTTPServer.cpp:699
int Send()
Send the HTTP response.
Definition: HTTPServer.cpp:403
Basic data types used to represent elements in a JSON document.
void HandleHTTPIO()
Definition: HTTPServer.h:173
void UpdateSockets()
This is run every loop iteration to update the list of sockets in the SelectServer from MHD...
Definition: HTTPServer.cpp:536
const std::string GetPostParameter(const std::string &key) const
Lookup a post parameter in this request.
Definition: HTTPServer.cpp:339
void SetHeader(const std::string &key, const std::string &value)
Set a header in the response.
Definition: HTTPServer.cpp:373