X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Futils.cpp;fp=source%2Futils.cpp;h=b6340db7dfd2da87a9abc6c9cbb8baabb6fba999;hb=f53eda26a3160972908f15c2427a60b0b82fbe87;hp=d550259984f79357ca94449df00a4a53ce8dbdcc;hpb=077408f98f08fac1a098a501fffdb22728a57a46;p=libs%2Fnet.git diff --git a/source/utils.cpp b/source/utils.cpp index d550259..b6340db 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -5,18 +5,26 @@ Copyright © 2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include #include +#include +#include #include "utils.h" using namespace std; namespace { -const char reserved[]=" :/?#[]@!$&'()*+,;=%"; +const char *reserved[]= +{ + " #%&+=?", + " #%&*+:;=?@[]", + " !#$%&'()*+,/:;=?@[]", +}; -bool is_reserved(char c) +bool is_reserved(char c, unsigned level) { - for(const char *r=reserved; *r; ++r) + for(const char *r=reserved[level]; *r; ++r) if(c==*r) return true; return false; @@ -27,12 +35,27 @@ bool is_reserved(char c) namespace Msp { namespace Http { -string urlencode(const string &str) +string urlencode(const string &str, EncodeLevel level) { string result; for(string::const_iterator i=str.begin(); i!=str.end(); ++i) { - if(is_reserved(*i)) + if(is_reserved(*i, level)) + result+=format("%%%02X", *i); + else + result+=*i; + } + return result; +} + +string urlencode_plus(const string &str, EncodeLevel level) +{ + string result; + for(string::const_iterator i=str.begin(); i!=str.end(); ++i) + { + if(*i==' ') + result+='+'; + else if(is_reserved(*i, level)) result+=format("%%%02X", *i); else result+=*i; @@ -61,5 +84,72 @@ string urldecode(const string &str) return result; } +Url parse_url(const string &str) +{ + static Regex r_url("(([a-z]+)://)?([a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*(:[0-9])?)?(/[^?#]*)?(\\?([^#]+))?(#(.*))?"); + if(RegMatch m=r_url.match(str)) + { + Url url; + url.scheme=m[2].str; + url.host=m[3].str; + url.path=urldecode(m[6].str); + url.query=m[8].str; + url.fragment=m[10].str; + return url; + } + else + throw InvalidParameterValue("Invalid URL"); +} + +string build_url(const Url &url) +{ + if(!url.path.empty() && url.path[0]!='/') + throw InvalidParameterValue("Only absolute paths are supported"); + string str; + if(!url.scheme.empty()) + str+=url.scheme+"://"; + str+=url.host; + str+=urlencode(url.path); + if(!url.query.empty()) + { + str+='?'; + str+=url.query; + } + if(!url.fragment.empty()) + { + str+='#'; + str+=url.fragment; + } + return str; +} + +Query parse_query(const std::string &str) +{ + vector parts=split(str, '&'); + Query query; + for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) + { + unsigned equals=i->find('='); + string &value=query[urldecode(i->substr(0, equals))]; + if(equals!=string::npos) + value=urldecode(i->substr(equals+1)); + } + return query; +} + +string build_query(const Query &query) +{ + string str; + for(Query::const_iterator i=query.begin(); i!=query.end(); ++i) + { + if(i!=query.begin()) + str+='&'; + str+=urlencode_plus(i->first); + str+='='; + str+=urlencode_plus(i->second); + } + return str; +} + } // namespace Http } // namespace Msp