userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
request_context.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/server/request/request_context.hpp
4
/// @brief @copybrief server::request::RequestContext
5
6
#
include
<
string
>
7
#
include
<
string_view
>
8
#
include
<
type_traits
>
9
10
#
include
<
userver
/
utils
/
any_movable
.
hpp
>
11
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
12
#
include
<
userver
/
utils
/
statistics
/
labels
.
hpp
>
13
14
USERVER_NAMESPACE_BEGIN
15
16
namespace
server::
request
{
17
18
namespace
impl {
19
class
InternalRequestContext;
20
}
21
22
/// @brief Stores request-specific data during request processing.
23
///
24
/// For example: you can store some data in `HandleRequestThrow()` method
25
/// and access this data in `GetResponseDataForLogging()` method.
26
class
RequestContext
final
{
27
public
:
28
RequestContext();
29
30
RequestContext(RequestContext&&)
noexcept
;
31
32
RequestContext(
const
RequestContext&) =
delete
;
33
34
~RequestContext();
35
36
/// @brief Stores user data if it was not previously stored in this.
37
/// @throw std::runtime_error if user data was already stored.
38
template
<
typename
Data>
39
Data&
SetUserData
(Data data);
40
41
/// @brief Emplaces user data if it was not previously stored in this.
42
/// @throw std::runtime_error if user data was already stored.
43
template
<
typename
Data,
typename
... Args>
44
Data&
EmplaceUserData
(Args&&... args);
45
46
/// @returns Stored user data
47
/// @throws std::runtime_error if no data was stored
48
/// @throws std::bad_any_cast if data of different type was stored
49
template
<
typename
Data>
50
Data&
GetUserData
();
51
52
/// @returns Stored user data
53
/// @throws std::runtime_error if no data was stored
54
/// @throws std::bad_any_cast if data of different type was stored
55
template
<
typename
Data>
56
const
Data&
GetUserData
()
const
;
57
58
/// @returns A pointer to data of type Data if it was stored before during
59
/// current request processing or nullptr otherwise
60
template
<
typename
Data>
61
std::remove_reference_t<Data>*
GetUserDataOptional
();
62
63
/// @returns A pointer to data of type Data if it was stored before during
64
/// current request processing or nullptr otherwise
65
template
<
typename
Data>
66
const
std::remove_reference_t<Data>*
GetUserDataOptional
()
const
;
67
68
/// @brief Erases the user data.
69
void
EraseUserData
()
noexcept
;
70
71
/// @brief Stores the data with specified name if it was not previously stored
72
/// in this.
73
/// @throw std::runtime_error if data with such name was already stored.
74
template
<
typename
Data>
75
Data&
SetData
(std::string name, Data data);
76
77
/// @brief Emplaces the data with specified name if it was not previously
78
/// stored in this.
79
/// @throw std::runtime_error if data with such name was already stored.
80
template
<
typename
Data,
typename
... Args>
81
Data&
EmplaceData
(std::string name, Args&&... args);
82
83
/// @returns Stored data with specified name.
84
/// @throws std::runtime_error if no data was stored
85
/// @throws std::bad_any_cast if data of different type was stored
86
template
<
typename
Data>
87
Data&
GetData
(std::string_view name);
88
89
/// @returns Stored data with specified name.
90
/// @throws std::runtime_error if no data was stored
91
/// @throws std::bad_any_cast if data of different type was stored
92
template
<
typename
Data>
93
const
Data&
GetData
(std::string_view name)
const
;
94
95
/// @returns Stored data with specified name or nullptr if no data found.
96
/// @throws std::bad_any_cast if data of different type was stored.
97
template
<
typename
Data>
98
std::remove_reference_t<Data>*
GetDataOptional
(std::string_view name);
99
100
/// @returns Stored data with specified name or nullptr if no data found.
101
/// @throws std::bad_any_cast if data of different type was stored.
102
template
<
typename
Data>
103
const
std::remove_reference_t<Data>*
GetDataOptional
(std::string_view name)
const
;
104
105
/// @brief Erase data with specified name.
106
void
EraseData
(std::string_view name)
noexcept
;
107
108
/// @brief Set the metrics shard (path + labels) for this request.
109
/// When set, handler metrics will be accumulated on a new subpath "http.handler.path.*"
110
/// and the provided labels would be set to each metric
111
/// @note If something (e.g. middleware) interrupts the request before this method is called
112
/// then the sharded metrics won't be written
113
void
SetHandlerMetricsShard
(std::string_view path,
utils
::
statistics
::LabelsSpan labels);
114
115
// TODO : TAXICOMMON-8252
116
impl::InternalRequestContext& GetInternalContext()
noexcept
;
117
118
private
:
119
utils
::AnyMovable& SetUserAnyData(
utils
::AnyMovable&& data);
120
utils
::AnyMovable& GetUserAnyData();
121
utils
::AnyMovable* GetUserAnyDataOptional()
noexcept
;
122
void
EraseUserAnyData()
noexcept
;
123
124
utils
::AnyMovable& SetAnyData(std::string&& name,
utils
::AnyMovable&& data);
125
utils
::AnyMovable& GetAnyData(std::string_view name);
126
utils
::AnyMovable* GetAnyDataOptional(std::string_view name)
noexcept
;
127
void
EraseAnyData(std::string_view name)
noexcept
;
128
129
class
Impl;
130
static
constexpr
std::size_t kPimplSize = 120;
131
utils
::FastPimpl<Impl, kPimplSize,
alignof
(
void
*)> impl_;
132
};
133
134
template
<
typename
Data>
135
Data& RequestContext::
SetUserData
(Data data) {
136
static_assert
(
137
!std::is_const_v<Data>,
138
"Data stored in RequestContext is mutable if RequestContext is "
139
"not `const`. Remove the `const` from the template parameter "
140
"of SetUserData as it makes no sense"
141
);
142
static_assert
(
143
!std::is_reference_v<Data>,
144
"Data in RequestContext is stored by copy. Remove the reference "
145
"from the template parameter of SetUserData as it makes no sense"
146
);
147
return
utils
::AnyCast<Data&>(SetUserAnyData(std::move(data)));
148
}
149
150
template
<
typename
Data,
typename
... Args>
151
Data& RequestContext::
EmplaceUserData
(Args&&... args) {
152
// NOLINTNEXTLINE(google-readability-casting)
153
auto
& data = SetUserAnyData(Data(std::forward<Args>(args)...));
154
return
utils
::AnyCast<Data&>(data);
155
}
156
157
template
<
typename
Data>
158
Data& RequestContext::
GetUserData
() {
159
return
utils
::AnyCast<Data&>(GetUserAnyData());
160
}
161
162
template
<
typename
Data>
163
const
Data& RequestContext::
GetUserData
()
const
{
164
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
165
return
const_cast
<RequestContext*>(
this
)->GetUserData<Data>();
166
}
167
168
template
<
typename
Data>
169
std::remove_reference_t<Data>* RequestContext::
GetUserDataOptional
() {
170
auto
* data = GetUserAnyDataOptional();
171
return
data ? &
utils
::AnyCast<Data&>(*data) :
nullptr
;
172
}
173
174
template
<
typename
Data>
175
const
std::remove_reference_t<Data>* RequestContext::
GetUserDataOptional
()
const
{
176
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
177
return
const_cast
<RequestContext*>(
this
)->GetUserDataOptional<Data>();
178
}
179
180
inline
void
RequestContext::
EraseUserData
()
noexcept
{ EraseUserAnyData(); }
181
182
template
<
typename
Data>
183
Data& RequestContext::
SetData
(std::string name, Data data) {
184
static_assert
(
185
!std::is_const_v<Data>,
186
"Data stored in RequestContext is mutable if RequestContext is "
187
"not `const`. Remove the `const` from the template parameter "
188
"of SetData as it makes no sense"
189
);
190
static_assert
(
191
!std::is_reference_v<Data>,
192
"Data in RequestContext is stored by copy. Remove the reference "
193
"from the template parameter of SetData as it makes no sense"
194
);
195
return
utils
::AnyCast<Data&>(SetAnyData(std::move(name), std::move(data)));
196
}
197
198
template
<
typename
Data,
typename
... Args>
199
Data& RequestContext::
EmplaceData
(std::string name, Args&&... args) {
200
// NOLINTNEXTLINE(google-readability-casting)
201
auto
& data = SetAnyData(std::move(name), Data(std::forward<Args>(args)...));
202
return
utils
::AnyCast<Data&>(data);
203
}
204
205
template
<
typename
Data>
206
Data& RequestContext::
GetData
(std::string_view name) {
207
return
utils
::AnyCast<Data&>(GetAnyData(name));
208
}
209
210
template
<
typename
Data>
211
const
Data& RequestContext::
GetData
(std::string_view name)
const
{
212
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
213
return
const_cast
<RequestContext*>(
this
)->GetData<Data>(name);
214
}
215
216
template
<
typename
Data>
217
std::remove_reference_t<Data>* RequestContext::
GetDataOptional
(std::string_view name) {
218
auto
* data = GetAnyDataOptional(name);
219
return
data ? &
utils
::AnyCast<Data&>(*data) :
nullptr
;
220
}
221
222
template
<
typename
Data>
223
const
std::remove_reference_t<Data>* RequestContext::
GetDataOptional
(std::string_view name)
const
{
224
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
225
return
const_cast
<RequestContext*>(
this
)->GetDataOptional<Data>(name);
226
}
227
228
inline
void
RequestContext::
EraseData
(std::string_view name)
noexcept
{ EraseAnyData(name); }
229
230
}
// namespace server::request
231
232
USERVER_NAMESPACE_END
userver
server
request
request_context.hpp
Generated on
for userver by
Doxygen
1.17.0