diff --git a/include/boost/url.hpp b/include/boost/url.hpp index deef0eea..934a26ba 100644 --- a/include/boost/url.hpp +++ b/include/boost/url.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/url/rfc/absolute_uri_bnf.hpp b/include/boost/url/rfc/absolute_uri_bnf.hpp new file mode 100644 index 00000000..b7c1ed5f --- /dev/null +++ b/include/boost/url/rfc/absolute_uri_bnf.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + +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 path; + optional authority; + optional> 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 diff --git a/include/boost/url/rfc/impl/absolute_uri_bnf.ipp b/include/boost/url/rfc/impl/absolute_uri_bnf.ipp new file mode 100644 index 00000000..4620f435 --- /dev/null +++ b/include/boost/url/rfc/impl/absolute_uri_bnf.ipp @@ -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 +#include +#include +#include +#include +#include + +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 diff --git a/include/boost/url/rfc/impl/port_bnf.ipp b/include/boost/url/rfc/impl/port_bnf.ipp index 02fc22f9..50f83adb 100644 --- a/include/boost/url/rfc/impl/port_bnf.ipp +++ b/include/boost/url/rfc/impl/port_bnf.ipp @@ -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; diff --git a/include/boost/url/rfc/impl/relative_ref_bnf.ipp b/include/boost/url/rfc/impl/relative_ref_bnf.ipp new file mode 100644 index 00000000..6998f1ca --- /dev/null +++ b/include/boost/url/rfc/impl/relative_ref_bnf.ipp @@ -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 +#include +#include +#include +#include + +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 diff --git a/include/boost/url/rfc/impl/uri_bnf.ipp b/include/boost/url/rfc/impl/uri_bnf.ipp index 7b6391a1..a5ad0bba 100644 --- a/include/boost/url/rfc/impl/uri_bnf.ipp +++ b/include/boost/url/rfc/impl/uri_bnf.ipp @@ -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 && diff --git a/include/boost/url/rfc/relative_ref_bnf.hpp b/include/boost/url/rfc/relative_ref_bnf.hpp new file mode 100644 index 00000000..6458e846 --- /dev/null +++ b/include/boost/url/rfc/relative_ref_bnf.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + +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 path; + optional authority; + optional> query; + optional 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 diff --git a/include/boost/url/rfc/uri_bnf.hpp b/include/boost/url/rfc/uri_bnf.hpp index 042fc001..66439e07 100644 --- a/include/boost/url/rfc/uri_bnf.hpp +++ b/include/boost/url/rfc/uri_bnf.hpp @@ -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 diff --git a/include/boost/url/src.hpp b/include/boost/url/src.hpp index 229b407d..2f594934 100644 --- a/include/boost/url/src.hpp +++ b/include/boost/url/src.hpp @@ -33,6 +33,7 @@ in a translation unit of the program. #include #include +#include #include #include #include @@ -46,6 +47,7 @@ in a translation unit of the program. #include #include #include +#include #include #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8fd9b1a2..663896e3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 diff --git a/test/rfc/absolute_uri_bnf.cpp b/test/rfc/absolute_uri_bnf.cpp new file mode 100644 index 00000000..63e98c8b --- /dev/null +++ b/test/rfc/absolute_uri_bnf.cpp @@ -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 + +#include "test_suite.hpp" +#include "test_bnf.hpp" + +#include + +namespace boost { +namespace urls { +namespace rfc { + +class absolute_uri_bnf_test +{ +public: + void + run() + { + using T = absolute_uri_bnf; + + bad(""); + bad(":"); + bad("http://#"); + bad("http://x.y.z/?a=b&c=d&#"); + bad("http://x.y.z/?a=b&c=d&#frag"); + bad("http://x.y.z/#frag"); + + good("http:"); + good("http:x"); + good("http:x/"); + good("http:x/x"); + good("http:x//"); + good("http://"); + good("http://x"); + good("http://x.y.z"); + good("http://x.y.z/"); + good("http://x.y.z/?"); + good("http://x.y.z/?a"); + good("http://x.y.z/?a="); + good("http://x.y.z/?a=b"); + good("http://x.y.z/?a=b&c=d"); + good("http://x.y.z/?a=b&c=d&"); + } +}; + +TEST_SUITE( + absolute_uri_bnf_test, + "boost.url.absolute_uri_bnf"); + +} // rfc +} // urls +} // boost diff --git a/test/rfc/port_bnf.cpp b/test/rfc/port_bnf.cpp index 17518f4f..6231c39f 100644 --- a/test/rfc/port_bnf.cpp +++ b/test/rfc/port_bnf.cpp @@ -40,8 +40,7 @@ public: void run() { - using T = optional< - port_bnf::number_type>; + using T = port_bnf; bad("x"); bad("80x"); diff --git a/test/rfc/uri_bnf.cpp b/test/rfc/uri_bnf.cpp index 6ec0eb35..48e7e8ae 100644 --- a/test/rfc/uri_bnf.cpp +++ b/test/rfc/uri_bnf.cpp @@ -27,8 +27,9 @@ public: { using T = uri_bnf; - bad (""); - bad (":"); + bad(""); + bad(":"); + bad("http://##"); good("http:"); good("http:x"); @@ -45,6 +46,11 @@ public: good("http://x.y.z/?a=b"); good("http://x.y.z/?a=b&c=d"); good("http://x.y.z/?a=b&c=d&"); + good("http://x.y.z/?a=b&c=d&#"); + good("http://x.y.z/?a=b&c=d"); + good("http://x.y.z/?a=b&c=d "); + good("http://x.y.z/?a=b&c=d %23"); + good("http://x.y.z/?a=b&c=d %23%20"); } };