CCF
Loading...
Searching...
No Matches
http_query.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "ccf/ds/nonstd.h"
6
7#define FMT_HEADER_ONLY
8#include <charconv>
9#include <fmt/format.h>
10#include <map>
11#include <optional>
12#include <string_view>
13
14namespace ccf::http
15{
16 // Query is parsed into a multimap, so that duplicate keys are retained.
17 // Handling of duplicates (or ignoring them entirely) is left to the caller.
18 // Keys and values are both string_views, pointing at subranges of original
19 // query string.
20 using ParsedQuery = std::multimap<std::string_view, std::string_view>;
21
22 static ParsedQuery parse_query(const std::string_view& query)
23 {
24 ParsedQuery parsed;
25 const auto params = ccf::nonstd::split(query, "&");
26 for (const auto& param : params)
27 {
28 // NB: This means both `foo=` and `foo` will be accepted and result in a
29 // `{"foo": ""}` in the map
30 const auto& [key, value] = ccf::nonstd::split_1(param, "=");
31 parsed.emplace(key, value);
32 }
33
34 return parsed;
35 }
36
37 template <typename T>
38 static bool get_query_value(
39 const ParsedQuery& pq,
40 const std::string_view& param_key,
41 T& val,
42 std::string& error_reason)
43 {
44 const auto it = pq.find(param_key);
45
46 if (it == pq.end())
47 {
48 error_reason = fmt::format("Missing query parameter '{}'", param_key);
49 return false;
50 }
51
52 const std::string_view& param_val = it->second;
53
54 if constexpr (std::is_same_v<T, std::string>)
55 {
56 val = T(param_val);
57 return true;
58 }
59 else if constexpr (std::is_integral_v<T>)
60 {
61 const auto [p, ec] =
62 std::from_chars(param_val.begin(), param_val.end(), val);
63 if (ec != std::errc() || p != param_val.end())
64 {
65 error_reason = fmt::format(
66 "Unable to parse value '{}' in parameter '{}'", param_val, param_key);
67 return false;
68 }
69
70 return true;
71 }
72 else
73 {
74 static_assert(ccf::nonstd::dependent_false<T>::value, "Unsupported type");
75 return false;
76 }
77 }
78
79 template <typename T>
80 static std::optional<T> get_query_value_opt(
81 const ParsedQuery& pq,
82 const std::string_view& param_key,
83 std::string& error_reason)
84 {
85 T val;
86 if (get_query_value(pq, param_key, val, error_reason))
87 {
88 return val;
89 }
90 else
91 {
92 return std::nullopt;
93 }
94 }
95}
Definition http_configuration.h:11
std::multimap< std::string_view, std::string_view > ParsedQuery
Definition http_query.h:20
Definition nonstd.h:62