X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fmessage.cpp;h=4aaa8bfd26d1fab34302cd6f32e0c583bac133fe;hb=f53eda26a3160972908f15c2427a60b0b82fbe87;hp=a8851fa31c4b5b86f9b7df6ff2c0ec60d457ba04;hpb=070d56e7b0036ca2e4234eb06dcae83ebfb3df34;p=libs%2Fnet.git diff --git a/source/message.cpp b/source/message.cpp index a8851fa..4aaa8bf 100644 --- a/source/message.cpp +++ b/source/message.cpp @@ -12,45 +12,59 @@ Distributed under the LGPL using namespace std; -#include - namespace Msp { namespace Http { +Message::Message(): + http_version(0x11), + chunk_length(0), + complete(false) +{ } + void Message::set_header(const string &hdr, const string &val) { - headers[tolower(hdr)]=val; + headers[normalize_header_name(hdr)]=val; +} + +bool Message::has_header(const string &hdr) const +{ + return headers.count(normalize_header_name(hdr)); } const string &Message::get_header(const string &hdr) const { - HeaderMap::const_iterator i=headers.find(hdr); + HeaderMap::const_iterator i=headers.find(normalize_header_name(hdr)); if(i==headers.end()) - throw KeyError(format("Header %s is not defined", hdr)); + throw KeyError("Undefined header", hdr); return i->second; } -void Message::add_data(const string &d) +void Message::add_content(const string &d) +{ + content+=d; + if(headers.count("Content-Type")==0) + set_header("Content-Type", "text/plain"); + set_header("Content-Length", lexical_cast(content.size())); +} + +void Message::set_user_data(const Variant &d) { - data+=d; - if(headers.count("content-type")==0) - set_header("content-type", "text/plain"); - set_header("content-length", lexical_cast(data.size())); + user_data=d; } -unsigned Message::parse_data(const string &d) +unsigned Message::parse_content(const string &d) { if(complete) return 0; - HeaderMap::const_iterator i=headers.find("content-length"); + HeaderMap::const_iterator i=headers.find("Content-Length"); if(i!=headers.end()) { - unsigned needed=lexical_cast(i->second)-data.size(); + unsigned needed=lexical_cast(i->second)-content.size(); unsigned len=min(needed, d.size()); - data.append(d, 0, len); + content.append(d, 0, len); if(len==needed) complete=true; @@ -58,7 +72,7 @@ unsigned Message::parse_data(const string &d) return len; } - i=headers.find("transfer-encoding"); + i=headers.find("Transfer-Encoding"); if(i!=headers.end() && strcasecmp(i->second, "chunked")==0) { unsigned pos=0; @@ -69,8 +83,7 @@ unsigned Message::parse_data(const string &d) unsigned lf=d.find('\n', pos); if(lf==string::npos) return pos; - // XXX strtoul - chunk_length=strtoul(strip(d.substr(pos, lf-pos)).c_str(), 0, 16); + chunk_length=lexical_cast(strip(d.substr(pos, lf-pos)), "x"); if(chunk_length==0) complete=true; pos=lf+1; @@ -78,7 +91,7 @@ unsigned Message::parse_data(const string &d) else { unsigned len=min(chunk_length, d.size()-pos); - data.append(d, pos, len); + content.append(d, pos, len); chunk_length-=len; if((pos=d.find('\n', pos+len))!=string::npos) ++pos; @@ -88,26 +101,62 @@ unsigned Message::parse_data(const string &d) return pos; } + complete=true; return 0; } -Message::Message(): - http_version(0x11), - chunk_length(0), - complete(false) -{ } +unsigned Message::parse_headers(const string &d) +{ + unsigned start=0; + while(1) + { + unsigned lf=d.find('\n', start); + if(lf==string::npos) + throw InvalidParameterValue("Incomplete response"); + if(lf==start || (d[start]=='\r' && lf==start+1)) + return lf+1; + + unsigned colon=d.find(':', start); + if(colon>lf) + throw InvalidParameterValue("No colon in header"); + + set_header(d.substr(start, colon-start), strip(d.substr(colon+1, lf-colon-1))); + + start=lf+1; + } +} string Message::str_common() const { string result; for(HeaderMap::const_iterator i=headers.begin(); i!=headers.end(); ++i) - result+=format("%s: %s\r\n", i->first, i->second); + if(i->first[0]!='-') + result+=format("%s: %s\r\n", i->first, i->second); result+="\r\n"; - result+=data; + result+=content; return result; } +string Message::normalize_header_name(const string &hdr) const +{ + string result=hdr; + bool upper=true; + for(string::iterator i=result.begin(); i!=result.end(); ++i) + { + if(upper) + { + *i=toupper(*i); + upper=false; + } + else if(*i=='-') + upper=true; + else + *i=tolower(*i); + } + return result; +} + } // namespace Http } // namespace Msp