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