]> git.tdb.fi Git - libs/net.git/blob - source/message.cpp
Rename data to content in Message
[libs/net.git] / source / message.cpp
1 /* $Id$
2
3 This file is part of libmsphttp
4 Copyright © 2008  Mikkosoft Productions, Mikko Rasa
5 Distributed under the LGPL
6 */
7
8 #include <cstdlib>
9 #include <msp/strings/formatter.h>
10 #include <msp/strings/utils.h>
11 #include "message.h"
12
13 using namespace std;
14
15 #include <iostream>
16
17 namespace Msp {
18 namespace Http {
19
20 void Message::set_header(const string &hdr, const string &val)
21 {
22         headers[tolower(hdr)]=val;
23 }
24
25 const string &Message::get_header(const string &hdr) const
26 {
27         HeaderMap::const_iterator i=headers.find(hdr);
28         if(i==headers.end())
29                 throw KeyError(format("Header %s is not defined", hdr));
30
31         return i->second;
32 }
33
34 void Message::add_content(const string &d)
35 {
36         content+=d;
37         if(headers.count("content-type")==0)
38                 set_header("content-type", "text/plain");
39         set_header("content-length", lexical_cast(content.size()));
40 }
41
42 void Message::set_user_data(const Variant &d)
43 {
44         user_data=d;
45 }
46
47 unsigned Message::parse_content(const string &d)
48 {
49         if(complete)
50                 return 0;
51
52         HeaderMap::const_iterator i=headers.find("content-length");
53         if(i!=headers.end())
54         {
55                 unsigned needed=lexical_cast<unsigned>(i->second)-content.size();
56                 unsigned len=min(needed, d.size());
57                 
58                 content.append(d, 0, len);
59
60                 if(len==needed)
61                         complete=true;
62                 
63                 return len;
64         }
65
66         i=headers.find("transfer-encoding");
67         if(i!=headers.end() && strcasecmp(i->second, "chunked")==0)
68         {
69                 unsigned pos=0;
70                 while(!complete && pos<d.size())
71                 {
72                         if(chunk_length==0)
73                         {
74                                 unsigned lf=d.find('\n', pos);
75                                 if(lf==string::npos)
76                                         return pos;
77                                 chunk_length=lexical_cast<unsigned>(strip(d.substr(pos, lf-pos)), "x");
78                                 if(chunk_length==0)
79                                         complete=true;
80                                 pos=lf+1;
81                         }
82                         else
83                         {
84                                 unsigned len=min(chunk_length, d.size()-pos);
85                                 content.append(d, pos, len);
86                                 chunk_length-=len;
87                                 if((pos=d.find('\n', pos+len))!=string::npos)
88                                         ++pos;
89                         }
90                 }
91
92                 return pos;
93         }
94
95         return 0;
96 }
97
98 Message::Message():
99         http_version(0x11),
100         chunk_length(0),
101         complete(false)
102 { }
103
104 string Message::str_common() const
105 {
106         string result;
107
108         for(HeaderMap::const_iterator i=headers.begin(); i!=headers.end(); ++i)
109                 result+=format("%s: %s\r\n", i->first, i->second);
110         result+="\r\n";
111         result+=content;
112
113         return result;
114 }
115
116 } // namespace Http
117 } // namespace Msp