diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-09-04 11:48:54 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-09-04 13:06:32 +0200 |
commit | 9aa90994ee85e549ddbe23a6f03e33d0edcd57b2 (patch) | |
tree | 1f5eb525df417378a8677084a5a01731bca76960 /src/httpserver.h | |
parent | 4b437b227c596f23ab8983559552b8c4910d2b17 (diff) | |
parent | d52802551752140cf41f0d9a225a43e84404d3e9 (diff) | |
download | bitcoin-9aa90994ee85e549ddbe23a6f03e33d0edcd57b2.tar.xz |
Merge pull request #5677
d528025 Revert "rpc-tests: re-enable rpc-tests for Windows" (Wladimir J. van der Laan)
1e700c9 doc: update deps in build-unix.md after libevent (Wladimir J. van der Laan)
26c9b83 Move windows socket init to utility function (Wladimir J. van der Laan)
4be0b08 libevent: Windows reuseaddr workaround in depends (Cory Fields)
3a174cd Fix race condition between starting HTTP server thread and setting EventBase() (Wladimir J. van der Laan)
6d2bc22 Document options for new HTTP/RPC server in --help (Wladimir J. van der Laan)
be33f3f Implement RPCTimerHandler for Qt RPC console (Wladimir J. van der Laan)
57d85d9 doc: mention SSL support dropped for RPC in release notes (Wladimir J. van der Laan)
40b556d evhttpd implementation (Wladimir J. van der Laan)
ee2a42b tests: GET requests cannot have request body, use POST in rest.py (Wladimir J. van der Laan)
6e996d3 tests: fix qt payment test (Cory Fields)
3140ef9 build: build-system changes for libevent (Wladimir J. van der Laan)
a9af234 libevent: add depends (Cory Fields)
6a21dd5 Remove rpc_boostasiotocnetaddr test (Wladimir J. van der Laan)
8f9301c qa: Remove -rpckeepalive tests from httpbasics (Wladimir J. van der Laan)
51fcfc0 doc: remove documentation for rpcssl (Wladimir J. van der Laan)
Diffstat (limited to 'src/httpserver.h')
-rw-r--r-- | src/httpserver.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/httpserver.h b/src/httpserver.h new file mode 100644 index 0000000000..459c60c047 --- /dev/null +++ b/src/httpserver.h @@ -0,0 +1,149 @@ +// 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 <string> +#include <stdint.h> +#include <boost/thread.hpp> +#include <boost/scoped_ptr.hpp> +#include <boost/function.hpp> + +static const int DEFAULT_HTTP_THREADS=4; +static const int DEFAULT_HTTP_WORKQUEUE=16; +static const int DEFAULT_HTTP_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(boost::thread_group& threadGroup); +/** Interrupt HTTP server threads */ +void InterruptHTTPServer(); +/** Stop HTTP server */ +void StopHTTPServer(); + +/** Handler for requests to a certain HTTP path */ +typedef boost::function<void(HTTPRequest* req, const std::string &)> 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: + HTTPRequest(struct evhttp_request* req); + ~HTTPRequest(); + + enum RequestMethod { + UNKNOWN, + GET, + POST, + HEAD, + PUT + }; + + /** Get requested URI. + */ + std::string GetURI(); + + /** Get CService (address:ip) for the origin of the http request. + */ + CService GetPeer(); + + /** Get request method. + */ + RequestMethod GetRequestMethod(); + + /** + * Get the request header specified by hdr, or an empty string. + * Return an pair (isPresent,string). + */ + std::pair<bool, std::string> GetHeader(const std::string& hdr); + + /** + * 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 an 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 boost::function<void(void)>& 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; + boost::function<void(void)> handler; +private: + struct event* ev; +}; + +#endif // BITCOIN_HTTPSERVER_H |