]>
Commit | Line | Data |
---|---|---|
afd64f76 WL |
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 | ||
9fb5b94e WL |
14 | static const int DEFAULT_HTTP_THREADS=4; |
15 | static const int DEFAULT_HTTP_WORKQUEUE=16; | |
89bccddc | 16 | static const int DEFAULT_HTTP_SERVER_TIMEOUT=30; |
9fb5b94e | 17 | |
afd64f76 WL |
18 | struct evhttp_request; |
19 | struct event_base; | |
20 | class CService; | |
21 | class HTTPRequest; | |
22 | ||
116503c0 WL |
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 | */ | |
afd64f76 WL |
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 | class HTTPClosure | |
120 | { | |
121 | public: | |
122 | virtual void operator()() = 0; | |
123 | 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: | |
858afa1a WL |
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); | |
afd64f76 WL |
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 | ||
afd64f76 | 143 | bool deleteWhenTriggered; |
858afa1a WL |
144 | boost::function<void(void)> handler; |
145 | private: | |
afd64f76 | 146 | struct event* ev; |
afd64f76 WL |
147 | }; |
148 | ||
149 | #endif // BITCOIN_HTTPSERVER_H |