X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fmessage.cpp;h=f1e4c286bd13031c1918d21cebacec189200223c;hb=1c965907682f4714db7b952915cf5b6bf9b7f4c1;hp=e0a5e7e171bf8afad01cf8932e4ca01acfb720b1;hpb=a4049d7c4126126ca3abd12b1aca8715e7006d44;p=libs%2Fnet.git diff --git a/source/message.cpp b/source/message.cpp index e0a5e7e..f1e4c28 100644 --- a/source/message.cpp +++ b/source/message.cpp @@ -1,10 +1,3 @@ -/* $Id$ - -This file is part of libmsphttp -Copyright © 2008 Mikkosoft Productions, Mikko Rasa -Distributed under the LGPL -*/ - #include #include #include @@ -12,36 +5,45 @@ 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_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())); + 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) { - user_data=d; + user_data = d; } unsigned Message::parse_content(const string &d) @@ -49,42 +51,42 @@ 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)-content.size(); - unsigned len=min(needed, d.size()); + unsigned needed = lexical_cast(i->second)-content.size(); + unsigned len = min(needed, d.size()); content.append(d, 0, len); if(len==needed) - complete=true; + complete = true; return len; } - i=headers.find("transfer-encoding"); + i = headers.find("Transfer-Encoding"); if(i!=headers.end() && strcasecmp(i->second, "chunked")==0) { - unsigned pos=0; + unsigned pos = 0; while(!complete && pos(strip(d.substr(pos, lf-pos)), "x"); + chunk_length = lexical_cast(strip(d.substr(pos, lf-pos)), "x"); if(chunk_length==0) - complete=true; - pos=lf+1; + complete = true; + pos = lf+1; } else { - unsigned len=min(chunk_length, d.size()-pos); + unsigned len = min(chunk_length, d.size()-pos); content.append(d, pos, len); - chunk_length-=len; - if((pos=d.find('\n', pos+len))!=string::npos) + chunk_length -= len; + if((pos = d.find('\n', pos+len))!=string::npos) ++pos; } } @@ -92,26 +94,62 @@ unsigned Message::parse_content(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); - result+="\r\n"; - result+=content; + if(i->first[0]!='-') + result += format("%s: %s\r\n", i->first, i->second); + result += "\r\n"; + 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