blob: 99eb29572f2fe8614dbc86dfc11bd94edec2e33a [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include "event2/buffer.h"
2#include "event2/http.h"
3
4#include <string>
5
6namespace aos {
7namespace http {
8
9// An HTTP server that serves files from a directory using libevent.
10// Also allows configuring certain URLs to be dynamically generated.
11class 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