+++ /dev/null
-#include <algorithm>
-#include <msp/strings/formatter.h>
-#include <msp/strings/regex.h>
-#include <msp/strings/utils.h>
-#include "utils.h"
-
-using namespace std;
-
-namespace {
-
-const char *reserved[]=
-{
- " #%&+=?",
- " #%&*+:;=?@[]",
- " !#$%&'()*+,/:;=?@[]",
-};
-
-bool is_reserved(char c, unsigned level)
-{
- for(const char *r=reserved[level]; *r; ++r)
- if(c==*r)
- return true;
- return false;
-}
-
-}
-
-namespace Msp {
-namespace Http {
-
-string urlencode(const string &str, EncodeLevel level)
-{
- string result;
- for(string::const_iterator i=str.begin(); i!=str.end(); ++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;
- }
- return result;
-}
-
-string urldecode(const string &str)
-{
- string result;
- for(unsigned i=0; i<str.size(); ++i)
- {
- char c = str[i];
- if(c=='%')
- {
- if(i+3>str.size())
- throw invalid_argument("urldecode");
- result += lexical_cast<unsigned char>(str.substr(i+1, 2), "x");
- i += 2;
- }
- else if(c=='+')
- result += ' ';
- else
- result += c;
- }
- 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 invalid_argument("parse_url");
-}
-
-string build_url(const Url &url)
-{
- if(!url.path.empty() && url.path[0]!='/')
- throw invalid_argument("build_url");
-
- 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<string> parts = split(str, '&');
- Query query;
- for(vector<string>::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