You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.9 KiB
147 lines
3.9 KiB
// 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 <functional> |
|
|
|
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(); |
|
|
|
/** Handler for requests to a certain HTTP path */ |
|
typedef std::function<bool(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 std::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; |
|
std::function<void(void)> handler; |
|
private: |
|
struct event* ev; |
|
}; |
|
|
|
#endif // BITCOIN_HTTPSERVER_H
|
|
|