#ifndef RHO_HTTP_SERVER_F5FFD21AD3EE463E850C5E2C789397BD #define RHO_HTTP_SERVER_F5FFD21AD3EE463E850C5E2C789397BD #include "common/RhoStd.h" #include "logging/RhoLog.h" #if !defined(OS_WINDOWS) && !defined(OS_WINCE) typedef int SOCKET; # define INVALID_SOCKET -1 # define SOCKET_ERROR -1 # define RHO_NET_ERROR_CODE errno # define closesocket close #else # if defined(OS_WINCE) # include # endif # define RHO_NET_ERROR_CODE ::WSAGetLastError() #endif namespace rho { namespace net { struct HttpHeader { String name; String value; HttpHeader() {} HttpHeader(String const &n, String const &v) :name(n), value(v) {} HttpHeader(String const &n, int v) :name(n) { char buf[30]; snprintf(buf, sizeof(buf), "%d", v); value = buf; } }; typedef Vector HttpHeaderList; class CHttpServer { DEFINE_LOGCLASS; enum {BUF_SIZE = 4096}; typedef HttpHeader Header; typedef HttpHeaderList HeaderList; typedef Vector ByteVector; struct Route { String application; String model; String id; String action; }; public: typedef void (*callback_t)(void *arg, String const &query); public: CHttpServer(int port, String const &root); ~CHttpServer(); void register_uri(String const &uri, callback_t const &callback); bool started() const {return m_active;} bool run(); void stop(); bool send_response(String const &response, bool redirect = false); bool send_response_body(String const &data) {return send_response_impl(data, true);} String create_response(String const &reason); String create_response(String const &reason, HeaderList const &headers); String create_response(String const &reason, String const &body); String create_response(String const &reason, HeaderList const &headers, String const &body); static int isIndex(String const &uri); bool call_ruby_method(String const &uri, String const &body, String& strReply); private: bool init(); void close_listener(); bool process(SOCKET sock); bool parse_request(String &method, String &uri, String &query, HeaderList &headers, String &body); bool parse_startline(String const &line, String &method, String &uri, String &query); bool parse_header(String const &line, Header &hdr); bool parse_route(String const &uri, Route &route); bool receive_request(ByteVector &request); bool decide(String const &method, String const &uri, String const &query, HeaderList const &headers, String const &body); bool dispatch(String const &uri, Route &route); bool send_file(String const &path, HeaderList const &hdrs); bool send_response_impl(String const &data, bool continuation); callback_t registered(String const &uri); private: bool m_active; int m_port; String m_root, m_strRhoRoot; SOCKET m_listener; SOCKET m_sock; std::map m_registered; bool verbose; }; } // namespace net } // namespace rho #endif // RHO_HTTP_SERVER_F5FFD21AD3EE463E850C5E2C789397BD