#ifndef HTTPSERVER_H_AIH108EG #define HTTPSERVER_H_AIH108EG #include #include #include #include "uscxml/concurrency/tinythread.h" #include "uscxml/Message.h" namespace uscxml { class HTTPServlet; class HTTPServer { public: class Request : public Event { public: Request() : curlReq(NULL) {} std::string content; struct evhttp_request* curlReq; operator bool() { return curlReq != NULL; } }; class Reply { public: Reply(Request req) : status(200), type(req.data.compound["type"].atom), curlReq(req.curlReq) {} int status; std::string type; std::map headers; std::string content; struct evhttp_request* curlReq; }; struct CallbackData { HTTPServlet* servlet; evhttp_request* httpReq; }; static HTTPServer* getInstance(int port = 8080); static std::string getBaseURL(); static void reply(const Reply& reply); static std::string mimeTypeForExtension(const std::string& ext); static bool registerServlet(const std::string& path, HTTPServlet* servlet); ///< Register a servlet, returns false if path is already taken static void unregisterServlet(HTTPServlet* servlet); private: struct comp_strsize_less { bool operator()(std::string const& l, std::string const& r) const { if (l.size() < r.size()) return false; return l < r; }; }; HTTPServer(unsigned short port); ~HTTPServer(); void start(); void stop(); static void run(void* instance); void determineAddress(); static void replyCallback(evutil_socket_t fd, short what, void *arg); static void httpRecvReqCallback(struct evhttp_request *req, void *callbackData); void processByMatchingServlet(const Request& request); static std::map mimeTypes; std::map _servlets; typedef std::map::iterator servlet_iter_t; struct event_base* _base; struct evhttp* _http; struct evhttp_bound_socket* _handle; unsigned short _port; std::string _address; static HTTPServer* _instance; static tthread::recursive_mutex _instanceMutex; tthread::thread* _thread; tthread::recursive_mutex _mutex; bool _isRunning; friend class HTTPServlet; }; class HTTPServlet { public: virtual bool httpRecvRequest(const HTTPServer::Request& request) = 0; virtual void setURL(const std::string& url) = 0; /// Called by the server with the actual URL virtual bool canAdaptPath() { return true; } }; } #endif /* end of include guard: HTTPSERVER_H_AIH108EG */