Branch data Line data Source code
# 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 <functional>
# 9 : : #include <optional>
# 10 : : #include <string>
# 11 : :
# 12 : : static const int DEFAULT_HTTP_THREADS=4;
# 13 : : static const int DEFAULT_HTTP_WORKQUEUE=16;
# 14 : : static const int DEFAULT_HTTP_SERVER_TIMEOUT=30;
# 15 : :
# 16 : : struct evhttp_request;
# 17 : : struct event_base;
# 18 : : class CService;
# 19 : : class HTTPRequest;
# 20 : :
# 21 : : /** Initialize HTTP server.
# 22 : : * Call this before RegisterHTTPHandler or EventBase().
# 23 : : */
# 24 : : bool InitHTTPServer();
# 25 : : /** Start HTTP server.
# 26 : : * This is separate from InitHTTPServer to give users race-condition-free time
# 27 : : * to register their handlers between InitHTTPServer and StartHTTPServer.
# 28 : : */
# 29 : : void StartHTTPServer();
# 30 : : /** Interrupt HTTP server threads */
# 31 : : void InterruptHTTPServer();
# 32 : : /** Stop HTTP server */
# 33 : : void StopHTTPServer();
# 34 : :
# 35 : : /** Change logging level for libevent. */
# 36 : : void 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 : : /** Get the query parameter value from request uri for a specified key, or std::nullopt if the
# 87 : : * key is not found.
# 88 : : *
# 89 : : * If the query string contains duplicate keys, the first value is returned. Many web frameworks
# 90 : : * would instead parse this as an array of values, but this is not (yet) implemented as it is
# 91 : : * currently not needed in any of the endpoints.
# 92 : : *
# 93 : : * @param[in] key represents the query parameter of which the value is returned
# 94 : : */
# 95 : : std::optional<std::string> GetQueryParameter(const std::string& key) const;
# 96 : :
# 97 : : /**
# 98 : : * Get the request header specified by hdr, or an empty string.
# 99 : : * Return a pair (isPresent,string).
# 100 : : */
# 101 : : std::pair<bool, std::string> GetHeader(const std::string& hdr) const;
# 102 : :
# 103 : : /**
# 104 : : * Read request body.
# 105 : : *
# 106 : : * @note As this consumes the underlying buffer, call this only once.
# 107 : : * Repeated calls will return an empty string.
# 108 : : */
# 109 : : std::string ReadBody();
# 110 : :
# 111 : : /**
# 112 : : * Write output header.
# 113 : : *
# 114 : : * @note call this before calling WriteErrorReply or Reply.
# 115 : : */
# 116 : : void WriteHeader(const std::string& hdr, const std::string& value);
# 117 : :
# 118 : : /**
# 119 : : * Write HTTP reply.
# 120 : : * nStatus is the HTTP status code to send.
# 121 : : * strReply is the body of the reply. Keep it empty to send a standard message.
# 122 : : *
# 123 : : * @note Can be called only once. As this will give the request back to the
# 124 : : * main thread, do not call any other HTTPRequest methods after calling this.
# 125 : : */
# 126 : : void WriteReply(int nStatus, const std::string& strReply = "");
# 127 : : };
# 128 : :
# 129 : : /** Get the query parameter value from request uri for a specified key, or std::nullopt if the key
# 130 : : * is not found.
# 131 : : *
# 132 : : * If the query string contains duplicate keys, the first value is returned. Many web frameworks
# 133 : : * would instead parse this as an array of values, but this is not (yet) implemented as it is
# 134 : : * currently not needed in any of the endpoints.
# 135 : : *
# 136 : : * Helper function for HTTPRequest::GetQueryParameter.
# 137 : : *
# 138 : : * @param[in] uri is the entire request uri
# 139 : : * @param[in] key represents the query parameter of which the value is returned
# 140 : : */
# 141 : : std::optional<std::string> GetQueryParameterFromUri(const char* uri, const std::string& key);
# 142 : :
# 143 : : /** Event handler closure.
# 144 : : */
# 145 : : class HTTPClosure
# 146 : : {
# 147 : : public:
# 148 : : virtual void operator()() = 0;
# 149 : 137601 : virtual ~HTTPClosure() {}
# 150 : : };
# 151 : :
# 152 : : /** Event class. This can be used either as a cross-thread trigger or as a timer.
# 153 : : */
# 154 : : class HTTPEvent
# 155 : : {
# 156 : : public:
# 157 : : /** Create a new event.
# 158 : : * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called)
# 159 : : * handler is the handler to call when the event is triggered.
# 160 : : */
# 161 : : HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function<void()>& handler);
# 162 : : ~HTTPEvent();
# 163 : :
# 164 : : /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after
# 165 : : * the given time has elapsed.
# 166 : : */
# 167 : : void trigger(struct timeval* tv);
# 168 : :
# 169 : : bool deleteWhenTriggered;
# 170 : : std::function<void()> handler;
# 171 : : private:
# 172 : : struct event* ev;
# 173 : : };
# 174 : :
# 175 : : #endif // BITCOIN_HTTPSERVER_H
|