2 #include <msp/core/maputils.h>
3 #include <msp/strings/formatter.h>
4 #include <msp/strings/utils.h>
18 void Message::set_header(const string &hdr, const string &val)
20 headers[normalize_header_name(hdr)] = val;
23 bool Message::has_header(const string &hdr) const
25 return headers.count(normalize_header_name(hdr));
28 const string &Message::get_header(const string &hdr) const
30 return get_item(headers, normalize_header_name(hdr));
33 void Message::add_content(const string &d)
36 if(headers.count("Content-Type")==0)
37 set_header("Content-Type", "text/plain");
38 set_header("Content-Length", lexical_cast(content.size()));
41 void Message::set_user_data(const Variant &d)
46 unsigned Message::parse_content(const string &d)
51 HeaderMap::const_iterator i = headers.find("Content-Length");
54 unsigned needed = lexical_cast<unsigned>(i->second)-content.size();
55 unsigned len = min(needed, d.size());
57 content.append(d, 0, len);
65 i = headers.find("Transfer-Encoding");
66 if(i!=headers.end() && strcasecmp(i->second, "chunked")==0)
69 while(!complete && pos<d.size())
73 unsigned lf = d.find('\n', pos);
76 chunk_length = lexical_cast<unsigned>(strip(d.substr(pos, lf-pos)), "x");
83 unsigned len = min(chunk_length, d.size()-pos);
84 content.append(d, pos, len);
86 if((pos = d.find('\n', pos+len))!=string::npos)
98 unsigned Message::parse_headers(const string &d)
103 unsigned lf = d.find('\n', start);
105 throw invalid_argument("Message::parse_headers");
106 if(lf==start || (d[start]=='\r' && lf==start+1))
109 unsigned colon = d.find(':', start);
111 throw invalid_argument("Message::parse_headers");
113 set_header(d.substr(start, colon-start), strip(d.substr(colon+1, lf-colon-1)));
119 string Message::str_common() const
123 for(HeaderMap::const_iterator i=headers.begin(); i!=headers.end(); ++i)
125 result += format("%s: %s\r\n", i->first, i->second);
132 string Message::normalize_header_name(const string &hdr) const
136 for(string::iterator i=result.begin(); i!=result.end(); ++i)