HTTPServer.h
Go to the documentation of this file.
1 
20 #ifndef HTTPSERVER_H_AIH108EG
21 #define HTTPSERVER_H_AIH108EG
22 
23 #include <stddef.h> // for NULL
24 
25 #include <map> // for map, map<>::iterator, etc
26 #include <string> // for string, operator<
27 #include <thread>
28 #include <mutex>
29 
30 extern "C" {
31 #include "event2/util.h" // for evutil_socket_t
32 #include <event2/http.h> // for evhttp_request
33 #include <evws.h>
34 }
35 
36 #include "uscxml/Common.h" // for USCXML_API
37 #include "uscxml/messages/Event.h" // for Data, Event
38 #include "uscxml/config.h" // for OPENSSL_FOUND
39 
40 namespace uscxml {
41 
42 class HTTPServlet;
43 class WebSocketServlet;
44 
45 class USCXML_API HTTPServer {
46 public:
47  class Request : public Event {
48  public:
49  Request() : evhttpReq(NULL) {}
50  std::string content;
51  struct evhttp_request* evhttpReq;
52 
53  operator bool() {
54  return evhttpReq != NULL;
55  }
56  };
57 
58  class USCXML_API SSLConfig {
59  public:
60  SSLConfig() : port(8443) {}
61  std::string privateKey;
62  std::string publicKey;
63  unsigned short port;
64  };
65 
66  class WSFrame : public Event {
67  public:
68  WSFrame() : evwsConn(NULL) {}
69  std::string content;
70  struct evws_connection* evwsConn;
71  };
72 
73  class USCXML_API Reply {
74  public:
75  Reply() : status(200), type("get"), evhttpReq(NULL) {}
76  Reply(Request req) : status(200), type(req.data.compound["type"].atom), evhttpReq(req.evhttpReq) {}
77 
78  void setRequest(Request req) {
79  type = req.data.compound["type"].atom;
80  evhttpReq = req.evhttpReq;
81  }
82 
83  int status;
84  std::string type;
85  std::map<std::string, std::string> headers;
86  std::string content;
87  struct evhttp_request* evhttpReq;
88  };
89 
90  struct CallbackData {
91  HTTPServlet* servlet;
92  evhttp_request* httpReq;
93  };
94 
95  enum ServerType {
96  HTTPS,
97  HTTP,
98  WebSockets
99  };
100 
101  static HTTPServer* getInstance(unsigned short port, unsigned short wsPort, SSLConfig* sslConf = NULL);
102  static HTTPServer* getInstance() {
103  return getInstance(0, 0, NULL);
104  }
105 
106  static std::string getBaseURL(ServerType type = HTTP);
107 
108  static void reply(const Reply& reply);
109  static void wsSend(struct evws_connection *conn, enum evws_opcode opcode, const char *data, uint64_t length);
110  static void wsBroadcast(const char *uri, enum evws_opcode opcode, const char *data, uint64_t length);
111 
112  static bool registerServlet(const std::string& path, HTTPServlet* servlet);
113  static void unregisterServlet(HTTPServlet* servlet);
114 
115  static bool registerServlet(const std::string& path, WebSocketServlet* servlet);
116  static void unregisterServlet(WebSocketServlet* servlet);
117 
118 private:
119 
120  class WSData {
121  public:
122  WSData(struct evws_connection *conn_, const char *uri_, enum evws_opcode opcode_, const char *data_, uint64_t length_) {
123  conn = conn_;
124  if (uri_)
125  uri = uri_;
126  opcode = opcode_;
127  data = std::string(data_, length_);
128  }
129  struct evws_connection *conn;
130  std::string data;
131  std::string uri;
132  evws_opcode opcode;
133  };
134 
135  struct comp_strsize_less {
136  bool operator()(std::string const& l, std::string const& r) const {
137  if (l.size() < r.size())
138  return false;
139  return true;
140 // return l < r;
141  };
142  };
143 
144  HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* sslConf);
145  virtual ~HTTPServer();
146 
147  void start();
148  void stop();
149  static void run(void* instance);
150 
151  void determineAddress();
152 
153  static void replyCallback(evutil_socket_t fd, short what, void *arg);
154  static void wsSendCallback(evutil_socket_t fd, short what, void *arg);
155 
156  static void httpRecvReqCallback(struct evhttp_request *req, void *callbackData);
157  static void wsRecvReqCallback(struct evws_connection *conn, struct evws_frame *, void *callbackData);
158 
159  void processByMatchingServlet(const Request& request);
160  void processByMatchingServlet(evws_connection* conn, const WSFrame& frame);
161 
162  static std::map<std::string, std::string> mimeTypes;
163  std::map<std::string, HTTPServlet*> _httpServlets;
164  typedef std::map<std::string, HTTPServlet*>::iterator http_servlet_iter_t;
165 
166  std::map<std::string, WebSocketServlet*> _wsServlets;
167  typedef std::map<std::string, WebSocketServlet*>::iterator ws_servlet_iter_t;
168 
169  struct event_base* _base;
170  struct evhttp* _http;
171  struct evws* _evws;
172 
173  struct evhttp_bound_socket* _httpHandle;
174  evutil_socket_t _wsHandle;
175 
176  unsigned short _port;
177  unsigned short _wsPort;
178  std::string _address;
179 
180  static HTTPServer* _instance;
181 
182  static std::recursive_mutex _instanceMutex;
183  std::thread* _thread;
184  std::recursive_mutex _mutex;
185  bool _isRunning;
186 
187  friend class HTTPServlet;
188  friend class WebSocketServlet;
189 
190 #if (defined EVENT_SSL_FOUND && defined OPENSSL_FOUND && defined OPENSSL_HAS_ELIPTIC_CURVES)
191  struct evhttp* _https;
192  struct evhttp_bound_socket* _sslHandle;
193  unsigned short _sslPort;
194 
195  static struct bufferevent* sslBufferEventCallback(struct event_base *base, void *arg);
196  static void sslGeneralBufferEventCallback (struct evhttp_request *req, void *arg);
197 #endif
198 };
199 
200 class USCXML_API HTTPServlet {
201 public:
202  virtual ~HTTPServlet() {}
203  virtual bool requestFromHTTP(const HTTPServer::Request& request) = 0;
204  virtual void setURL(const std::string& url) = 0;
205  virtual bool canAdaptPath() {
206  return true;
207  }
208 };
209 
210 class USCXML_API WebSocketServlet {
211 public:
212  virtual ~WebSocketServlet() {}
213  virtual bool requestFromWS(struct evws_connection *conn, const HTTPServer::WSFrame& frame) = 0;
214  virtual void setURL(const std::string& url) = 0;
215  virtual bool canAdaptPath() {
216  return true;
217  }
218 };
219 
220 }
221 
222 #endif /* end of include guard: HTTPSERVER_H_AIH108EG */
Definition: HTTPServer.h:210
virtual bool canAdaptPath()
Called by the server with the actual URL.
Definition: HTTPServer.h:205
Definition: HTTPServer.h:66
Definition: HTTPServer.h:45
Definition: Breakpoint.cpp:26
Definition: HTTPServer.h:73
Definition: HTTPServer.h:47
Definition: HTTPServer.h:90
Definition: Event.h:94
Definition: HTTPServer.h:200
Definition: HTTPServer.h:58
virtual bool canAdaptPath()
Called by the server with the actual URL.
Definition: HTTPServer.h:215