define HTTP request methods at module level outside of class

This is a refactor to prepare for matching the API of HTTPRequest
definitions in both namespaces http_bitcoin and http_libevent. In
particular, to provide a consistent return type for GetRequestMethod()
in both classes.
This commit is contained in:
Matthew Zipkin 2024-12-11 13:21:31 -05:00 committed by Matthew Zipkin
parent cd059b6e14
commit 90761d5026
No known key found for this signature in database
GPG key ID: E7E2984B6289C93A
4 changed files with 27 additions and 26 deletions

View file

@ -157,7 +157,7 @@ static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUserna
static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req) static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
{ {
// JSONRPC handles only POST // JSONRPC handles only POST
if (req->GetRequestMethod() != HTTPRequest::POST) { if (req->GetRequestMethod() != HTTPRequestMethod::POST) {
req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests"); req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests");
return false; return false;
} }

View file

@ -243,18 +243,18 @@ static bool InitHTTPAllowList()
} }
/** HTTP request method as string - use for logging only */ /** HTTP request method as string - use for logging only */
std::string RequestMethodString(HTTPRequest::RequestMethod m) std::string RequestMethodString(HTTPRequestMethod m)
{ {
switch (m) { switch (m) {
case HTTPRequest::GET: case HTTPRequestMethod::GET:
return "GET"; return "GET";
case HTTPRequest::POST: case HTTPRequestMethod::POST:
return "POST"; return "POST";
case HTTPRequest::HEAD: case HTTPRequestMethod::HEAD:
return "HEAD"; return "HEAD";
case HTTPRequest::PUT: case HTTPRequestMethod::PUT:
return "PUT"; return "PUT";
case HTTPRequest::UNKNOWN: case HTTPRequestMethod::UNKNOWN:
return "unknown"; return "unknown";
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
assert(false); assert(false);
@ -297,7 +297,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
} }
// Early reject unknown HTTP methods // Early reject unknown HTTP methods
if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) { if (hreq->GetRequestMethod() == HTTPRequestMethod::UNKNOWN) {
LogDebug(BCLog::HTTP, "HTTP request from %s rejected: Unknown HTTP request method\n", LogDebug(BCLog::HTTP, "HTTP request from %s rejected: Unknown HTTP request method\n",
hreq->GetPeer().ToStringAddrPort()); hreq->GetPeer().ToStringAddrPort());
hreq->WriteReply(HTTP_BAD_METHOD); hreq->WriteReply(HTTP_BAD_METHOD);
@ -710,19 +710,19 @@ std::string HTTPRequest::GetURI() const
return evhttp_request_get_uri(req); return evhttp_request_get_uri(req);
} }
HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() const HTTPRequestMethod HTTPRequest::GetRequestMethod() const
{ {
switch (evhttp_request_get_command(req)) { switch (evhttp_request_get_command(req)) {
case EVHTTP_REQ_GET: case EVHTTP_REQ_GET:
return GET; return HTTPRequestMethod::GET;
case EVHTTP_REQ_POST: case EVHTTP_REQ_POST:
return POST; return HTTPRequestMethod::POST;
case EVHTTP_REQ_HEAD: case EVHTTP_REQ_HEAD:
return HEAD; return HTTPRequestMethod::HEAD;
case EVHTTP_REQ_PUT: case EVHTTP_REQ_PUT:
return PUT; return HTTPRequestMethod::PUT;
default: default:
return UNKNOWN; return HTTPRequestMethod::UNKNOWN;
} }
} }

View file

@ -37,6 +37,14 @@ struct evhttp_request;
struct event_base; struct event_base;
class CService; class CService;
enum HTTPRequestMethod {
UNKNOWN,
GET,
POST,
HEAD,
PUT
};
namespace http_libevent { namespace http_libevent {
class HTTPRequest; class HTTPRequest;
@ -88,14 +96,6 @@ public:
explicit HTTPRequest(struct evhttp_request* req, const util::SignalInterrupt& interrupt, bool replySent = false); explicit HTTPRequest(struct evhttp_request* req, const util::SignalInterrupt& interrupt, bool replySent = false);
~HTTPRequest(); ~HTTPRequest();
enum RequestMethod {
UNKNOWN,
GET,
POST,
HEAD,
PUT
};
/** Get requested URI. /** Get requested URI.
*/ */
std::string GetURI() const; std::string GetURI() const;
@ -106,7 +106,7 @@ public:
/** Get request method. /** Get request method.
*/ */
RequestMethod GetRequestMethod() const; HTTPRequestMethod GetRequestMethod() const;
/** Get the query parameter value from request uri for a specified key, or std::nullopt if the /** Get the query parameter value from request uri for a specified key, or std::nullopt if the
* key is not found. * key is not found.

View file

@ -22,12 +22,13 @@
extern "C" int evhttp_parse_firstline_(struct evhttp_request*, struct evbuffer*); extern "C" int evhttp_parse_firstline_(struct evhttp_request*, struct evbuffer*);
extern "C" int evhttp_parse_headers_(struct evhttp_request*, struct evbuffer*); extern "C" int evhttp_parse_headers_(struct evhttp_request*, struct evbuffer*);
std::string RequestMethodString(HTTPRequestMethod m);
FUZZ_TARGET(http_request) FUZZ_TARGET(http_request)
{ {
using http_libevent::HTTPRequest; using http_libevent::HTTPRequest;
std::string RequestMethodString(HTTPRequest::RequestMethod m);
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
evhttp_request* evreq = evhttp_request_new(nullptr, nullptr); evhttp_request* evreq = evhttp_request_new(nullptr, nullptr);
assert(evreq != nullptr); assert(evreq != nullptr);
@ -51,7 +52,7 @@ FUZZ_TARGET(http_request)
util::SignalInterrupt interrupt; util::SignalInterrupt interrupt;
HTTPRequest http_request{evreq, interrupt, true}; HTTPRequest http_request{evreq, interrupt, true};
const HTTPRequest::RequestMethod request_method = http_request.GetRequestMethod(); const HTTPRequestMethod request_method = http_request.GetRequestMethod();
(void)RequestMethodString(request_method); (void)RequestMethodString(request_method);
(void)http_request.GetURI(); (void)http_request.GetURI();
(void)http_request.GetHeader("Host"); (void)http_request.GetHeader("Host");