2 #include <msp/strings/formatter.h>
3 #include <msp/strings/utils.h>
17 void Message::set_header(const string &hdr, const string &val)
19 headers[normalize_header_name(hdr)] = val;
22 bool Message::has_header(const string &hdr) const
24 return headers.count(normalize_header_name(hdr));
27 const string &Message::get_header(const string &hdr) const
29 HeaderMap::const_iterator i = headers.find(normalize_header_name(hdr));
31 throw KeyError("Undefined header", hdr);
36 void Message::add_content(const string &d)
39 if(headers.count("Content-Type")==0)
40 set_header("Content-Type", "text/plain");
41 set_header("Content-Length", lexical_cast(content.size()));
44 void Message::set_user_data(const Variant &d)
49 unsigned Message::parse_content(const string &d)
54 HeaderMap::const_iterator i = headers.find("Content-Length");
57 unsigned needed = lexical_cast<unsigned>(i->second)-content.size();
58 unsigned len = min(needed, d.size());
60 content.append(d, 0, len);
68 i = headers.find("Transfer-Encoding");
69 if(i!=headers.end() && strcasecmp(i->second, "chunked")==0)
72 while(!complete && pos<d.size())
76 unsigned lf = d.find('\n', pos);
79 chunk_length = lexical_cast<unsigned>(strip(d.substr(pos, lf-pos)), "x");
86 unsigned len = min(chunk_length, d.size()-pos);
87 content.append(d, pos, len);
89 if((pos = d.find('\n', pos+len))!=string::npos)
101 unsigned Message::parse_headers(const string &d)
106 unsigned lf = d.find('\n', start);
108 throw InvalidParameterValue("Incomplete response");
109 if(lf==start || (d[start]=='\r' && lf==start+1))
112 unsigned colon = d.find(':', start);
114 throw InvalidParameterValue("No colon in header");
116 set_header(d.substr(start, colon-start), strip(d.substr(colon+1, lf-colon-1)));
122 string Message::str_common() const
126 for(HeaderMap::const_iterator i=headers.begin(); i!=headers.end(); ++i)
128 result += format("%s: %s\r\n", i->first, i->second);
135 string Message::normalize_header_name(const string &hdr) const
139 for(string::iterator i=result.begin(); i!=result.end(); ++i)