X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fmessage.cpp;h=2b3e40b539d9208138153d6401d453e17a590cee;hb=c8df43e7794dc82d5604dfa612e464bbc5ca3cdd;hp=a8851fa31c4b5b86f9b7df6ff2c0ec60d457ba04;hpb=070d56e7b0036ca2e4234eb06dcae83ebfb3df34;p=libs%2Fnet.git diff --git a/source/message.cpp b/source/message.cpp index a8851fa..2b3e40b 100644 --- a/source/message.cpp +++ b/source/message.cpp @@ -1,86 +1,89 @@ -/* $Id$ - -This file is part of libmsphttp -Copyright © 2008 Mikkosoft Productions, Mikko Rasa -Distributed under the LGPL -*/ - #include +#include #include #include #include "message.h" 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); - if(i==headers.end()) - throw KeyError(format("Header %s is not defined", hdr)); + return get_item(headers, normalize_header_name(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())); } -void Message::add_data(const string &d) +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 len=min(needed, d.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; + 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"); if(chunk_length==0) - complete=true; - pos=lf+1; + complete = true; + pos = lf+1; } else { - unsigned len=min(chunk_length, d.size()-pos); - data.append(d, pos, len); - chunk_length-=len; - if((pos=d.find('\n', pos+len))!=string::npos) + 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) ++pos; } } @@ -88,26 +91,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 invalid_argument("Message::parse_headers"); + if(lf==start || (d[start]=='\r' && lf==start+1)) + return lf+1; + + unsigned colon = d.find(':', start); + if(colon>lf) + throw invalid_argument("Message::parse_headers"); + + 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+=data; + 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