]> git.tdb.fi Git - libs/net.git/blob - source/http/header.cpp
Add a dynamic receiver class for more flexible packet handling
[libs/net.git] / source / http / header.cpp
1 #include "header.h"
2 #include <stdexcept>
3 #include <msp/strings/utils.h>
4 #include "message.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace Http {
10
11 Header::Header(const Message &msg, const string &n, Style s):
12         name(n),
13         style(s),
14         raw_value(msg.get_header(name))
15 {
16         parse();
17 }
18
19 Header::Header(const string &n, const string &rv, Style s):
20         name(n),
21         style(s),
22         raw_value(rv)
23 {
24         parse();
25 }
26
27 Header::Style Header::get_default_style(const string &name)
28 {
29         if(!strcasecmp(name, "content-disposition"))
30                 return VALUE_WITH_ATTRIBUTES;
31         else if(!strcasecmp(name, "content-type"))
32                 return VALUE_WITH_ATTRIBUTES;
33         else if(!strcasecmp(name, "cookie"))
34                 return KEY_VALUE_LIST;
35         else if(!strcasecmp(name, "set-cookie"))
36                 return VALUE_WITH_ATTRIBUTES;
37         else
38                 return SINGLE_VALUE;
39 }
40
41 void Header::parse()
42 {
43         if(style==DEFAULT)
44                 style = get_default_style(name);
45
46         if(style==SINGLE_VALUE)
47         {
48                 Value value;
49                 value.value = strip(raw_value);
50                 values.push_back(value);
51                 return;
52         }
53
54         char value_sep = (style==VALUE_WITH_ATTRIBUTES ? 0 : ',');
55
56         auto i = raw_value.cbegin();
57         while(i!=raw_value.cend())
58         {
59                 Value value;
60
61                 auto start = i;
62                 if(style==KEY_VALUE_LIST)
63                         value.value = name;
64                 else
65                 {
66                         for(; (i!=raw_value.end() && *i!=';' && *i!=value_sep); ++i) ;
67                         value.value = strip(string(start, i));
68                         if(value.value.empty())
69                                 throw invalid_argument("Header::parse");
70                 }
71
72                 while(i!=raw_value.end() && (*i!=',' || style==KEY_VALUE_LIST) && style!=LIST)
73                 {
74                         if(*i==';' || *i==',')
75                                 ++i;
76
77                         start = i;
78                         for(; (i!=raw_value.end() && *i!=';' && *i!=value_sep && *i!='='); ++i) ;
79                         string pname = strip(string(start, i));
80                         if(pname.empty())
81                                 throw invalid_argument("Header::parse");
82
83                         string pvalue;
84                         if(i!=raw_value.end() && *i=='=')
85                         {
86                                 for(++i; (i!=raw_value.end() && isspace(*i)); ++i) ;
87                                 if(i==raw_value.end() || *i==';' || *i==value_sep)
88                                         throw invalid_argument("Header::parse");
89
90                                 if(*i=='"')
91                                 {
92                                         start = ++i;
93                                         for(; (i!=raw_value.end() && *i!='"'); ++i) ;
94                                         if(i==raw_value.end())
95                                                 throw invalid_argument("Header::parse");
96
97                                         pvalue = string(start, i);
98
99                                         for(++i; (i!=raw_value.end() && *i!=';' && *i!=value_sep); ++i)
100                                                 if(!isspace(*i))
101                                                         throw invalid_argument("Header::parse");
102                                 }
103                                 else
104                                 {
105                                         start = i;
106                                         for(; (i!=raw_value.end() && *i!=';' && *i!=value_sep); ++i) ;
107                                         pvalue = strip(string(start, i));
108                                 }
109                         }
110
111                         value.parameters[pname] = pvalue;
112                 }
113
114                 values.push_back(value);
115
116                 if(i!=raw_value.end() && (*i==';' || *i==','))
117                         ++i;
118         }
119 }
120
121 } // namespace Http
122 } // namespace Msp