userver: userver/baggage/baggage.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
baggage.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/baggage/baggage.hpp
4/// @brief @copybrief baggage::Baggage
5
6#include <algorithm> // TODO: remove
7#include <optional>
8#include <stdexcept>
9#include <string>
10#include <string_view>
11#include <unordered_set>
12#include <vector>
13
14#include <userver/engine/task/inherited_variable.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace baggage {
19
20using BaggageProperties =
21 std::vector<std::pair<std::string, std::optional<std::string>>>;
22
23class Baggage;
25
26/// @brief Baggage base exception
27class BaggageException : public std::runtime_error {
28 public:
29 explicit BaggageException(const std::string& message)
30 : std::runtime_error(message) {}
31};
32
33/// @brief property of entry. Has required key and optional value.
34/// Keys shouldn't contain '=', ';' and ','. Values shouldn't contains
35/// ',' and ';'
37 friend class BaggageEntry;
38
39 public:
40 BaggageEntryProperty(std::string_view key,
41 std::optional<std::string_view> value = std::nullopt);
42 std::string ToString() const;
43 std::optional<std::string> GetValue() const;
44 std::string GetKey() const;
45
46 private:
47 const std::string_view key_;
48 std::optional<std::string_view> value_;
49};
50
51/// @brief Baggage Entry. Has required key and value,
52/// optional list of properties.
53/// Keys shouldn't contain '=' and ','. Values shouldn't contains
54/// ',' and ';'
56 friend class Baggage;
57
58 public:
59 BaggageEntry(std::string_view key, std::string_view value,
60 std::vector<BaggageEntryProperty> properties);
61 std::string ToString() const;
62 std::string GetValue() const;
63 std::string GetKey() const;
64
65 /// @return vector of properties of chosen entry
67
68 /// @brief Check that entry contains property with selected key
69 bool HasProperty(const std::string& key) const;
70
71 /// @brief Get first property with selected key
72 /// @throws BaggageException If key doesn't exist
73 const BaggageEntryProperty& GetProperty(const std::string& key) const;
74
75 private:
76 /// @brief Add entry to the received header string
77 void ConcatenateWith(std::string& header) const;
78 const std::string_view key_;
79 std::string_view value_;
80 std::vector<BaggageEntryProperty> properties_;
81};
82
83/// @brief Baggage header. Contains entries (key, value, optional<properties>).
84///
85/// For more details on header check the official site
86/// https://w3c.github.io/baggage/
87///
88/// @see baggage::BaggageManagerComponent
89class Baggage {
90 public:
91 Baggage(std::string header, std::unordered_set<std::string> allowed_keys);
92 Baggage(const Baggage&) noexcept;
93 Baggage(Baggage&&) noexcept;
94
95 std::string ToString() const;
96
97 /// @return vector of entries
99
100 /// @brief check that header contains entry with selected key
101 bool HasEntry(const std::string& key) const;
102
103 /// @brief find first entry with selected key
104 /// @throws BaggageException If key doesn't exist
105 const BaggageEntry& GetEntry(const std::string& key) const;
106
107 /// @brief entry's key validation
108 bool IsValidEntry(const std::string& key) const;
109
110 /// @brief Add entry to baggage header.
111 /// @throws BaggageException If key, value or properties
112 /// don't match with requirements or if allowed_keys
113 /// don't contain selected key
114 void AddEntry(std::string key, std::string value,
115 BaggageProperties properties);
116
117 /// @brief get baggage allowed keys
119
120 protected:
121 /// @brief parsers
122 /// @returns std::nullopt If key, value or properties
123 /// don't match with requirements or if allowed_keys
124 /// don't contain selected key
125 std::optional<BaggageEntry> TryMakeBaggageEntry(std::string_view entry);
126 static std::optional<BaggageEntryProperty> TryMakeBaggageEntryProperty(
127 std::string_view property);
128
129 private:
130 /// @brief Parse baggage_header and fill entries_
131 void FillEntries();
132
133 /// @brief Create result_header
134 void CreateResultHeader();
135
136 std::string header_value_;
137 std::unordered_set<std::string> allowed_keys_;
138 std::vector<BaggageEntry> entries_;
139
140 // result header after parsing entities.
141 // empty string if is_valid_header == true
142 std::string result_header_;
143
144 // true if requested header == header for sending
145 bool is_valid_header_ = true;
146};
147
148/// @brief Parsing function
149std::optional<Baggage> TryMakeBaggage(
150 std::string header, std::unordered_set<std::string> allowed_keys);
151
152template <typename T>
153bool HasInvalidSymbols(const T& obj) {
154 return std::find_if(obj.begin(), obj.end(), [](unsigned char x) {
155 return x == ',' || x == ';' || x == '=' || std::isspace(x);
156 }) != obj.end();
157}
158
159inline engine::TaskInheritedVariable<Baggage> kInheritedBaggage;
160
161} // namespace baggage
162
163USERVER_NAMESPACE_END