brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 1 | #include "event2/buffer.h" |
| 2 | #include "event2/http.h" |
| 3 | |
| 4 | #include <string> |
| 5 | |
| 6 | namespace aos { |
| 7 | namespace http { |
| 8 | |
| 9 | // An HTTP server that serves files from a directory using libevent. |
| 10 | // Also allows configuring certain URLs to be dynamically generated. |
| 11 | class HTTPServer { |
| 12 | public: |
| 13 | HTTPServer(const char *directory, uint16_t port); |
| 14 | // Starts serving pages. |
| 15 | // Might not clean up everything before returning. |
| 16 | void Run(); |
| 17 | protected: |
| 18 | template<class T> class MemberHandler { |
| 19 | public: |
| 20 | typedef void (T::*Handler)(evhttp_request *); |
| 21 | struct Holder { |
| 22 | T *self; |
| 23 | Handler handler; |
| 24 | }; |
| 25 | static void Call(evhttp_request *request, void *handler_in) { |
| 26 | const Holder *const holder = static_cast<Holder *>(handler_in); |
| 27 | AddStandardHeaders(request); |
| 28 | ((holder->self)->*(holder->handler))(request); |
| 29 | } |
| 30 | }; |
| 31 | void AddPage(const std::string &path, void (*handler)(evhttp_request *, void *), |
| 32 | void *data); |
| 33 | template<class T> void AddPage(const std::string &path, |
| 34 | typename MemberHandler<T>::Handler handler, |
| 35 | T *self) { |
| 36 | // have to put "typename" in, so the typedef makes it clearer |
| 37 | typedef typename MemberHandler<T>::Holder HolderType; |
| 38 | AddPage(path, MemberHandler<T>::Call, new HolderType{self, handler}); |
| 39 | } |
| 40 | // This gets set up as the generic handler. |
| 41 | // It can also be called separately to serve the file that the request is |
| 42 | // requesting from the filesystem. |
| 43 | void ServeFile(evhttp_request *request); |
| 44 | private: |
| 45 | // The directory where files to be served come from. |
| 46 | const char *directory_; |
| 47 | // The main libevent structure. |
| 48 | event_base *const base_; |
| 49 | // The libevent HTTP server handle. |
| 50 | evhttp *const http_; |
| 51 | static void AddStandardHeaders(evhttp_request *request); |
| 52 | static void StaticServeFile(evhttp_request *request, void *self) { |
| 53 | static_cast<HTTPServer *>(self)->ServeFile(request); |
| 54 | } |
| 55 | }; |
| 56 | |
| 57 | } // namespace http |
| 58 | } // namespace aos |