2 #include <msp/core/maputils.h>
5 #include "submessage.h"
13 FormData::FormData(const Request &req)
15 const string &method = req.get_method();
18 Url url = parse_url(req.get_path());
19 fields = parse_query(url.query);
21 else if(method=="POST")
23 Header content_type(req, "Content-Type");
24 const Header::Value &ct_value = content_type.values.at(0);
25 if(ct_value.value=="application/x-www-form-urlencoded")
26 fields = parse_query(req.get_content());
27 else if(ct_value.value=="multipart/form-data")
29 const string &boundary = get_item(ct_value.parameters, "boundary");
30 parse_multipart(req, boundary);
33 throw invalid_argument("FormData::FormData");
36 throw invalid_argument("FormData::FormData");
39 void FormData::parse_multipart(const Request &req, const string &boundary)
41 const string &content = req.get_content();
43 string::size_type line_start = 0;
44 string::size_type part_start = 0;
47 string::size_type lf = content.find('\n', line_start);
49 throw invalid_argument("FormData::parse_multipart");
51 bool is_boundary = !content.compare(line_start, 2, "--");
52 is_boundary = (is_boundary && !content.compare(line_start+2, boundary.size(), boundary));
58 /* The CRLF preceding the boundary delimiter is treated as part
59 of the delimiter as per RFC 2046 */
60 string::size_type part_end = line_start-1;
61 if(content[part_end-1]=='\r')
64 SubMessage part = SubMessage::parse(content.substr(part_start, part_end-part_start));
65 Header content_disposition(part, "Content-Disposition");
66 const Header::Value &cd_value = content_disposition.values.at(0);
67 if(cd_value.value=="form-data")
69 const string &name = get_item(cd_value.parameters, "name");
70 fields[name] = part.get_content();
76 if(!content.compare(line_start+2+boundary.size(), 2, "--"))
84 const string &FormData::get_value(const string &key) const
86 auto i = fields.find(key);