From a94013060674f6ea4c2781cfe57779328b1d9bef Mon Sep 17 00:00:00 2001 From: Julian Mundhahs Date: Tue, 18 Feb 2025 18:32:07 +0100 Subject: [PATCH] replace missed concepts --- src/engine/ParsedRequestBuilder.cpp | 49 ++++++++++++++++++++++++++ src/engine/ParsedRequestBuilder.h | 53 ++++------------------------- src/engine/SPARQLProtocol.h | 3 +- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/engine/ParsedRequestBuilder.cpp b/src/engine/ParsedRequestBuilder.cpp index ef3c8125a9..5adeb12220 100644 --- a/src/engine/ParsedRequestBuilder.cpp +++ b/src/engine/ParsedRequestBuilder.cpp @@ -7,6 +7,22 @@ using namespace ad_utility::use_type_identity; using namespace ad_utility::url_parser::sparqlOperation; +// ____________________________________________________________________________ +ParsedRequestBuilder::ParsedRequestBuilder(const RequestType& request) { + using namespace ad_utility::url_parser::sparqlOperation; + // For an HTTP request, `request.target()` yields the HTTP Request-URI. + // This is a concatenation of the URL path and the query strings. + auto parsedUrl = ad_utility::url_parser::parseRequestTarget(request.target()); + parsedRequest_ = {std::move(parsedUrl.path_), std::nullopt, + std::move(parsedUrl.parameters_), None{}}; +} + +// ____________________________________________________________________________ +void ParsedRequestBuilder::extractAccessToken(const RequestType& request) { + parsedRequest_.accessToken_ = + determineAccessToken(request, parsedRequest_.parameters_); +} + // ____________________________________________________________________________ void ParsedRequestBuilder::extractDatasetClauses() { extractDatasetClauseIfOperationIs(ti, "default-graph-uri", false); @@ -114,3 +130,36 @@ GraphOrDefault ParsedRequestBuilder::extractTargetGraph( return DEFAULT{}; } } + +// ____________________________________________________________________________ +std::optional ParsedRequestBuilder::determineAccessToken( + const RequestType& request, + const ad_utility::url_parser::ParamValueMap& params) { + namespace http = boost::beast::http; + std::optional tokenFromAuthorizationHeader; + std::optional tokenFromParameter; + if (request.find(http::field::authorization) != request.end()) { + string_view authorization = request[http::field::authorization]; + const std::string prefix = "Bearer "; + if (!authorization.starts_with(prefix)) { + throw std::runtime_error(absl::StrCat( + "Authorization header doesn't start with \"", prefix, "\".")); + } + authorization.remove_prefix(prefix.length()); + tokenFromAuthorizationHeader = std::string(authorization); + } + if (params.contains("access-token")) { + tokenFromParameter = ad_utility::url_parser::getParameterCheckAtMostOnce( + params, "access-token"); + } + // If both are specified, they must be equal. This way there is no hidden + // precedence. + if (tokenFromAuthorizationHeader && tokenFromParameter && + tokenFromAuthorizationHeader != tokenFromParameter) { + throw std::runtime_error( + "Access token is specified both in the `Authorization` header and by " + "the `access-token` parameter, but they are not the same"); + } + return tokenFromAuthorizationHeader ? std::move(tokenFromAuthorizationHeader) + : std::move(tokenFromParameter); +} diff --git a/src/engine/ParsedRequestBuilder.h b/src/engine/ParsedRequestBuilder.h index b52e12bce0..4c179ed5f3 100644 --- a/src/engine/ParsedRequestBuilder.h +++ b/src/engine/ParsedRequestBuilder.h @@ -17,29 +17,19 @@ struct ParsedRequestBuilder { FRIEND_TEST(ParsedRequestBuilderTest, determineAccessToken); FRIEND_TEST(ParsedRequestBuilderTest, parameterIsContainedExactlyOnce); + using RequestType = + boost::beast::http::request; + ad_utility::url_parser::ParsedRequest parsedRequest_; // Initialize a `ParsedRequestBuilder`, parsing the request target into the // `ParsedRequest`. - explicit ParsedRequestBuilder( - const ad_utility::httpUtils::HttpRequest auto& request) { - using namespace ad_utility::url_parser::sparqlOperation; - // For an HTTP request, `request.target()` yields the HTTP Request-URI. - // This is a concatenation of the URL path and the query strings. - auto parsedUrl = - ad_utility::url_parser::parseRequestTarget(request.target()); - parsedRequest_ = {std::move(parsedUrl.path_), std::nullopt, - std::move(parsedUrl.parameters_), None{}}; - } + explicit ParsedRequestBuilder(const RequestType& request); // Extract the access token from the access-token parameter or the // Authorization header and set it for `ParsedRequest`. If both are given, // then they must be the same. - void extractAccessToken( - const ad_utility::httpUtils::HttpRequest auto& request) { - parsedRequest_.accessToken_ = - determineAccessToken(request, parsedRequest_.parameters_); - } + void extractAccessToken(const RequestType& request); // If applicable extract the dataset clauses from the parameters and set them // on the Query or Update. @@ -92,35 +82,6 @@ struct ParsedRequestBuilder { // Determine the access token from the parameters and the requests // Authorization header. static std::optional determineAccessToken( - const ad_utility::httpUtils::HttpRequest auto& request, - const ad_utility::url_parser::ParamValueMap& params) { - namespace http = boost::beast::http; - std::optional tokenFromAuthorizationHeader; - std::optional tokenFromParameter; - if (request.find(http::field::authorization) != request.end()) { - string_view authorization = request[http::field::authorization]; - const std::string prefix = "Bearer "; - if (!authorization.starts_with(prefix)) { - throw std::runtime_error(absl::StrCat( - "Authorization header doesn't start with \"", prefix, "\".")); - } - authorization.remove_prefix(prefix.length()); - tokenFromAuthorizationHeader = std::string(authorization); - } - if (params.contains("access-token")) { - tokenFromParameter = ad_utility::url_parser::getParameterCheckAtMostOnce( - params, "access-token"); - } - // If both are specified, they must be equal. This way there is no hidden - // precedence. - if (tokenFromAuthorizationHeader && tokenFromParameter && - tokenFromAuthorizationHeader != tokenFromParameter) { - throw std::runtime_error( - "Access token is specified both in the `Authorization` header and by " - "the `access-token` parameter, but they are not the same"); - } - return tokenFromAuthorizationHeader - ? std::move(tokenFromAuthorizationHeader) - : std::move(tokenFromParameter); - } + const RequestType& request, + const ad_utility::url_parser::ParamValueMap& params); }; diff --git a/src/engine/SPARQLProtocol.h b/src/engine/SPARQLProtocol.h index 570a10b647..8c03fe5ddb 100644 --- a/src/engine/SPARQLProtocol.h +++ b/src/engine/SPARQLProtocol.h @@ -25,8 +25,7 @@ class SPARQLProtocol { static constexpr std::string_view contentTypeSparqlUpdate = "application/sparql-update"; - using RequestType = - boost::beast::http::request; + using RequestType = ParsedRequestBuilder::RequestType; // Parse an HTTP GET request into a `ParsedRequest`. The // `ParsedRequestBuilder` must have already extracted the access token.