Browse Source

add simple URL parser that only does what necessary to parse HTTP redirects.

pull/2/head
roker 1 year ago
parent
commit
fafffa8855
2 changed files with 90 additions and 0 deletions
  1. +69
    -0
      url_parser.cc
  2. +21
    -0
      url_parser.hh

+ 69
- 0
url_parser.cc View File

@ -0,0 +1,69 @@
#include "url_parser.hh"
#include <stdexcept>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
BOOST_FUSION_ADAPT_STRUCT(
pEp::URL,
(std::string, schema)
(std::string, username)
(std::string, password)
(std::string, host)
(int , port)
(std::string, path_and_query)
(std::string, fragment)
)
namespace pEp
{
template <typename Iterator>
struct UriGrammar : qi::grammar<Iterator, URL()>
{
typedef unsigned long ulong;
UriGrammar() : UriGrammar::base_type(url)
{
schema = *(qi::char_ - ':' - '/');
username = *(qi::char_ - ':' - '@');
password = *(qi::char_ - '@');
host = *(qi::char_ - '/' - ':');
path_and_query = *(qi::char_ - '#');
fragment = *(qi::char_);
url = schema
>> "://" >> -( username
>> -(':' >> password) >> '@'
)
>> host
>> (':' >> qi::int_[ boost::phoenix::at_c<4>(qi::_val) = qi::_1 ])
>> -(path_and_query) // >> -('?' >> params[ boost::phoenix::at_c<6>(qi::_val) = qi::_1 ] )
>> -('#' >> fragment);
};
qi::rule<Iterator, URL()> url;
qi::rule<Iterator, std::string()> schema, username, password, host, path_and_query, fragment;
};
URL parse_url(const char* begin, const char* end)
{
static const UriGrammar<const char*> G;
URL url;
const char* begin2 = begin;
const bool okay = boost::spirit::qi::parse(begin2, end, G, url);
if(!okay)
{
throw std::runtime_error("Cannot parse URL <" + std::string(begin,end) + "> !");
}
return url;
}
} // end of namespace pEp

+ 21
- 0
url_parser.hh View File

@ -0,0 +1,21 @@
#pragma once
#include <string>
namespace pEp
{
struct URL
{
std::string schema; // http/https
std::string username;
std::string password;
std::string host;
int port = -1;
std::string path_and_query = "/"; // no need to split them down anymore
std::string fragment;
};
URL parse_url(const char* begin, const char* end);
} // end of namespace pEp

Loading…
Cancel
Save