9 #include "crow/http_request.h"
11 #include "crow/multipart.h"
12 #include "crow/ci_map.h"
24 std::unordered_map<std::string_view, std::string_view>
params;
35 operator double()
const
38 return std::stod(
static_cast<std::string
>(
value));
43 using mph_view_map = std::unordered_multimap<std::string_view, header_view, ci_hash, ci_key_eq>;
48 const auto header = headers.find(key);
49 if (
header != headers.cend())
84 std::from_chars(
body.data(),
body.data() +
body.size(), result);
89 operator double()
const
92 return std::stod(
static_cast<std::string
>(
body));
95 const header_view& get_header_object(
const std::string_view key)
const
100 friend std::ostream& operator<<(std::ostream& stream,
const part_view& part)
102 for (
const auto& [header_key, header_value] : part.headers)
104 stream << header_key <<
": " << header_value.value;
105 for (
const auto& [param_key, param_value] : header_value.params)
107 stream <<
"; " << param_key <<
'=' << padded{param_value};
112 stream << part.body << crlf;
118 using mp_view_map = std::unordered_multimap<std::string_view, part_view, ci_hash, ci_key_eq>;
128 const std::string& get_header_value(
const std::string& key)
const
133 part_view get_part_by_name(
const std::string_view name)
135 mp_view_map::iterator result =
part_map.find(name);
137 return result->second;
142 friend std::ostream& operator<<(std::ostream& stream,
const message_view message)
144 std::string delimiter = dd + message.boundary;
146 for (
const part_view& part : message.parts)
148 stream << delimiter << crlf;
151 stream << delimiter << dd << crlf;
159 std::ostringstream str;
161 return std::move(str).str();
165 std::string
dump(
int part_)
const
167 std::ostringstream str;
168 str <<
parts.at(part_);
169 return std::move(str).str();
173 message_view(
const ci_map& headers_,
const std::string& boundary_,
const std::vector<part_view>& sections):
187 boundary(get_boundary(get_header_value(
"Content-Type")))
189 parse_body(req.body);
193 std::string_view get_boundary(
const std::string_view
header)
const
195 constexpr std::string_view boundary_text =
"boundary=";
196 const size_t found =
header.find(boundary_text);
197 if (found == std::string_view::npos)
199 return std::string_view();
202 const std::string_view to_return = header.substr(found + boundary_text.size());
203 if (to_return[0] ==
'\"')
205 return to_return.substr(1, to_return.length() - 2);
210 void parse_body(std::string_view body)
212 const std::string delimiter = dd +
boundary;
215 while (body != (crlf))
217 const size_t found = body.find(delimiter);
218 if (found == std::string_view::npos)
224 const std::string_view section = body.substr(0, found);
228 body = body.substr(found + delimiter.length() + 2);
229 if (!section.empty())
231 part_view parsed_section = parse_section(section);
235 parts.push_back(std::move(parsed_section));
240 part_view parse_section(std::string_view section)
242 constexpr
static std::string_view crlf2 =
"\r\n\r\n";
244 const size_t found = section.find(crlf2);
245 const std::string_view head_line = section.substr(0, found + 2);
246 section = section.substr(found + 4);
249 parse_section_head(head_line),
250 section.substr(0, section.length() - 2),
258 while (!lines.empty())
262 const size_t found_crlf = lines.find(crlf);
263 std::string_view line = lines.substr(0, found_crlf);
264 std::string_view key;
265 lines = lines.substr(found_crlf + 2);
269 const size_t found_semicolon = line.find(
"; ");
270 std::string_view header = line.substr(0, found_semicolon);
271 if (found_semicolon != std::string_view::npos)
272 line = line.substr(found_semicolon + 2);
274 line = std::string_view();
276 const size_t header_split = header.find(
": ");
277 key = header.substr(0, header_split);
279 to_add.value = header.substr(header_split + 2);
283 while (!line.empty())
285 const size_t found_semicolon = line.find(
"; ");
286 std::string_view param = line.substr(0, found_semicolon);
287 if (found_semicolon != std::string_view::npos)
288 line = line.substr(found_semicolon + 2);
290 line = std::string_view();
292 const size_t param_split = param.find(
'=');
294 const std::string_view value = param.substr(param_split + 1);
296 to_add.params.emplace(param.substr(0, param_split), trim(value));
298 result.emplace(key, to_add);
304 inline std::string_view trim(
const std::string_view
string,
const char excess =
'"')
const
306 if (
string.length() > 1 &&
string[0] == excess &&
string[
string.length() - 1] == excess)
307 return string.substr(1,
string.length() - 2);
std::unordered_multimap< std::string_view, part_view, ci_hash, ci_key_eq > mp_view_map
Multipart map (key is the name parameter).
Definition: multipart_view.h:118
std::unordered_multimap< std::string_view, header_view, ci_hash, ci_key_eq > mph_view_map
Multipart header map (key is header key).
Definition: multipart_view.h:43
const header & get_header_object(const T &headers, const std::string &key)
Same as get_header_value_object() but for multipart::header.
Definition: multipart.h:48
The main namespace of the library. In this namespace is defined the most important classes and functi...
const std::string & get_header_value(const T &headers, const std::string &key)
Find and return the value associated with the key. (returns an empty string if nothing is found)
Definition: http_request.h:24
The parsed multipart request/response.
Definition: multipart_view.h:122
std::reference_wrapper< const ci_map > headers
The request/response headers.
Definition: multipart_view.h:123
std::vector< part_view > parts
The individual parts of the message.
Definition: multipart_view.h:125
std::string dump(int part_) const
Represent an individual part as a string.
Definition: multipart_view.h:165
mp_view_map part_map
The individual parts of the message, organized in a map with the name header parameter being the key.
Definition: multipart_view.h:126
message_view(const ci_map &headers_, const std::string &boundary_, const std::vector< part_view > §ions)
Default constructor using default values.
Definition: multipart_view.h:173
std::string boundary
The text boundary that separates different parts
Definition: multipart_view.h:124
message_view(const request &req)
Create a multipart message from a request data.
Definition: multipart_view.h:185
std::string dump() const
Represent all parts as a string (does not include message headers)
Definition: multipart_view.h:157
String padded with the specified padding (double quotes by default)
Definition: multipart_view.h:60
std::string_view value
String to pad.
Definition: multipart_view.h:61
friend std::ostream & operator<<(std::ostream &stream, const padded value_)
Outputs padded value to the stream.
Definition: multipart_view.h:65
const char padding
Padding to use.
Definition: multipart_view.h:62
One part of the multipart message.
Definition: multipart_view.h:76
mph_view_map headers
(optional) The first part before the data, Contains information regarding the type of data and encodi...
Definition: multipart_view.h:77
std::string_view body
The actual data in the part.
Definition: multipart_view.h:78
An HTTP request.
Definition: http_request.h:36