mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
Add GetQueryParameter helper function
Easily get the query parameter from the URI, with optional default value.
This commit is contained in:
parent
fff771ee86
commit
a09497614e
4 changed files with 101 additions and 3 deletions
|
@ -95,6 +95,7 @@ BITCOIN_TESTS =\
|
|||
test/fs_tests.cpp \
|
||||
test/getarg_tests.cpp \
|
||||
test/hash_tests.cpp \
|
||||
test/httpserver_tests.cpp \
|
||||
test/i2p_tests.cpp \
|
||||
test/interfaces_tests.cpp \
|
||||
test/key_io_tests.cpp \
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
@ -639,6 +641,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);
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
#ifndef BITCOIN_HTTPSERVER_H
|
||||
#define BITCOIN_HTTPSERVER_H
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
static const int DEFAULT_HTTP_THREADS=4;
|
||||
static const int DEFAULT_HTTP_WORKQUEUE=16;
|
||||
|
@ -83,6 +84,17 @@ public:
|
|||
*/
|
||||
RequestMethod GetRequestMethod() const;
|
||||
|
||||
/** Get the query parameter value from request uri for a specified key, or std::nullopt if the
|
||||
* key is not found.
|
||||
*
|
||||
* If the query string contains duplicate keys, the first value is returned. Many web frameworks
|
||||
* would instead parse this as an array of values, but this is not (yet) implemented as it is
|
||||
* currently not needed in any of the endpoints.
|
||||
*
|
||||
* @param[in] key represents the query parameter of which the value is returned
|
||||
*/
|
||||
std::optional<std::string> GetQueryParameter(const std::string& key) const;
|
||||
|
||||
/**
|
||||
* Get the request header specified by hdr, or an empty string.
|
||||
* Return a pair (isPresent,string).
|
||||
|
@ -115,6 +127,20 @@ public:
|
|||
void WriteReply(int nStatus, const std::string& strReply = "");
|
||||
};
|
||||
|
||||
/** Get the query parameter value from request uri for a specified key, or std::nullopt if the key
|
||||
* is not found.
|
||||
*
|
||||
* If the query string contains duplicate keys, the first value is returned. Many web frameworks
|
||||
* would instead parse this as an array of values, but this is not (yet) implemented as it is
|
||||
* currently not needed in any of the endpoints.
|
||||
*
|
||||
* Helper function for HTTPRequest::GetQueryParameter.
|
||||
*
|
||||
* @param[in] uri is the entire request uri
|
||||
* @param[in] key represents the query parameter of which the value is returned
|
||||
*/
|
||||
std::optional<std::string> GetQueryParameterFromUri(const char* uri, const std::string& key);
|
||||
|
||||
/** Event handler closure.
|
||||
*/
|
||||
class HTTPClosure
|
||||
|
|
38
src/test/httpserver_tests.cpp
Normal file
38
src/test/httpserver_tests.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2012-2022 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <httpserver.h>
|
||||
#include <test/util/setup_common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(httpserver_tests, BasicTestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_query_parameters)
|
||||
{
|
||||
std::string uri {};
|
||||
|
||||
// No parameters
|
||||
uri = "localhost:8080/rest/headers/someresource.json";
|
||||
BOOST_CHECK(!GetQueryParameterFromUri(uri.c_str(), "p1").has_value());
|
||||
|
||||
// Single parameter
|
||||
uri = "localhost:8080/rest/endpoint/someresource.json?p1=v1";
|
||||
BOOST_CHECK_EQUAL(GetQueryParameterFromUri(uri.c_str(), "p1").value(), "v1");
|
||||
BOOST_CHECK(!GetQueryParameterFromUri(uri.c_str(), "p2").has_value());
|
||||
|
||||
// Multiple parameters
|
||||
uri = "/rest/endpoint/someresource.json?p1=v1&p2=v2";
|
||||
BOOST_CHECK_EQUAL(GetQueryParameterFromUri(uri.c_str(), "p1").value(), "v1");
|
||||
BOOST_CHECK_EQUAL(GetQueryParameterFromUri(uri.c_str(), "p2").value(), "v2");
|
||||
|
||||
// If the query string contains duplicate keys, the first value is returned
|
||||
uri = "/rest/endpoint/someresource.json?p1=v1&p1=v2";
|
||||
BOOST_CHECK_EQUAL(GetQueryParameterFromUri(uri.c_str(), "p1").value(), "v1");
|
||||
|
||||
// Invalid query string syntax is the same as not having parameters
|
||||
uri = "/rest/endpoint/someresource.json&p1=v1&p2=v2";
|
||||
BOOST_CHECK(!GetQueryParameterFromUri(uri.c_str(), "p1").has_value());
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Add table
Reference in a new issue