2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-30 20:32:15 +00:00

absolute-uri, relative-ref

This commit is contained in:
Vinnie Falco
2021-09-05 16:39:06 -07:00
parent e2694e8132
commit 7ff92edd6b
13 changed files with 337 additions and 14 deletions

View File

@@ -26,6 +26,7 @@
#include <boost/url/bnf/repeat.hpp>
#include <boost/url/bnf/token.hpp>
#include <boost/url/rfc/absolute_uri_bnf.hpp>
#include <boost/url/rfc/authority_bnf.hpp>
#include <boost/url/rfc/char_sets.hpp>
#include <boost/url/rfc/fragment_bnf.hpp>
@@ -39,6 +40,7 @@
#include <boost/url/rfc/pct_encoding.hpp>
#include <boost/url/rfc/port_bnf.hpp>
#include <boost/url/rfc/relative_part_bnf.hpp>
#include <boost/url/rfc/relative_ref_bnf.hpp>
#include <boost/url/rfc/query_bnf.hpp>
#include <boost/url/rfc/scheme_bnf.hpp>
#include <boost/url/rfc/uri_bnf.hpp>

View File

@@ -0,0 +1,57 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//
#ifndef BOOST_URL_RFC_ABSOLUTE_URI_BNF_HPP
#define BOOST_URL_RFC_ABSOLUTE_URI_BNF_HPP
#include <boost/url/detail/config.hpp>
#include <boost/url/error.hpp>
#include <boost/url/bnf/range.hpp>
#include <boost/url/rfc/authority_bnf.hpp>
#include <boost/url/rfc/pct_encoded_str.hpp>
#include <boost/url/rfc/query_bnf.hpp>
#include <boost/url/rfc/scheme_bnf.hpp>
#include <boost/optional.hpp>
namespace boost {
namespace urls {
namespace rfc {
/** BNF for absolute-URI
@par BNF
@code
absolute-URI = scheme ":" hier-part [ "?" query ]
@endcode
@see
https://datatracker.ietf.org/doc/html/rfc3986#section-3
*/
struct absolute_uri_bnf
{
scheme_bnf scheme;
bnf::range<pct_encoded_str> path;
optional<authority_bnf> authority;
optional<bnf::range<query_param>> query;
BOOST_URL_DECL
friend
bool
parse(
char const*& it,
char const* const end,
error_code& ec,
absolute_uri_bnf& t);
};
} // rfc
} // urls
} // boost
#endif

View File

@@ -0,0 +1,67 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//
#ifndef BOOST_URL_RFC_IMPL_ABSOLUTE_URI_BNF_IPP
#define BOOST_URL_RFC_IMPL_ABSOLUTE_URI_BNF_IPP
#include <boost/url/rfc/absolute_uri_bnf.hpp>
#include <boost/url/bnf/parse.hpp>
#include <boost/url/rfc/fragment_bnf.hpp>
#include <boost/url/rfc/hier_part_bnf.hpp>
#include <boost/url/rfc/query_bnf.hpp>
#include <boost/url/rfc/scheme_bnf.hpp>
namespace boost {
namespace urls {
namespace rfc {
bool
parse(
char const*& it,
char const* const end,
error_code& ec,
absolute_uri_bnf& t)
{
using bnf::parse;
// scheme ":"
if(! parse(it, end, ec,
t.scheme, ':'))
return false;
// hier-part
hier_part_bnf hp;
if(! parse(it, end, ec, hp))
return false;
t.authority = hp.authority;
t.path = hp.path;
// [ "?" query ]
if( it != end &&
*it == '?')
{
++it;
t.query.emplace();
if(! parse(it, end, ec,
query_bnf{*t.query}))
return false;
}
else
{
t.query.reset();
}
return true;
}
} // rfc
} // urls
} // boost
#endif

View File

