Open Lighting Architecture  Latest Git
 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();
110  int SendJson(const ola::web::JsonValue &json);
111  int Send();
112  struct MHD_Connection *Connection() const { return m_connection; }
113  private:
114  std::string m_data;
115  struct MHD_Connection *m_connection;
116  typedef std::multimap<std::string, std::string> HeadersMultiMap;
117  HeadersMultiMap m_headers;
118  unsigned int m_status_code;
119 
121 };
122 
123 
146  public:
149 
151  public:
152  // The port to listen on
153  uint16_t port;
154  // The root for content served with ServeStaticContent();
155  std::string data_dir;
156 
158  : port(0),
159  data_dir("") {
160  }
161  };
162 
163  explicit HTTPServer(const HTTPServerOptions &options);
164  virtual ~HTTPServer();
165  bool Init();
166  void *Run();
167  void Stop();
168  void UpdateSockets();
169 
174  void HandleHTTPIO() {}
175 
176  int DispatchRequest(const HTTPRequest *request, HTTPResponse *response);
177 
178  // Register a callback handler.
179  bool RegisterHandler(const std::string &path, BaseHTTPCallback *handler);
180 
181  // Register a file handler.
182  bool RegisterFile(const std::string &path,
183  const std::string &content_type);
184  bool RegisterFile(const std::string &path,
185  const std::string &file,
186  const std::string &content_type);
187  // Set the default handler.
188  void RegisterDefaultHandler(BaseHTTPCallback *handler);
189 
190  void Handlers(std::vector<std::string> *handlers) const;
191  const std::string DataDir() const { return m_data_dir; }
192 
193  // Return an error
194  int ServeError(HTTPResponse *response, const std::string &details = "");
195  int ServeNotFound(HTTPResponse *response);
196  static int ServeRedirect(HTTPResponse *response, const std::string &location);
197 
198  // Return the contents of a file.
199  int ServeStaticContent(const std::string &path,
200  const std::string &content_type,
201  HTTPResponse *response);
202 
203  static const char CONTENT_TYPE_PLAIN[];
204  static const char CONTENT_TYPE_HTML[];
205  static const char CONTENT_TYPE_GIF[];
206  static const char CONTENT_TYPE_PNG[];
207  static const char CONTENT_TYPE_ICO[];
208  static const char CONTENT_TYPE_CSS[];
209  static const char CONTENT_TYPE_JS[];
210  static const char CONTENT_TYPE_OCT[];
211  static const char CONTENT_TYPE_XML[];
212  static const char CONTENT_TYPE_JSON[];
213 
214  // Expose the SelectServer
215  ola::io::SelectServer *SelectServer() { return m_select_server.get(); }
216 
217  static struct MHD_Response *BuildResponse(void *data, size_t size);
218 
219  private :
220  typedef struct {
221  std::string file_path;
222  std::string content_type;
223  } static_file_info;
224 
225  struct DescriptorState {
226  public:
227  explicit DescriptorState(ola::io::UnmanagedFileDescriptor *_descriptor)
228  : descriptor(_descriptor), read(0), write(0) {}
229 
231  uint8_t read : 1;
232  uint8_t write : 1;
233  uint8_t : 6;
234  };
235 
236  struct Descriptor_lt {
237  bool operator()(const DescriptorState *d1,
238  const DescriptorState *d2) const {
239  return d1->descriptor->ReadDescriptor() <
240  d2->descriptor->ReadDescriptor();
241  }
242  };
243 
244  typedef std::set<DescriptorState*, Descriptor_lt> SocketSet;
245 
246  struct MHD_Daemon *m_httpd;
247  std::auto_ptr<ola::io::SelectServer> m_select_server;
248  SocketSet m_sockets;
249 
250  std::map<std::string, BaseHTTPCallback*> m_handlers;
251  std::map<std::string, static_file_info> m_static_content;
252  BaseHTTPCallback *m_default_handler;
253  unsigned int m_port;
254  std::string m_data_dir;
255 
256  int ServeStaticContent(static_file_info *file_info,
257  HTTPResponse *response);
258 
259  void InsertSocket(bool is_readable, bool is_writeable, int fd);
260  void FreeSocket(DescriptorState *state);
261 
263 };
264 } // namespace http
265 } // namespace ola
266 #endif // INCLUDE_OLA_HTTP_HTTPSERVER_H_
The base HTTP Server.
Definition: HTTPServer.h:145
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:255
HTTPServer(const HTTPServerOptions &options)
Setup the HTTP server.
Definition: HTTPServer.cpp:443
int ServeStaticContent(const std::string &path, const std::string &content_type, HTTPResponse *response)
Return the contents of a file.
Definition: HTTPServer.cpp:798
#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:771
int ServeError(HTTPResponse *response, const std::string &details="")
Serve an error.
Definition: HTTPServer.cpp:753
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:293
Definition: HTTPServer.h:150
void SetContentType(const std::string &type)
Set the content-type header.
Definition: HTTPServer.cpp:364
bool Init()
Setup the HTTP server.
Definition: HTTPServer.cpp:485
void * Run()
The entry point into the new thread.
Definition: HTTPServer.cpp:513
void SetNoCache()
Set the appropriate headers so this response isn't cached.
Definition: HTTPServer.cpp:372
void ProcessPostData(const char *data, size_t *data_size)
Process post data.
Definition: HTTPServer.cpp:283
Definition: Thread.h:52
Definition: HTTPServer.h:98
void SetAccessControlAllowOriginAll()
Set the appropriate headers so this response is accessible from any origin.
Definition: HTTPServer.cpp:380
int SendJson(const ola::web::JsonValue &json)
Send a JsonObject as the response.
Definition: HTTPServer.cpp:400
void Stop()
Stop the HTTP server.
Definition: HTTPServer.cpp:544
bool CheckParameterExists(const std::string &key) const
Return whether an url parameter exists.
Definition: HTTPServer.cpp:325
A single threaded I/O event management system.
Definition: SelectServer.h:63
virtual ~HTTPServer()
Destroy this object.
Definition: HTTPServer.cpp:460
bool RegisterHandler(const std::string &path, BaseHTTPCallback *handler)
Register a handler.
Definition: HTTPServer.cpp:668
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:685
int DispatchRequest(const HTTPRequest *request, HTTPResponse *response)
Call the appropriate handler.
Definition: HTTPServer.cpp:638
static int ServeRedirect(HTTPResponse *response, const std::string &location)
Serve a redirect.
Definition: HTTPServer.cpp:785
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:309
void Handlers(std::vector< std::string > *handlers) const
Return a list of all handlers registered.
Definition: HTTPServer.cpp:735
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:268
void RegisterDefaultHandler(BaseHTTPCallback *handler)
Set the default handler.
Definition: HTTPServer.cpp:727
int Send()
Send the HTTP response.
Definition: HTTPServer.cpp:422
Basic data types used to represent elements in a JSON document.
void HandleHTTPIO()
Definition: HTTPServer.h:174
void UpdateSockets()
This is run every loop iteration to update the list of sockets in the SelectServer from MHD...
Definition: HTTPServer.cpp:559
const std::string GetPostParameter(const std::string &key) const
Lookup a post parameter in this request.
Definition: HTTPServer.cpp:348
void SetHeader(const std::string &key, const std::string &value)
Set a header in the response.
Definition: HTTPServer.cpp:390