// Copyright (c) 2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_HTTPSERVER_H #define BITCOIN_HTTPSERVER_H #include #include #include static const int DEFAULT_HTTP_THREADS=4; static const int DEFAULT_HTTP_WORKQUEUE=16; static const int DEFAULT_HTTP_SERVER_TIMEOUT=30; struct evhttp_request; struct event_base; class CService; class HTTPRequest; /** Initialize HTTP server. * Call this before RegisterHTTPHandler or EventBase(). */ bool InitHTTPServer(); /** Start HTTP server. * This is separate from InitHTTPServer to give users race-condition-free time * to register their handlers between InitHTTPServer and StartHTTPServer. */ bool StartHTTPServer(); /** Interrupt HTTP server threads */ void InterruptHTTPServer(); /** Stop HTTP server */ void StopHTTPServer(); /** Change logging level for libevent. Removes BCLog::LIBEVENT from log categories if * libevent doesn't support debug logging.*/ bool UpdateHTTPServerLogging(bool enable); /** Handler for requests to a certain HTTP path */ typedef std::function HTTPRequestHandler; /** Register handler for prefix. * If multiple handlers match a prefix, the first-registered one will * be invoked. */ void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler); /** Unregister handler for prefix */ void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch); /** Return evhttp event base. This can be used by submodules to * queue timers or custom events. */ struct event_base* EventBase(); /** In-flight HTTP request. * Thin C++ wrapper around evhttp_request. */ class HTTPRequest { private: struct evhttp_request* req; bool replySent; public: explicit HTTPRequest(struct evhttp_request* req); ~HTTPRequest(); enum RequestMethod { UNKNOWN, GET, POST, HEAD, PUT }; /** Get requested URI. */ std::string GetURI() const; /** Get CService (address:ip) for the origin of the http request. */ CService GetPeer() const; /** Get request method. */ RequestMethod GetRequestMethod() const; /** * Get the request header specified by hdr, or an empty string. * Return a pair (isPresent,string). */ std::pair GetHeader(const std::string& hdr) const; /** * Read request body. * * @note As this consumes the underlying buffer, call this only once. * Repeated calls will return an empty string. */ std::string ReadBody(); /** * Write output header. * * @note call this before calling WriteErrorReply or Reply. */ void WriteHeader(const std::string& hdr, const std::string& value); /** * Write HTTP reply. * nStatus is the HTTP status code to send. * strReply is the body of the reply. Keep it empty to send a standard message. * * @note Can be called only once. As this will give the request back to the * main thread, do not call any other HTTPRequest methods after calling this. */ void WriteReply(int nStatus, const std::string& strReply = ""); }; /** Event handler closure. */ class HTTPClosure { public: virtual void operator()() = 0; virtual ~HTTPClosure() {} }; /** Event class. This can be used either as a cross-thread trigger or as a timer. */ class HTTPEvent { public: /** Create a new event. * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called) * handler is the handler to call when the event is triggered. */ HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function& handler); ~HTTPEvent(); /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after * the given time has elapsed. */ void trigger(struct timeval* tv); bool deleteWhenTriggered; std::function handler; private: struct event* ev; }; #endif // BITCOIN_HTTPSERVER_H