Boost logo

Boost :

From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2021-10-16 15:14:59


On Sat, Oct 16, 2021 at 8:02 AM Phil Endecott via Boost
<boost_at_[hidden]> wrote:
> ...

To all, thanks for all the feedback. I'm not ignoring it, but we
discovered a super duper annoying problem with how the path segments
and query parameters containers represent their respective parts of
the URL, and fixing it is requiring some heroics so I am fixing that
up. To keep things spicy this is the unit test that I am trying to
make work:

    void
    testPathContainer()
    {
        auto const check = [](
            string_view s,
            std::initializer_list<
                string_view> init,
            bool abs)
        {
            url_view u =
                parse_uri_reference(
                    s).value();
            auto const segs =
                u.encoded_segments();
            BOOST_TEST(abs ==
                u.is_path_absolute());
            if(! BOOST_TEST(
                segs.size() == init.size()))
                return;
            BOOST_TEST(equal(
                segs.begin(), segs.end(),
                init.begin(), init.end()));
        };

        auto const abs = [&check](
            string_view s,
            std::initializer_list<
                string_view> init)
        {
            check(s, init, true);
        };

        auto const rel = [&check](
            string_view s,
            std::initializer_list<
                string_view> init)
        {
            check(s, init, false);
        };

        rel("", {});
        rel("./", { "" });
        rel("index.htm", { "index.htm" });
        rel("path/to/file.txt", { "path", "to", "file.txt" });
        rel("//example.com", {} );
        rel("x:y:z", { "y:z" });
        rel("x:y:z/", { "y:z", "" });
        rel("./y:z", { "y:z" });
        rel("./y:z/", { "y:z", "" });

        abs("/", {});
        abs("/./", { "" });
        abs("//example.com/", {} );
        abs("//example.com/./", { "" } );
        abs("/index.htm", { "index.htm" });
        abs("/home/", { "home", "" });
        abs("//x//", { "", "" });
        abs("/.//", { "", "" });
        abs("//x/y", { "y" });
        abs("/././/", { ".", "", "" });
        abs("/.//", { "", "" });
        abs("x:/.//", { "", "" });
    }

So yeah, if you are reading it correctly it means that if you have the
relative-ref "./" and you iterate the path segments you will get just
one element, an empty string { "" }. This might seem counterintuitive
but it is necessary to provide the invariant that the segments
container acts like vector<string>. If you push_back a series of
elements to an empty path, then iterating the container will give you
exactly those strings back. And the implementation preserves the
"absoluteness" of the path. That is, if the path previously started
with a slash then it will continue to start with a slash. If the path
previously did not start with a slash, then the new path will not
start with a slash - modulo the provision that any URL with an
authority can never be relative. There's a new function
set_absolute_path(bool) that adjusts the path accordingly. Making this
all work seamlessly is a chore..

Thanks


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk