]> git.tdb.fi Git - libs/net.git/commitdiff
Add a utility struct for parsing complex header values
authorMikko Rasa <tdb@tdb.fi>
Mon, 16 May 2016 09:06:19 +0000 (12:06 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 16 May 2016 09:06:19 +0000 (12:06 +0300)
It's not used to store headers in Message since not all headers follow
the same syntax.  User-Agent in particular may have semicolons which are
not parameters separators.

source/http/header.cpp [new file with mode: 0644]
source/http/header.h [new file with mode: 0644]

diff --git a/source/http/header.cpp b/source/http/header.cpp
new file mode 100644 (file)
index 0000000..02c82ca
--- /dev/null
@@ -0,0 +1,82 @@
+#include <stdexcept>
+#include <msp/strings/utils.h>
+#include "header.h"
+#include "message.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Http {
+
+Header::Header(const Message &msg, const string &n):
+       name(n),
+       raw_value(msg.get_header(name))
+{
+       parse();
+}
+
+Header::Header(const string &n, const string &rv):
+       name(n),
+       raw_value(rv)
+{
+       parse();
+}
+
+void Header::parse()
+{
+       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");
+
+               while(i!=raw_value.end() && *i!=',')
+               {
+                       start = ++i;
+                       for(; (i!=raw_value.end() && *i!=';' && *i!=',' && *i!='='); ++i) ;
+                       string pname = strip(string(start, i));
+                       if(pname.empty())
+                               throw invalid_argument("Header::parse");
+
+                       string pvalue;
+                       if(i!=raw_value.end() && *i=='=')
+                       {
+                               for(++i; (i!=raw_value.end() && isspace(*i)); ++i) ;
+                               if(i==raw_value.end() || *i==';' || *i==',')
+                                       throw invalid_argument("Header::parse");
+
+                               if(*i=='"')
+                               {
+                                       start = ++i;
+                                       for(; (i!=raw_value.end() && *i!='"'); ++i) ;
+                                       if(i==raw_value.end())
+                                               throw invalid_argument("Header::parse");
+
+                                       pvalue = string(start, i);
+
+                                       for(++i; (i!=raw_value.end() && *i!=';' && *i!=','); ++i)
+                                               if(!isspace(*i))
+                                                       throw invalid_argument("Header::parse");
+                               }
+                               else
+                               {
+                                       start = i;
+                                       for(; (i!=raw_value.end() && *i!=';' && *i!=','); ++i) ;
+                                       pvalue = strip(string(start, i));
+                               }
+                       }
+
+                       value.parameters[pname] = pvalue;
+               }
+
+               values.push_back(value);
+       }
+}
+
+} // namespace Http
+} // namespace Msp
diff --git a/source/http/header.h b/source/http/header.h
new file mode 100644 (file)
index 0000000..202b844
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef MSP_HTTP_HEADER_H_
+#define MSP_HTTP_HEADER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace Msp {
+namespace Http {
+
+class Message;
+
+struct Header
+{
+       struct Value
+       {
+               std::string value;
+               std::map<std::string, std::string> parameters;
+       };
+
+       std::string name;
+       std::string raw_value;
+       std::vector<Value> values;
+
+       Header() { }
+       Header(const Message &, const std::string &);
+       Header(const std::string &, const std::string &);
+
+       void parse();
+};
+
+} // namespace Http
+} // namespace Msp
+
+#endif