@@ -28,7 +28,6 @@ parse(
error_code& ec,
port_bnf& t)
{
using bnf::parse;
bnf::digit_chars cs;
port_bnf::number_type u = 0;
auto const start = it;

View File

@@ -0,0 +1,77 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//
#ifndef BOOST_URL_RFC_IMPL_RELATIVE_REF_BNF_IPP
#define BOOST_URL_RFC_IMPL_RELATIVE_REF_BNF_IPP
#include <boost/url/rfc/relative_ref_bnf.hpp>
#include <boost/url/bnf/parse.hpp>
#include <boost/url/rfc/fragment_bnf.hpp>
#include <boost/url/rfc/query_bnf.hpp>
#include <boost/url/rfc/relative_part_bnf.hpp>
namespace boost {
namespace urls {
namespace rfc {
bool
parse(
char const*& it,
char const* const end,
error_code& ec,
relative_ref_bnf& t)
{
using bnf::parse;
// relative-part
relative_part_bnf rp;
if(! parse(it, end, ec, rp))
return false;
t.authority = rp.authority;
t.path = rp.path;
// [ "?" query ]
if( it != end &&
*it == '?')
{
++it;
t.query.emplace();
if(! parse(it, end, ec,
query_bnf{*t.query}))
return false;
}
else
{
t.query.reset();
}
// [ "#" fragment ]
if( it != end &&
*it == '#')
{
++it;
t.fragment.emplace();
if(! parse(it, end, ec,
fragment_bnf{
*t.fragment}))
return false;
}
else
{
t.fragment.reset();
}
return true;
}
} // rfc
} // urls
} // boost
#endif

View File

@@ -36,11 +36,11 @@ parse(
return false;
// hier-part
hier_part_bnf h;
if(! parse(it, end, ec, h))
hier_part_bnf hp;
if(! parse(it, end, ec, hp))
return false;
t.authority = h.authority;
t.path = h.path;
t.authority = hp.authority;
t.path = hp.path;
// [ "?" query ]
if( it != end &&

View File

@@ -0,0 +1,57 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//
#ifndef BOOST_URL_RFC_RELATIVE_REF_BNF_HPP
#define BOOST_URL_RFC_RELATIVE_REF_BNF_HPP
#include <boost/url/detail/config.hpp>
#include <boost/url/error.hpp>
#include <boost/url/bnf/range.hpp>
#include <boost/url/rfc/authority_bnf.hpp>
#include <boost/url/rfc/pct_encoded_str.hpp>
#include <boost/url/rfc/query_bnf.hpp>
#include <boost/url/rfc/scheme_bnf.hpp>
#include <boost/optional.hpp>
namespace boost {
namespace urls {
namespace rfc {
/** BNF for relative-ref
@par BNF
@code
relative-ref = relative-part [ "?" query ] [ "#" fragment ]
@endcode
@see
https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
*/
struct relative_ref_bnf
{
bnf::range<pct_encoded_str> path;
optional<authority_bnf> authority;
optional<bnf::range<query_param>> query;
optional<pct_encoded_str> fragment;
BOOST_URL_DECL
friend
bool
parse(
char const*& it,
char const* const end,
error_code& ec,
relative_ref_bnf& t);
};
} // rfc
} // urls
} // boost
#endif

View File

@@ -28,11 +28,6 @@ namespace rfc {
@par BNF
@code
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
@endcode
@see

View File

@@ -33,6 +33,7 @@ in a translation unit of the program.
#include <boost/url/impl/url.ipp>
#include <boost/url/impl/url_view.ipp>
#include <boost/url/rfc/impl/absolute_uri_bnf.ipp>
#include <boost/url/rfc/impl/authority_bnf.ipp>
#include <boost/url/rfc/impl/char_sets.ipp>
#include <boost/url/rfc/impl/fragment_bnf.ipp>
@@ -46,6 +47,7 @@ in a translation unit of the program.
#include <boost/url/rfc/impl/port_bnf.ipp>
#include <boost/url/rfc/impl/query_bnf.ipp>
#include <boost/url/rfc/impl/relative_part_bnf.ipp>
#include <boost/url/rfc/impl/relative_ref_bnf.ipp>
#include <boost/url/rfc/impl/scheme_bnf.ipp>
#include <boost/url/rfc/impl/uri_bnf.ipp>
#include <boost/url/rfc/impl/userinfo_bnf.ipp>

View File

@@ -37,6 +37,7 @@ set(BOOST_URL_TESTS_FILES
bnf/range.cpp
bnf/repeat.cpp
bnf/token.cpp
rfc/absolute_uri_bnf.cpp
rfc/authority_bnf.cpp
rfc/char_sets.cpp
rfc/fragment_bnf.cpp

View File

@@ -0,0 +1,61 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//
// Test that header file is self-contained.
#include <boost/url/rfc/absolute_uri_bnf.hpp>
#include "test_suite.hpp"
#include "test_bnf.hpp"
#include <iostream>
namespace boost {
namespace urls {
namespace rfc {
class absolute_uri_bnf_test
{
public:
void
run()
{
using T = absolute_uri_bnf;
bad<T>("");
bad<T>(":");
bad<T>("http://#");
bad<T>("http://x.y.z/?a=b&c=d&#");
bad<T>("http://x.y.z/?a=b&c=d&#frag");
bad<T>("http://x.y.z/#frag");
good<T>("http:");
good<T>("http:x");
good<T>("http:x/");
good<T>("http:x/x");
good<T>("http:x//");
good<T>("http://");
good<T>("http://x");
good<T>("http://x.y.z");
good<T>("http://x.y.z/");
good<T>("http://x.y.z/?");
good<T>("http://x.y.z/?a");
good<T>("http://x.y.z/?a=");
good<T>("http://x.y.z/?a=b");
good<T>("http://x.y.z/?a=b&c=d");
good<T>("http://x.y.z/?a=b&c=d&");
}
};
TEST_SUITE(
absolute_uri_bnf_test,
"boost.url.absolute_uri_bnf");
} // rfc
} // urls
} // boost

View File

@@ -40,8 +40,7 @@ public:
void
run()
{
using T = optional<
port_bnf::number_type>;
using T = port_bnf;
bad<T>("x");
bad<T>("80x");

View File

@@ -27,8 +27,9 @@ public:
{
using T = uri_bnf;
bad <T>("");
bad <T>(":");
bad<T>("");
bad<T>(":");
bad<T>("http://##");
good<T>("http:");
good<T>("http:x");
@@ -45,6 +46,11 @@ public:
good<T>("http://x.y.z/?a=b");
good<T>("http://x.y.z/?a=b&c=d");
good<T>("http://x.y.z/?a=b&c=d&");
good<T>("http://x.y.z/?a=b&c=d&#");
good<T>("http://x.y.z/?a=b&c=d&#1");
good<T>("http://x.y.z/?a=b&c=d&#12");
good<T>("http://x.y.z/?a=b&c=d&#12%23");
good<T>("http://x.y.z/?a=b&c=d&#12%23%20");
}
};