Add function getClientHTTPHeader, part 1

This commit is contained in:
Alexey Milovidov 2024-03-23 20:52:26 +01:00
parent 229d12e0de
commit e195806c5b
7 changed files with 42 additions and 24 deletions

View File

@ -5,6 +5,7 @@
#include <IO/WriteHelpers.h>
#include <Core/ProtocolDefines.h>
#include <base/getFQDNOrHostName.h>
#include <Poco/Net/HTTPRequest.h>
#include <unistd.h>
#include <Common/config_version.h>
@ -255,7 +256,29 @@ String toString(ClientInfo::Interface interface)
return "TCP_INTERSERVER";
}
return std::format("Unknown {}!\n", static_cast<int>(interface));
return std::format("Unknown server interface ({}).", static_cast<int>(interface));
}
void ClientInfo::setFromHTTPRequest(const Poco::Net::HTTPRequest & request)
{
http_method = ClientInfo::HTTPMethod::UNKNOWN;
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET)
http_method = ClientInfo::HTTPMethod::GET;
else if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
http_method = ClientInfo::HTTPMethod::POST;
http_user_agent = request.get("User-Agent", "");
http_referer = request.get("Referer", "");
forwarded_for = request.get("X-Forwarded-For", "");
for (const auto & header : request)
{
/// These headers can contain authentication info and shouldn't be accessible by the user.
String key_lowercase = Poco::toLower(header.first);
if (key_lowercase.starts_with("x-clickhouse") || key_lowercase == "authentication")
continue;
http_headers[header.first] = header.second;
}
}
}

View File

@ -7,6 +7,12 @@
#include <Common/VersionNumber.h>
#include <boost/algorithm/string/trim.hpp>
namespace Poco::Net
{
class HTTPRequest;
}
namespace DB
{
@ -93,6 +99,7 @@ public:
HTTPMethod http_method = HTTPMethod::UNKNOWN;
String http_user_agent;
String http_referer;
std::unordered_map<String, String> http_headers;
/// For mysql and postgresql
UInt64 connection_id = 0;
@ -135,6 +142,9 @@ public:
/// Initialize parameters on client initiating query.
void setInitialQuery();
/// Initialize parameters related to HTTP request.
void setFromHTTPRequest(const Poco::Net::HTTPRequest & request);
bool clientVersionEquals(const ClientInfo & other, bool compare_patch) const;
String getVersionStr() const;

View File

@ -4640,11 +4640,9 @@ void Context::setClientConnectionId(uint32_t connection_id_)
client_info.connection_id = connection_id_;
}
void Context::setHTTPClientInfo(ClientInfo::HTTPMethod http_method, const String & http_user_agent, const String & http_referer)
void Context::setHTTPClientInfo(const Poco::Net::HTTPRequest & request)
{
client_info.http_method = http_method;
client_info.http_user_agent = http_user_agent;
client_info.http_referer = http_referer;
client_info.setFromHTTPRequest(request);
need_recalculate_access = true;
}

View File

@ -642,7 +642,7 @@ public:
void setClientInterface(ClientInfo::Interface interface);
void setClientVersion(UInt64 client_version_major, UInt64 client_version_minor, UInt64 client_version_patch, unsigned client_tcp_protocol_version);
void setClientConnectionId(uint32_t connection_id);
void setHTTPClientInfo(ClientInfo::HTTPMethod http_method, const String & http_user_agent, const String & http_referer);
void setHTTPClientInfo(const Poco::Net::HTTPRequest & request);
void setForwardedFor(const String & forwarded_for);
void setQueryKind(ClientInfo::QueryKind query_kind);
void setQueryKindInitial();

View File

@ -429,18 +429,12 @@ void Session::setClientConnectionId(uint32_t connection_id)
prepared_client_info->connection_id = connection_id;
}
void Session::setHTTPClientInfo(ClientInfo::HTTPMethod http_method, const String & http_user_agent, const String & http_referer)
void Session::setHTTPClientInfo(const Poco::Net::HTTPRequest & request)
{
if (session_context)
{
session_context->setHTTPClientInfo(http_method, http_user_agent, http_referer);
}
session_context->setHTTPClientInfo(request);
else
{
prepared_client_info->http_method = http_method;
prepared_client_info->http_user_agent = http_user_agent;
prepared_client_info->http_referer = http_referer;
}
prepared_client_info->setFromHTTPRequest(request);
}
void Session::setForwardedFor(const String & forwarded_for)

View File

@ -65,7 +65,7 @@ public:
void setClientInterface(ClientInfo::Interface interface);
void setClientVersion(UInt64 client_version_major, UInt64 client_version_minor, UInt64 client_version_patch, unsigned client_tcp_protocol_version);
void setClientConnectionId(uint32_t connection_id);
void setHTTPClientInfo(ClientInfo::HTTPMethod http_method, const String & http_user_agent, const String & http_referer);
void setHTTPClientInfo(const Poco::Net::HTTPRequest & request);
void setForwardedFor(const String & forwarded_for);
void setQuotaClientKey(const String & quota_key);
void setConnectionClientVersion(UInt64 client_version_major, UInt64 client_version_minor, UInt64 client_version_patch, unsigned client_tcp_protocol_version);

View File

@ -490,14 +490,7 @@ bool HTTPHandler::authenticateUser(
/// Set client info. It will be used for quota accounting parameters in 'setUser' method.
ClientInfo::HTTPMethod http_method = ClientInfo::HTTPMethod::UNKNOWN;
if (request.getMethod() == HTTPServerRequest::HTTP_GET)
http_method = ClientInfo::HTTPMethod::GET;
else if (request.getMethod() == HTTPServerRequest::HTTP_POST)
http_method = ClientInfo::HTTPMethod::POST;
session->setHTTPClientInfo(http_method, request.get("User-Agent", ""), request.get("Referer", ""));
session->setForwardedFor(request.get("X-Forwarded-For", ""));
session->setHTTPClientInfo(request);
session->setQuotaClientKey(quota_key);
/// Extract the last entry from comma separated list of forwarded_for addresses.