3 This file is part of libmsphttp
4 Copyright © 2009 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
9 #include <msp/strings/formatter.h>
10 #include <msp/strings/regex.h>
11 #include <msp/strings/utils.h>
18 const char *reserved[]=
22 " !#$%&'()*+,/:;=?@[]",
25 bool is_reserved(char c, unsigned level)
27 for(const char *r=reserved[level]; *r; ++r)
38 string urlencode(const string &str, EncodeLevel level)
41 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
43 if(is_reserved(*i, level))
44 result+=format("%%%02X", *i);
51 string urlencode_plus(const string &str, EncodeLevel level)
54 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
58 else if(is_reserved(*i, level))
59 result+=format("%%%02X", *i);
66 string urldecode(const string &str)
69 for(unsigned i=0; i<str.size(); ++i)
75 throw InvalidParameterValue("Malformed data");
76 result+=lexical_cast<unsigned char>(str.substr(i+1, 2), "x");
87 Url parse_url(const string &str)
89 static Regex r_url("(([a-z]+)://)?([a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*(:[0-9])?)?(/[^?#]*)?(\\?([^#]+))?(#(.*))?");
90 if(RegMatch m=r_url.match(str))
95 url.path=urldecode(m[6].str);
97 url.fragment=m[10].str;
101 throw InvalidParameterValue("Invalid URL");
104 string build_url(const Url &url)
106 if(!url.path.empty() && url.path[0]!='/')
107 throw InvalidParameterValue("Only absolute paths are supported");
109 if(!url.scheme.empty())
110 str+=url.scheme+"://";
112 str+=urlencode(url.path);
113 if(!url.query.empty())
118 if(!url.fragment.empty())
126 Query parse_query(const std::string &str)
128 vector<string> parts=split(str, '&');
130 for(vector<string>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
132 unsigned equals=i->find('=');
133 string &value=query[urldecode(i->substr(0, equals))];
134 if(equals!=string::npos)
135 value=urldecode(i->substr(equals+1));
140 string build_query(const Query &query)
143 for(Query::const_iterator i=query.begin(); i!=query.end(); ++i)
147 str+=urlencode_plus(i->first);
149 str+=urlencode_plus(i->second);