From 451c140747bef1829d55d20a33dd3543b9ab8c98 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 16 May 2016 12:06:19 +0300 Subject: [PATCH] Add a utility struct for parsing complex header values 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 | 82 ++++++++++++++++++++++++++++++++++++++++++ source/http/header.h | 35 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 source/http/header.cpp create mode 100644 source/http/header.h diff --git a/source/http/header.cpp b/source/http/header.cpp new file mode 100644 index 0000000..02c82ca --- /dev/null +++ b/source/http/header.cpp @@ -0,0 +1,82 @@ +#include +#include +#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 index 0000000..202b844 --- /dev/null +++ b/source/http/header.h @@ -0,0 +1,35 @@ +#ifndef MSP_HTTP_HEADER_H_ +#define MSP_HTTP_HEADER_H_ + +#include +#include +#include + +namespace Msp { +namespace Http { + +class Message; + +struct Header +{ + struct Value + { + std::string value; + std::map parameters; + }; + + std::string name; + std::string raw_value; + std::vector values; + + Header() { } + Header(const Message &, const std::string &); + Header(const std::string &, const std::string &); + + void parse(); +}; + +} // namespace Http +} // namespace Msp + +#endif -- 2.43.0