RESTinio
Loading...
Searching...
No Matches
chunked_input_info.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
5/*!
6 * @file
7 * @brief Information about chunked encoded body.
8 * @since v.0.6.9
9 */
10
11#pragma once
12
13#include <restinio/exception.hpp>
14#include <restinio/http_headers.hpp>
15
16#include <restinio/impl/include_fmtlib.hpp>
17
18#include <vector>
19#include <memory>
20
21namespace restinio
22{
23
24//
25// chunk_ext_param_t
26//
27
28/**
29 * @brief Chunk extension parameter.
30 *
31 * @since v.0.7.0
32 */
34{
35 std::string m_name;
36 std::string m_value;
37};
38
41
42//
43// chunk_info_t
44//
45/*!
46 * @brief Information about one chunk in an incoming request with
47 * chunked encoding.
48 *
49 * In RESTinio v.0.6.9 all chunks are concatenated into the one body.
50 * The information about individual chunks preserved in the form
51 * of vector of chunk_info_t objects. Every object contains
52 * the offset from the begining of the concatenated body and the size
53 * of the chunk. This information allows to extract the corresponding
54 * fragment from the whole body.
55 *
56 * @since v.0.6.9
57 */
59{
60 std::size_t m_started_at;
61 std::size_t m_size;
62
63 /**
64 * @brief Storage of chunk extension parameters
65 *
66 * The instance will be allocated only if chunk has extension's parameters.
67 *
68 * @since v.0.7.0
69 */
71public:
72 //! Initializing constructor.
74 std::size_t started_at,
75 std::size_t size,
76 chunk_ext_params_unique_ptr_t ext_params )
77 : m_started_at{ started_at }
78 , m_size{ size }
80 {}
81
82 //! Get the starting offset of chunk.
83 [[nodiscard]]
84 std::size_t
85 started_at() const noexcept { return m_started_at; }
86
87 //! Get the size of chunk.
88 [[nodiscard]]
89 std::size_t
90 size() const noexcept { return m_size; }
91
92 //! Extract the chunk value from the whole body.
93 /*!
94 * @attention
95 * This method doesn't check the possibility of the extraction.
96 * An attempt of extraction of chunk from a body that is too small
97 * is undefined behavior.
98 */
99 [[nodiscard]]
101 make_string_view_nonchecked( string_view_t full_body ) const noexcept
102 {
103 return full_body.substr( m_started_at, m_size );
104 }
105
106 //! Extract the chunk value from the whole body.
107 /*!
108 * A check of possibility of extraction is performed.
109 *
110 * @throw exception_t if @a full_body is too small to hold the chunk.
111 */
112 [[nodiscard]]
114 make_string_view( string_view_t full_body ) const
115 {
116 if( m_started_at >= full_body.size() ||
117 m_started_at + m_size > full_body.size() )
118 {
119 throw exception_t{
120 fmt::format(
122 "unable to make a chunk (started_at:{}, size: {}) "
123 "from a body with length:{}" ),
125 m_size,
126 full_body.size() )
127 };
128 }
129
130 return make_string_view_nonchecked( full_body );
131 }
132
133 /**
134 * @brief Get a list of chunk extension's params.
135 *
136 * In case this chunk has extensions this function returns a valid pointer
137 * to a vector of ext parameters (name-value pairs).
138 *
139 * @code
140 * auto handle_request( restinio::request_t req ) {
141 * const auto * chunked_input = req.chunked_input_info();
142 * if( !chunked_input )
143 * {
144 * return restinio::request_rejected();
145 * }
146 * auto resp = req->create_response()
147 * .append_header_date_field()
148 * .append_header( "Content-Type", "text/plain; charset=utf-8" );
149 *
150 * int i = 0;
151 * for( const auto & ch : chunked_input->chunks() )
152 * {
153 * if( const auto * params = ch.ext_params(); params )
154 * {
155 * resp.append_body(
156 * fmt::format(
157 * FMT_STRING( "Chunk #{} has {} ext param(s)\r\n" ),
158 * i++,
159 * params->size() ) );
160 * }
161 * else
162 * {
163 * resp.append_body(
164 * fmt::format(
165 * FMT_STRING( "Chunk #{} has no ext params\r\n" ),
166 * i++ ) );
167 * }
168 * }
169 * return resp.done();
170 * }
171 * @endcode
172 *
173 * @since v.0.7.0
174 */
176 ext_params() const noexcept
177 {
178 return m_ext_params.get();
179 }
180};
181
182namespace impl
183{
184
185//
186// chunked_input_info_block_t
187//
188/*!
189 * @brief Bunch of data related to chunked input.
190 *
191 * @since v.0.6.9
192 */
194{
195 //! All non-empty chunks from the input.
197
198 //! Trailing fields found in the input.
199 /*!
200 * @note
201 * Can be empty.
202 */
204};
205
206} /* namespace impl */
207
208//
209// chunked_input_info_t
210//
211/*!
212 * @brief An information about chunks and trailing fields in the
213 * incoming request.
214 *
215 * This information is collected if chunked encoding is used in the
216 * incoming request.
217 *
218 * @since v.0.6.9
219 */
221{
222 //! Actual data.
224
225public:
226 //! Default constructor. Makes empty object.
228 //! Initializing constructor.
229 /*!
230 * @note
231 * This constrictor is intended to be used inside RESTinio and
232 * can be changed in future versions without any notice.
233 */
238
239 //! Get the count of chunks.
240 /*!
241 * @retval 0 if there is no chunks in the incoming request.
242 */
243 [[nodiscard]]
244 std::size_t
245 chunk_count() const noexcept { return m_info.m_chunks.size(); }
246
247 //! Get reference to the description of a chunk by index.
248 /*!
249 * @attention
250 * This method doesn't check the validity of @a index.
251 * An attempt to access non-existent chunk is undefined behavior.
252 */
253 [[nodiscard]]
254 const chunk_info_t &
255 chunk_at_nochecked( std::size_t index ) const noexcept
256 {
257 return m_info.m_chunks[ index ];
258 }
259
260 //! Get reference to the description of a chunk by index.
261 /*!
262 * @throw std::exception if @a index is invalid.
263 */
264 [[nodiscard]]
265 const chunk_info_t &
266 chunk_at( std::size_t index ) const
267 {
268 return m_info.m_chunks.at( index );
269 }
270
271 //! Get access to the container with description of chunks.
272 /*!
273 * @note
274 * The actual type of the container is not specified and can
275 * be changed from version to version. But this container
276 * can be sequentially enumerated from begin() to the end().
277 */
278 [[nodiscard]]
279 const auto &
280 chunks() const noexcept
281 {
282 return m_info.m_chunks;
283 }
284
285 //! Get access to the container with trailing fields.
286 /*!
287 * @note
288 * This can be an empty container if there is no trailing fields
289 * in the incoming request.
290 */
291 [[nodiscard]]
293 trailing_fields() const noexcept
294 {
295 return m_info.m_trailing_fields;
296 }
297};
298
299//
300// chunked_input_info_unique_ptr_t
301//
302/*!
303 * @brief Alias of unique_ptr for chunked_input_info.
304 *
305 * @since v.0.6.9
306 */
309
310} /* namespace restinio */
Information about one chunk in an incoming request with chunked encoding.
chunk_info_t(std::size_t started_at, std::size_t size, chunk_ext_params_unique_ptr_t ext_params)
Initializing constructor.
nullable_pointer_t< const chunk_ext_params_t > ext_params() const noexcept
Get a list of chunk extension's params.
std::size_t started_at() const noexcept
Get the starting offset of chunk.
std::size_t size() const noexcept
Get the size of chunk.
string_view_t make_string_view_nonchecked(string_view_t full_body) const noexcept
Extract the chunk value from the whole body.
chunk_ext_params_unique_ptr_t m_ext_params
Storage of chunk extension parameters.
string_view_t make_string_view(string_view_t full_body) const
Extract the chunk value from the whole body.
An information about chunks and trailing fields in the incoming request.
const chunk_info_t & chunk_at_nochecked(std::size_t index) const noexcept
Get reference to the description of a chunk by index.
const auto & chunks() const noexcept
Get access to the container with description of chunks.
impl::chunked_input_info_block_t m_info
Actual data.
std::size_t chunk_count() const noexcept
Get the count of chunks.
const http_header_fields_t & trailing_fields() const noexcept
Get access to the container with trailing fields.
chunked_input_info_t(impl::chunked_input_info_block_t info)
Initializing constructor.
chunked_input_info_t()=default
Default constructor. Makes empty object.
const chunk_info_t & chunk_at(std::size_t index) const
Get reference to the description of a chunk by index.
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
#define RESTINIO_FMT_FORMAT_STRING(s)
Chunk extension parameter.
Bunch of data related to chunked input.
std::vector< chunk_info_t > m_chunks
All non-empty chunks from the input.
http_header_fields_t m_trailing_fields
Trailing fields found in the input.