diff options
Diffstat (limited to 'src/httpserver.cpp')
-rw-r--r-- | src/httpserver.cpp | 96 |
1 files changed, 64 insertions, 32 deletions
diff --git a/src/httpserver.cpp b/src/httpserver.cpp index e00c68585e..8e00a6278f 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -9,9 +9,9 @@ #include <httpserver.h> #include <chainparamsbase.h> -#include <compat.h> +#include <compat/compat.h> #include <netbase.h> -#include <node/ui_interface.h> +#include <node/interface_ui.h> #include <rpc/protocol.h> // For HTTP status codes #include <shutdown.h> #include <sync.h> @@ -23,6 +23,7 @@ #include <deque> #include <memory> +#include <optional> #include <stdio.h> #include <stdlib.h> #include <string> @@ -30,11 +31,12 @@ #include <sys/types.h> #include <sys/stat.h> -#include <event2/thread.h> #include <event2/buffer.h> #include <event2/bufferevent.h> -#include <event2/util.h> +#include <event2/http.h> #include <event2/keyvalq_struct.h> +#include <event2/thread.h> +#include <event2/util.h> #include <support/events.h> @@ -71,21 +73,18 @@ private: Mutex cs; std::condition_variable cond GUARDED_BY(cs); std::deque<std::unique_ptr<WorkItem>> queue GUARDED_BY(cs); - bool running GUARDED_BY(cs); + bool running GUARDED_BY(cs){true}; const size_t maxDepth; public: - explicit WorkQueue(size_t _maxDepth) : running(true), - maxDepth(_maxDepth) + explicit WorkQueue(size_t _maxDepth) : maxDepth(_maxDepth) { } /** Precondition: worker threads have all stopped (they have been joined). */ - ~WorkQueue() - { - } + ~WorkQueue() = default; /** Enqueue a work item */ - bool Enqueue(WorkItem* item) + bool Enqueue(WorkItem* item) EXCLUSIVE_LOCKS_REQUIRED(!cs) { LOCK(cs); if (!running || queue.size() >= maxDepth) { @@ -96,7 +95,7 @@ public: return true; } /** Thread function */ - void Run() + void Run() EXCLUSIVE_LOCKS_REQUIRED(!cs) { while (true) { std::unique_ptr<WorkItem> i; @@ -113,7 +112,7 @@ public: } } /** Interrupt and exit loops */ - void Interrupt() + void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!cs) { LOCK(cs); running = false; @@ -345,10 +344,22 @@ static void HTTPWorkQueueRun(WorkQueue<HTTPClosure>* queue, int worker_num) /** libevent event log callback */ static void libevent_log_cb(int severity, const char *msg) { - if (severity >= EVENT_LOG_WARN) // Log warn messages and higher without debug category - LogPrintf("libevent: %s\n", msg); - else - LogPrint(BCLog::LIBEVENT, "libevent: %s\n", msg); + BCLog::Level level; + switch (severity) { + case EVENT_LOG_DEBUG: + level = BCLog::Level::Debug; + break; + case EVENT_LOG_MSG: + level = BCLog::Level::Info; + break; + case EVENT_LOG_WARN: + level = BCLog::Level::Warning; + break; + default: // EVENT_LOG_ERR and others are mapped to error + level = BCLog::Level::Error; + break; + } + LogPrintLevel(BCLog::LIBEVENT, level, "%s\n", msg); } bool InitHTTPServer() @@ -358,12 +369,8 @@ bool InitHTTPServer() // Redirect libevent's logging to our own log event_set_log_callback(&libevent_log_cb); - // Update libevent's log handling. Returns false if our version of - // libevent doesn't support debug logging, in which case we should - // clear the BCLog::LIBEVENT flag. - if (!UpdateHTTPServerLogging(LogInstance().WillLogCategory(BCLog::LIBEVENT))) { - LogInstance().DisableCategory(BCLog::LIBEVENT); - } + // Update libevent's log handling. + UpdateHTTPServerLogging(LogInstance().WillLogCategory(BCLog::LIBEVENT)); #ifdef WIN32 evthread_use_windows_threads(); @@ -393,7 +400,7 @@ bool InitHTTPServer() LogPrint(BCLog::HTTP, "Initialized HTTP server\n"); int workQueueDepth = std::max((long)gArgs.GetIntArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L); - LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); + LogPrintfCategory(BCLog::HTTP, "creating work queue of depth %d\n", workQueueDepth); g_work_queue = std::make_unique<WorkQueue<HTTPClosure>>(workQueueDepth); // transfer ownership to eventBase/HTTP via .release() @@ -402,18 +409,12 @@ bool InitHTTPServer() return true; } -bool UpdateHTTPServerLogging(bool enable) { -#if LIBEVENT_VERSION_NUMBER >= 0x02010100 +void UpdateHTTPServerLogging(bool enable) { if (enable) { event_enable_debug_logging(EVENT_DBG_ALL); } else { event_enable_debug_logging(EVENT_DBG_NONE); } - return true; -#else - // Can't update libevent logging if version < 02010100 - return false; -#endif } static std::thread g_thread_http; @@ -423,7 +424,7 @@ void StartHTTPServer() { LogPrint(BCLog::HTTP, "Starting HTTP server\n"); int rpcThreads = std::max((long)gArgs.GetIntArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); - LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); + LogPrintfCategory(BCLog::HTTP, "starting %d worker threads\n", rpcThreads); g_thread_http = std::thread(ThreadHTTP, eventBase); for (int i = 0; i < rpcThreads; i++) { @@ -639,6 +640,37 @@ HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() const } } +std::optional<std::string> HTTPRequest::GetQueryParameter(const std::string& key) const +{ + const char* uri{evhttp_request_get_uri(req)}; + + return GetQueryParameterFromUri(uri, key); +} + +std::optional<std::string> GetQueryParameterFromUri(const char* uri, const std::string& key) +{ + evhttp_uri* uri_parsed{evhttp_uri_parse(uri)}; + const char* query{evhttp_uri_get_query(uri_parsed)}; + std::optional<std::string> result; + + if (query) { + // Parse the query string into a key-value queue and iterate over it + struct evkeyvalq params_q; + evhttp_parse_query_str(query, ¶ms_q); + + for (struct evkeyval* param{params_q.tqh_first}; param != nullptr; param = param->next.tqe_next) { + if (param->key == key) { + result = param->value; + break; + } + } + evhttp_clear_headers(¶ms_q); + } + evhttp_uri_free(uri_parsed); + + return result; +} + void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler) { LogPrint(BCLog::HTTP, "Registering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch); |