diff --git a/headers/os/net/Url.h b/headers/os/net/Url.h index 9ce8a48a03..30e0da4dcc 100644 --- a/headers/os/net/Url.h +++ b/headers/os/net/Url.h @@ -29,6 +29,7 @@ public: BUrl& SetPath(const BString& path); BUrl& SetRequest(const BString& request); BUrl& SetFragment(const BString& fragment); + void Redirect(const BString& newLocation); // URL fields access const BString& UrlString() const; diff --git a/src/kits/network/libnetapi/Url.cpp b/src/kits/network/libnetapi/Url.cpp index 073e3a75db..8c2644256e 100644 --- a/src/kits/network/libnetapi/Url.cpp +++ b/src/kits/network/libnetapi/Url.cpp @@ -92,6 +92,42 @@ BUrl::~BUrl() // #pragma mark URL fields modifiers +void +BUrl::Redirect(const BString& newLocation) +{ + BString oldUrl = UrlString(); + BUrl newUrl(newLocation); + + if(newUrl.Protocol() != "") + { + *this = newUrl; + } else { + // the new location seems to be relative to ours. + const BString& newPath = newUrl.Path(); + + if(newPath[0] == '/') { + // new path is absolute, just adopt it + SetPath(newPath); + } else { + // Path is relative, append it to current one + // TODO resolve '..' + BString path = Path(); + // Remove last part of path (the file, if any) so we get the + // "current directory" + path.Truncate(path.FindLast('/') + 1); + path += newPath; + SetPath(path); + } + + // Also copy request and fragment from the other URL + if(newUrl.Request() != "") + SetRequest(newUrl.Request()); + if(newUrl.Fragment() != "") + SetRequest(newUrl.Fragment()); + } +} + + BUrl& BUrl::SetUrlString(const BString& url) {