From 6af74d460a0ec4f53bb5cff328ee34d05131be9a Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 25 Sep 2019 01:37:00 +0300 Subject: [PATCH] Add parsing for different styles of HTTP headers --- source/http/header.cpp | 64 ++++++++++++++++++++++++++++++++++-------- source/http/header.h | 17 +++++++++-- 2 files changed, 67 insertions(+), 14 deletions(-) diff --git a/source/http/header.cpp b/source/http/header.cpp index 02c82ca..3027d17 100644 --- a/source/http/header.cpp +++ b/source/http/header.cpp @@ -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; } } diff --git a/source/http/header.h b/source/http/header.h index 202b844..c3d07f3 100644 --- a/source/http/header.h +++ b/source/http/header.h @@ -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 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(); }; -- 2.43.0