]> git.tdb.fi Git - libs/net.git/commitdiff
Add parsing for different styles of HTTP headers
authorMikko Rasa <tdb@tdb.fi>
Tue, 24 Sep 2019 22:37:00 +0000 (01:37 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 24 Sep 2019 22:37:00 +0000 (01:37 +0300)
source/http/header.cpp
source/http/header.h

index 02c82ca08001c10f898102afd1595a980ee3c8b8..3027d17d887eddaba34ff03fc90ade533c4b55cd 100644 (file)
@@ -8,37 +8,74 @@ using namespace std;
 namespace Msp {
 namespace Http {
 
-Header::Header(const Message &msg, const string &n):
+Header::Header(const Message &msg, const string &n, Style s):
        name(n),
+       style(s),
        raw_value(msg.get_header(name))
 {
        parse();
 }
 
-Header::Header(const string &n, const string &rv):
+Header::Header(const string &n, const string &rv, Style s):
        name(n),
+       style(s),
        raw_value(rv)
 {
        parse();
 }
 
+Header::Style Header::get_default_style(const string &name)
+{
+       if(!strcasecmp(name, "content-disposition"))
+               return VALUE_WITH_ATTRIBUTES;
+       else if(!strcasecmp(name, "content-type"))
+               return VALUE_WITH_ATTRIBUTES;
+       else if(!strcasecmp(name, "cookie"))
+               return KEY_VALUE_LIST;
+       else if(!strcasecmp(name, "set-cookie"))
+               return VALUE_WITH_ATTRIBUTES;
+       else
+               return SINGLE_VALUE;
+}
+
 void Header::parse()
 {
+       if(style==DEFAULT)
+               style = get_default_style(name);
+
+       if(style==SINGLE_VALUE)
+       {
+               Value value;
+               value.value = strip(raw_value);
+               values.push_back(value);
+               return;
+       }
+
+       char value_sep = (style==VALUE_WITH_ATTRIBUTES ? 0 : ',');
+
        string::const_iterator i = raw_value.begin();
        while(i!=raw_value.end())
        {
                Value value;
 
                string::const_iterator start = i;
-               for(; (i!=raw_value.end() && *i!=';' && *i!=','); ++i) ;
-               value.value = strip(string(start, i));
-               if(value.value.empty())
-                       throw invalid_argument("Header::parse");
+               if(style==KEY_VALUE_LIST)
+                       value.value = name;
+               else
+               {
+                       for(; (i!=raw_value.end() && *i!=';' && *i!=value_sep); ++i) ;
+                       value.value = strip(string(start, i));
+                       if(value.value.empty())
+                               throw invalid_argument("Header::parse");
+               }
 
-               while(i!=raw_value.end() && *i!=',')
+               while(i!=raw_value.end() && (*i!=',' || style==KEY_VALUE_LIST) && style!=LIST)
                {
-                       start = ++i;
-                       for(; (i!=raw_value.end() && *i!=';' && *i!=',' && *i!='='); ++i) ;
+                       if(*i==';' || *i==',')
+                               ++i;
+
+                       start = i;
+                       for(; (i!=raw_value.end() && *i!=';' && *i!=value_sep && *i!='='); ++i) ;
                        string pname = strip(string(start, i));
                        if(pname.empty())
                                throw invalid_argument("Header::parse");
@@ -47,7 +84,7 @@ void Header::parse()
                        if(i!=raw_value.end() && *i=='=')
                        {
                                for(++i; (i!=raw_value.end() && isspace(*i)); ++i) ;
-                               if(i==raw_value.end() || *i==';' || *i==',')
+                               if(i==raw_value.end() || *i==';' || *i==value_sep)
                                        throw invalid_argument("Header::parse");
 
                                if(*i=='"')
@@ -59,14 +96,14 @@ void Header::parse()
 
                                        pvalue = string(start, i);
 
-                                       for(++i; (i!=raw_value.end() && *i!=';' && *i!=','); ++i)
+                                       for(++i; (i!=raw_value.end() && *i!=';' && *i!=value_sep); ++i)
                                                if(!isspace(*i))
                                                        throw invalid_argument("Header::parse");
                                }
                                else
                                {
                                        start = i;
-                                       for(; (i!=raw_value.end() && *i!=';' && *i!=','); ++i) ;
+                                       for(; (i!=raw_value.end() && *i!=';' && *i!=value_sep); ++i) ;
                                        pvalue = strip(string(start, i));
                                }
                        }
@@ -75,6 +112,9 @@ void Header::parse()
                }
 
                values.push_back(value);
+
+               if(i!=raw_value.end() && (*i==';' || *i==','))
+                       ++i;
        }
 }
 
index 202b844110b1044d360eec00baaa30d6db8f94ad..c3d07f38dc81d75ec979ddc5538b0cc2c8aa4d54 100644 (file)
@@ -12,6 +12,16 @@ class Message;
 
 struct Header
 {
+       enum Style
+       {
+               DEFAULT,
+               SINGLE_VALUE,
+               LIST,
+               KEY_VALUE_LIST,
+               VALUE_WITH_ATTRIBUTES,
+               LIST_WITH_ATTRIBUTES
+       };
+
        struct Value
        {
                std::string value;
@@ -19,12 +29,15 @@ struct Header
        };
 
        std::string name;
+       Style style;
        std::string raw_value;
        std::vector<Value> values;
 
        Header() { }
-       Header(const Message &, const std::string &);
-       Header(const std::string &, const std::string &);
+       Header(const Message &, const std::string &, Style = DEFAULT);
+       Header(const std::string &, const std::string &, Style = DEFAULT);
+
+       static Style get_default_style(const std::string &);
 
        void parse();
 };