EVHttpServer  1.0.0
A Lightweight http server base libevent and threadpool
EVHttpServer.h
1 #ifndef _EVHTTP_SERVER_H_
2 #define _EVHTTP_SERVER_H_
3 
4 #include <string>
5 #include <unordered_map>
6 #include <mutex>
7 #include <thread>
8 #include <list>
9 #include <regex>
10 #include <memory>
11 
19 #define USE_LINUX_REGEX_API (1)
20 
21 #ifdef _WIN32
22  #define USE_LINUX_REGEX_API (0)
23 #else
24  #include <sys/types.h>
25  #include <regex.h>
26 #endif
27 
33 class ThreadPool;
34 
40 struct evhttp_request;
41 
47 struct event_base;
48 
57 {
58 public:
63  enum ReqType {
64  REQ_GET = 1 << 0,
65  REQ_POST = 1 << 1,
66  REQ_HEAD = 1 << 2,
67  REQ_PUT = 1 << 3,
68  REQ_DELETE = 1 << 4,
69  REQ_OPTIONS = 1 << 5,
70  REQ_TRACE = 1 << 6,
71  REQ_CONNECT = 1 << 7,
72  REQ_PATCH = 1 << 8
73  };
74 
79  struct HttpKeyVal
80  {
81  std::string key;
82  std::string value;
83  };
84 
91  class HttpReq
92  {
93  public:
94  ReqType method() const;
95  std::string methodStr() const;
96  std::string path() const;
97  std::string body() const;
98  std::unique_ptr<char[]> bodyRaw() const;
99  std::string uri() const;
100  std::string host() const;
101 
102  void headers(std::list<HttpKeyVal> & ret) const;
103  bool findHeader(const std::string & key, std::string & value) const;
104 
105  void querys(std::list<HttpKeyVal> & ret) const;
106  bool findQuery(const std::string & key, std::string & value) const;
107  private:
108  HttpReq(const HttpReq &) = delete;
109  HttpReq & operator = (const HttpReq &) = delete;
110  HttpReq(evhttp_request * req);
111  struct evhttp_request * m_request = nullptr;
112  friend EVHttpServer;
113  };
114 
120  class HttpRes
121  {
122  public:
123  bool setBody(const std::string & body);
124  bool addHeader(const HttpKeyVal & header);
125  bool addHeaders(const std::list<HttpKeyVal> & list);
126  bool setHeaders(const std::list<HttpKeyVal> & list);
127 
128  void setCode(const int & code);
129  void setReason(const std::string & reason);
130  private:
131  HttpRes(const HttpRes &) = delete;
132  HttpRes & operator = (const HttpRes &) = delete;
133  HttpRes(evhttp_request * req);
134  private:
135  int getCode(void) const;
136  const char * getReason(void) const;
137  private:
138  int m_code = 200;
139  std::string m_reason;
140  struct evhttp_request * m_request = nullptr;
141  bool m_initBody = false;
142  friend EVHttpServer;
143  };
144 
145  using ReqHandler = void (*)(const HttpReq & req, HttpRes & res, void * arg);/* Define http request callback function type */
146 public:
151  {
152  public:
153  PathAndMethod() : method(ReqType::REQ_GET)
154  {
155  }
156  PathAndMethod(ReqType m, const std::string & u) : method(m), path(u)
157  {
158  }
159  bool operator == (const PathAndMethod & info) const
160  {
161  return ((this->method == info.method) && (this->path == info.path));
162  }
163  public:
164  ReqType method;
165  std::string path;
166  };
167 public:
168  EVHttpServer();
169  virtual ~EVHttpServer();
170  bool init(const unsigned int port, const std::string & ip = "0.0.0.0");
171  bool init(const std::list<unsigned int> & portList, const std::string & ip = "0.0.0.0");
172  bool start(const unsigned int threadNum = 5);
173  bool stop();
174  bool addHandler(const PathAndMethod & reqArg, const ReqHandler & handler, void * arg = nullptr);
175  bool rmHandler(const PathAndMethod & reqArg);
176  bool addRegHandler(const PathAndMethod & reqArg, const ReqHandler & handler, void * arg = nullptr);
177  bool rmRegHandler(const PathAndMethod & reqArg);
178 private:
179  bool deInit();
180  static void handleHttpEvent(struct evhttp_request * request, void * arg);
181  static void * dispatchThread(void * arg);
182 private:
183  struct PathAndMethodHash
184  {
185  std::size_t operator () (const PathAndMethod & t) const
186  {
187  std::string key = std::to_string(t.method) + t.path;
188  std::hash<std::string> strHash;
189  return strHash(key);
190  }
191  };
192  struct CallBackBind
193  {
194  ReqHandler func;
195  void * arg;
196  };
197  struct RegNode
198  {
199  PathAndMethod reqArg;
200 #if USE_LINUX_REGEX_API
201  regex_t reg;
202 #else
203  std::regex reg;
204 #endif
205  CallBackBind callbackBind;
206  };
207 private:
208  static void dealTask(struct evhttp_request * request, const PathAndMethod & reqArg, const CallBackBind & handleBind);
209 private:
210  std::thread * m_thread = nullptr; /* dispatch thread */
211  volatile bool m_isInited = false; /* initialized flag */
212  volatile bool m_isRunning = false; /* dispatch thread run flag */
213  event_base * m_base = nullptr;
214  std::list<void *> m_evhttpList;
215  std::mutex m_mutex;
216  std::unordered_map<PathAndMethod, CallBackBind, PathAndMethodHash> m_handlerMap; /* map of request and callback functions */
217  std::list<RegNode> m_regList;
218  ThreadPool * m_threadPool = nullptr;
219  EVHttpServer(const EVHttpServer &) = delete;
220  EVHttpServer & operator = (const EVHttpServer &) = delete;
221 };
222 
223 #endif
bool start(const unsigned int threadNum=5)
Start http server,run event dispatch thread. if threadNum > 0, the thread pool will be created and s...
Definition: EVHttpServer.cpp:190
bool addRegHandler(const PathAndMethod &reqArg, const ReqHandler &handler, void *arg=nullptr)
Add a handler for "regex path", handlers can be registered both before and after the start function i...
Definition: EVHttpServer.cpp:469
ReqType
ReqType is the enumeration type of the http request method, refer to the evhttp_cmd_type type definit...
Definition: EVHttpServer.h:63
bool rmRegHandler(const PathAndMethod &reqArg)
Remove handlers for "regex path".
Definition: EVHttpServer.cpp:530
bool addHandler(const PathAndMethod &reqArg, const ReqHandler &handler, void *arg=nullptr)
Register the callback handler function corresponding to the http request, handlers can be registered ...
Definition: EVHttpServer.cpp:239
EVHttpServer is just an http server implemented by encapsulating libevent using c++, It provides:
Definition: EVHttpServer.h:56
bool stop()
Stop the event dispatch thread and destroy the thread pool.
Definition: EVHttpServer.cpp:389
Definition: ThreadPool.h:14
bool init(const unsigned int port, const std::string &ip="0.0.0.0")
initialize http server
Definition: EVHttpServer.cpp:34
bool rmHandler(const PathAndMethod &reqArg)
Remove the callback handler corresponding to the http request.
Definition: EVHttpServer.cpp:270
HttpKeyVal is a key-value pair used to represent the HTTP head and HTTP Query.
Definition: EVHttpServer.h:79
HttpRes is the encapsulation class of http response, which provides methods for setting body...
Definition: EVHttpServer.h:120
EVHttpServer()
Construct EVHttpServer object.
Definition: EVHttpServer.cpp:23
Path and method are used to represent an HTTP request.
Definition: EVHttpServer.h:150
virtual ~EVHttpServer()
destructor
Definition: EVHttpServer.cpp:446
HttpReq is an encapsulation class for http requests, which provides access to method, path, body, etc. It is not allowed to be created externally. Some components of the uri do not provide access functions.
Definition: EVHttpServer.h:91