mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
Clang warns about http_server having a non-virtual destructor; we aren't actually doing anything that would cause problems, but the warning is legit and a correct thing to fix.
94 lines
3.7 KiB
C++
94 lines
3.7 KiB
C++
#pragma once
|
|
|
|
#include <uWebSockets/App.h>
|
|
#include <future>
|
|
#include <unordered_set>
|
|
#include "epee/storages/portable_storage.h"
|
|
#include "common/password.h"
|
|
#include "version.h"
|
|
|
|
namespace cryptonote::rpc {
|
|
using namespace std::literals;
|
|
|
|
using HttpRequest = uWS::HttpRequest;
|
|
using HttpResponse = uWS::HttpResponse<false/*SSL*/>;
|
|
|
|
using http_response_code = std::pair<int, std::string_view>;
|
|
|
|
// Base class for common RPC server functionality used by both core rpc http server and
|
|
// wallet_rpc_server.
|
|
class http_server_base {
|
|
public:
|
|
|
|
std::string get_remote_address(HttpResponse& res);
|
|
|
|
/// Checks for required authentication, if enabled. If authentication fails, sets a "failed"
|
|
/// response and returns false; if authentication isn't required or passes, returns true (and
|
|
/// doesn't touch the response).
|
|
bool check_auth(HttpRequest& req, HttpResponse& res);
|
|
|
|
// Sends an error response and finalizes the response. If body is empty, uses the default error
|
|
// response text.
|
|
void error_response(
|
|
HttpResponse& res,
|
|
http_response_code code,
|
|
std::optional<std::string_view> body = std::nullopt) const;
|
|
|
|
// Similar to the above, but for JSON RPC requests: we send "200 OK" at the HTTP layer; the
|
|
// error code and message gets encoded in JSON inside the response body.
|
|
void jsonrpc_error_response(
|
|
HttpResponse& res,
|
|
int code,
|
|
std::string message,
|
|
std::optional<epee::serialization::storage_entry> = std::nullopt) const;
|
|
|
|
// Posts a callback to the uWebSockets thread loop controlling this connection; all writes must
|
|
// be done from that thread, and so this method is provided to defer a callback from another
|
|
// thread into that one. The function should have signature `void ()`.
|
|
template <typename Func>
|
|
void loop_defer(Func&& f) {
|
|
m_loop->defer(std::forward<Func>(f));
|
|
}
|
|
|
|
const std::string& server_header() { return m_server_header; }
|
|
|
|
bool closing() const { return m_closing; }
|
|
|
|
static constexpr http_response_code
|
|
HTTP_OK{200, "OK"sv},
|
|
HTTP_BAD_REQUEST{400, "Bad Request"sv},
|
|
HTTP_FORBIDDEN{403, "Forbidden"sv},
|
|
HTTP_NOT_FOUND{404, "Not Found"sv},
|
|
HTTP_ERROR{500, "Internal Server Error"sv},
|
|
HTTP_SERVICE_UNAVAILABLE{503, "Service Unavailable"sv};
|
|
|
|
protected:
|
|
|
|
virtual ~http_server_base() = default;
|
|
|
|
virtual void create_rpc_endpoints(uWS::App& http) = 0;
|
|
|
|
/// handles cors headers by adding any needed headers to the given vector
|
|
void handle_cors(HttpRequest& req, std::vector<std::pair<std::string, std::string>>& extra_headers);
|
|
|
|
// The uWebSockets event loop pointer (so that we can inject a callback to shut it down)
|
|
uWS::Loop* m_loop{nullptr};
|
|
// The socket(s) we are listening on
|
|
std::vector<us_listen_socket_t*> m_listen_socks;
|
|
// The thread in which the uWebSockets event listener is running
|
|
std::thread m_rpc_thread;
|
|
// An optional required login for this HTTP RPC interface
|
|
std::optional<tools::login> m_login;
|
|
// Cached string we send for the Server header
|
|
std::string m_server_header = "Loki RPC HTTP/" + std::string{OXEN_VERSION_STR};
|
|
// Access-Control-Allow-Origin header values; if one of these match the incoming Origin header
|
|
// we return it in the ACAO header; otherwise (or if this is empty) we omit the header entirely.
|
|
std::unordered_set<std::string> m_cors;
|
|
// Will be set to true when we're trying to shut down which closes any connections as we reply
|
|
// to them. Should only be read/write from inside the uWS loop.
|
|
bool m_closing = false;
|
|
// If true then always reply with 'Access-Control-Allow-Origin: *' to allow anything.
|
|
bool m_cors_any = false;
|
|
};
|
|
}
|