util/UriUtil: New uri_squash_dot_segments.
This commit is contained in:
parent
cf554d306d
commit
49ed9dae34
@ -29,10 +29,13 @@
|
||||
|
||||
#include "UriUtil.hxx"
|
||||
#include "ASCII.hxx"
|
||||
#include "SplitString.hxx"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
static const char *
|
||||
verify_uri_segment(const char *p) noexcept
|
||||
{
|
||||
@ -108,3 +111,37 @@ uri_remove_auth(const char *uri) noexcept
|
||||
result.erase(auth - uri, at + 1 - auth);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string
|
||||
uri_squash_dot_segments(const char *uri) noexcept
|
||||
{
|
||||
std::forward_list<std::string_view> path = SplitString(std::string_view(uri), '/');
|
||||
path.remove_if([](const std::string_view &seg) { return seg == "."; });
|
||||
path.reverse();
|
||||
|
||||
std::string result;
|
||||
|
||||
int segskips = 0;
|
||||
auto it = path.begin();
|
||||
while (it != path.end()) {
|
||||
if (*it == "..") {
|
||||
segskips++;
|
||||
it++;
|
||||
continue;
|
||||
} else if (segskips != 0) {
|
||||
segskips--;
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
result.insert(0, *it);
|
||||
|
||||
if (it != path.begin()) {
|
||||
result.insert(it->length(), "/");
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -56,4 +56,12 @@ gcc_pure
|
||||
std::string
|
||||
uri_remove_auth(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Remove dot segments in the URI. For example, uri_squash_dot_segments
|
||||
* ("foo/bar/.././")=="foo/".
|
||||
*/
|
||||
gcc_pure
|
||||
std::string
|
||||
uri_squash_dot_segments(const char *uri) noexcept;
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user