+++ /dev/null
-#include <cstdlib>
-#include <msp/core/maputils.h>
-#include <msp/strings/formatter.h>
-#include <msp/strings/utils.h>
-#include "message.h"
-
-using namespace std;
-
-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[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
-{
- return get_item(headers, normalize_header_name(hdr));
-}
-
-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)
-{
- user_data = d;
-}
-
-unsigned Message::parse_content(const string &d)
-{
- if(complete)
- return 0;
-
- HeaderMap::const_iterator i = headers.find("Content-Length");
- if(i!=headers.end())
- {
- unsigned needed = lexical_cast<unsigned>(i->second)-content.size();
- unsigned len = min(needed, d.size());
-
- content.append(d, 0, len);
-
- if(len==needed)
- complete = true;
-
- return len;
- }
-
- i = headers.find("Transfer-Encoding");
- if(i!=headers.end() && strcasecmp(i->second, "chunked")==0)
- {
- unsigned pos = 0;
- while(!complete && pos<d.size())
- {
- if(chunk_length==0)
- {
- unsigned lf = d.find('\n', pos);
- if(lf==string::npos)
- return pos;
- chunk_length = lexical_cast<unsigned>(strip(d.substr(pos, lf-pos)), "x");
- if(chunk_length==0)
- complete = true;
- pos = lf+1;
- }
- else
- {
- 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;
- }
- }
-
- return pos;
- }
-
- complete = true;
- return 0;
-}
-
-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)
- 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