From a5ac24f00c38c503652c70acce13c4cb1bfe83c6 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Thu, 10 Oct 2013 17:17:21 +0200 Subject: [PATCH] BUrl: add a Redirect method * This takes a relative path as a parameter, and modifies the object to point to the given location. * '..' is not handled yet, and will be sent as-is to the server. * Makes it possible to follow more types of 302 redirects In particular, I can now run the tests from Opera's testsuite (testsuite.opera.com), which shows I have more work to do on cookie handling. --- headers/os/net/Url.h | 1 + src/kits/network/libnetapi/Url.cpp | 36 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) 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) {