1 // Copyright (c) 2015-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_HTTPSERVER_H
6 #define BITCOIN_HTTPSERVER_H
7 
8 #include <string>
9 #include <functional>
10 
11 static const int DEFAULT_HTTP_THREADS=4;
12 static const int DEFAULT_HTTP_WORKQUEUE=16;
13 static const int DEFAULT_HTTP_SERVER_TIMEOUT=30;
14 
15 struct evhttp_request;
16 struct event_base;
17 class CService;
18 class HTTPRequest;
19 
20 /** Initialize HTTP server.
21  * Call this before RegisterHTTPHandler or EventBase().
22  */
23 bool InitHTTPServer();
24 /** Start HTTP server.
25  * This is separate from InitHTTPServer to give users race-condition-free time
26  * to register their handlers between InitHTTPServer and StartHTTPServer.
27  */
28 void StartHTTPServer();
29 /** Interrupt HTTP server threads */
30 void InterruptHTTPServer();
31 /** Stop HTTP server */
32 void StopHTTPServer();
33 
34 /** Change logging level for libevent. Removes BCLog::LIBEVENT from log categories if
35  * libevent doesn't support debug logging.*/
36 bool UpdateHTTPServerLogging(bool enable);
37 
38 /** Handler for requests to a certain HTTP path */
39 typedef std::function<bool(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
40 /** Register handler for prefix.
41  * If multiple handlers match a prefix, the first-registered one will
42  * be invoked.
43  */
44 void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler);
45 /** Unregister handler for prefix */
46 void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch);
47 
48 /** Return evhttp event base. This can be used by submodules to
49  * queue timers or custom events.
50  */
51 struct event_base* EventBase();
52 
53 /** In-flight HTTP request.
54  * Thin C++ wrapper around evhttp_request.
55  */
56 class HTTPRequest
57 {
58 private:
59     struct evhttp_request* req;
60     bool replySent;
61 
62 public:
63     explicit HTTPRequest(struct evhttp_request* req, bool replySent = false);
64     ~HTTPRequest();
65 
66     enum RequestMethod {
67         UNKNOWN,
68         GET,
69         POST,
70         HEAD,
71         PUT
72     };
73 
74     /** Get requested URI.
75      */
76     std::string GetURI() const;
77 
78     /** Get CService (address:ip) for the origin of the http request.
79      */
80     CService GetPeer() const;
81 
82     /** Get request method.
83      */
84     RequestMethod GetRequestMethod() const;
85 
86     /**
87      * Get the request header specified by hdr, or an empty string.
88      * Return a pair (isPresent,string).
89      */
90     std::pair<bool, std::string> GetHeader(const std::string& hdr) const;
91 
92     /**
93      * Read request body.
94      *
95      * @note As this consumes the underlying buffer, call this only once.
96      * Repeated calls will return an empty string.
97      */
98     std::string ReadBody();
99 
100     /**
101      * Write output header.
102      *
103      * @note call this before calling WriteErrorReply or Reply.
104      */
105     void WriteHeader(const std::string& hdr, const std::string& value);
106 
107     /**
108      * Write HTTP reply.
109      * nStatus is the HTTP status code to send.
110      * strReply is the body of the reply. Keep it empty to send a standard message.
111      *
112      * @note Can be called only once. As this will give the request back to the
113      * main thread, do not call any other HTTPRequest methods after calling this.
114      */
115     void WriteReply(int nStatus, const std::string& strReply = "");
116 };
117 
118 /** Event handler closure.
119  */
120 class HTTPClosure
121 {
122 public:
123     virtual void operator()() = 0;
~HTTPClosure()124     virtual ~HTTPClosure() {}
125 };
126 
127 /** Event class. This can be used either as a cross-thread trigger or as a timer.
128  */
129 class HTTPEvent
130 {
131 public:
132     /** Create a new event.
133      * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called)
134      * handler is the handler to call when the event is triggered.
135      */
136     HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function<void()>& handler);
137     ~HTTPEvent();
138 
139     /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after
140      * the given time has elapsed.
141      */
142     void trigger(struct timeval* tv);
143 
144     bool deleteWhenTriggered;
145     std::function<void()> handler;
146 private:
147     struct event* ev;
148 };
149 
150 #endif // BITCOIN_HTTPSERVER_H
151