uri: fix empty query/fragment offsets
This commit is contained in:
parent
2ee2806979
commit
ce2f05ede2
40
test/uri.cpp
40
test/uri.cpp
@ -376,6 +376,45 @@ test_validity (cruft::TAP::logger &tap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void
|
||||||
|
test_pqf (cruft::TAP::logger &tap)
|
||||||
|
{
|
||||||
|
static constexpr struct {
|
||||||
|
char const *uri;
|
||||||
|
char const *pq;
|
||||||
|
char const *pqf;
|
||||||
|
} TESTS[] = {
|
||||||
|
{
|
||||||
|
"http://example.com/foo?bar#qux",
|
||||||
|
"/foo?bar",
|
||||||
|
"/foo?bar#qux"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://example.com/foo",
|
||||||
|
"/foo",
|
||||||
|
"/foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://example.com/foo?#qux",
|
||||||
|
"/foo?",
|
||||||
|
"/foo?#qux"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://example.com/foo?bar#",
|
||||||
|
"/foo?bar",
|
||||||
|
"/foo?bar#"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const &t: TESTS) {
|
||||||
|
cruft::uri const obj (t.uri);
|
||||||
|
tap.expect_eq (t.pq, obj.pq (), "pq: {}", t.uri);
|
||||||
|
tap.expect_eq (t.pqf, obj.pqf (), "pqf: {}", t.uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
@ -387,6 +426,7 @@ main (void)
|
|||||||
test_normalise (tap);
|
test_normalise (tap);
|
||||||
test_rfc_resolve (tap);
|
test_rfc_resolve (tap);
|
||||||
test_resolve (tap);
|
test_resolve (tap);
|
||||||
|
test_pqf (tap);
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
||||||
|
13
uri.cpp
13
uri.cpp
@ -31,9 +31,20 @@ cruft::uri::uri (std::string &&_value):
|
|||||||
|
|
||||||
parse ();
|
parse ();
|
||||||
|
|
||||||
|
// Ensure the offsets are well-ordered.
|
||||||
|
//
|
||||||
|
// We want the QUERY offsets to come after the PATH offsets even if there
|
||||||
|
// is no QUERY data (or at least be placed coincident with the PATH
|
||||||
|
// offsets).
|
||||||
for (int i = 1; i < NUM_COMPONENTS; ++i) {
|
for (int i = 1; i < NUM_COMPONENTS; ++i) {
|
||||||
if (m_offsets[i].second != m_offsets[i].first)
|
// We very specifically do not want to move any offset that has a
|
||||||
|
// non-zero (ie, found) offset.
|
||||||
|
//
|
||||||
|
// If we do, this prevents us from computing `pqf` and retaining a
|
||||||
|
// trailing "?" for an empty query.
|
||||||
|
if (m_offsets[i].second or m_offsets[i].first)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_offsets[i] = {
|
m_offsets[i] = {
|
||||||
m_offsets[i - 1].second,
|
m_offsets[i - 1].second,
|
||||||
m_offsets[i - 1].second
|
m_offsets[i - 1].second
|
||||||
|
5
uri.hpp
5
uri.hpp
@ -99,7 +99,9 @@ namespace cruft {
|
|||||||
std::string_view heirarchical (void) const&; //{ return { user ().begin (), path ().end () }; }
|
std::string_view heirarchical (void) const&; //{ return { user ().begin (), path ().end () }; }
|
||||||
std::string_view authority (void) const&; //{ return { user ().begin (), port ().end () }; }
|
std::string_view authority (void) const&; //{ return { user ().begin (), port ().end () }; }
|
||||||
|
|
||||||
std::string_view pq (void) const&
|
/// Returns a view over the path and query components
|
||||||
|
std::string_view
|
||||||
|
pq (void) const&
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
m_value.data () + m_offsets[PATH].first,
|
m_value.data () + m_offsets[PATH].first,
|
||||||
@ -107,6 +109,7 @@ namespace cruft {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a view over the path, query, and fragment components
|
||||||
std::string_view
|
std::string_view
|
||||||
pqf (void) const& {
|
pqf (void) const& {
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user