hrev46212 adds 4 changesets to branch 'master' old head: 56434332b1d718ebf610e80a5d6043f3e28dba16 new head: eab89314ceedf030ca7a1d42934357e9110f41f6 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=eab8931+%5E5643433 ---------------------------------------------------------------------------- a5ac24f: 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. d05f9e2: BDateTime: Time_T functions return or take a time_t * They used an unsigned int, which led to overflows when trying to set them to a time before January 1st, 1970 (local time) * Some things use January 1st, 1970, GMT (or UTC) as a reference point. In my timezone this leads to such a negative date. An example is cookie expiration dates which are set to this date to expire them immediately. Spotted by Opera testsuite. * This makes the method unuseable for dates after 2036 (signed 32-bit time_t will overflow then. This gives us just 33 years to switch to a 64-bit time_t. In te meantime, please try using other methods to set the date and time for BDateTime objects if you need to go this far. 185471c: HttpRequest: follow 302 redirects by default. eab8931: NetworkCookie: fix date validity check * January 1st 1970 is a perfectly valid expiration date for a cookie, and shouldn't magically turn it into a session cookie. [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 6 files changed, 52 insertions(+), 13 deletions(-) headers/os/net/Url.h | 1 + headers/os/support/DateTime.h | 4 +-- src/kits/network/libnetapi/HttpRequest.cpp | 10 ++----- src/kits/network/libnetapi/NetworkCookie.cpp | 2 +- src/kits/network/libnetapi/Url.cpp | 36 ++++++++++++++++++++++++ src/kits/support/DateTime.cpp | 12 ++++++-- ############################################################################ Commit: a5ac24f00c38c503652c70acce13c4cb1bfe83c6 URL: http://cgit.haiku-os.org/haiku/commit/?id=a5ac24f Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Thu Oct 10 15:17:21 2013 UTC 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. ---------------------------------------------------------------------------- diff --git a/headers/os/net/Url.h b/headers/os/net/Url.h index 9ce8a48..30e0da4 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 073e3a7..8c26442 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) { ############################################################################ Commit: d05f9e2d3d13931ef7a10bdc065b385dc341746d URL: http://cgit.haiku-os.org/haiku/commit/?id=d05f9e2 Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Thu Oct 10 15:20:19 2013 UTC BDateTime: Time_T functions return or take a time_t * They used an unsigned int, which led to overflows when trying to set them to a time before January 1st, 1970 (local time) * Some things use January 1st, 1970, GMT (or UTC) as a reference point. In my timezone this leads to such a negative date. An example is cookie expiration dates which are set to this date to expire them immediately. Spotted by Opera testsuite. * This makes the method unuseable for dates after 2036 (signed 32-bit time_t will overflow then. This gives us just 33 years to switch to a 64-bit time_t. In te meantime, please try using other methods to set the date and time for BDateTime objects if you need to go this far. ---------------------------------------------------------------------------- diff --git a/headers/os/support/DateTime.h b/headers/os/support/DateTime.h index d9ba24d..17e1c65 100644 --- a/headers/os/support/DateTime.h +++ b/headers/os/support/DateTime.h @@ -189,8 +189,8 @@ public: const BTime& Time() const; void SetTime(const BTime &time); - int32 Time_t() const; - void SetTime_t(uint32 seconds); + time_t Time_t() const; + void SetTime_t(time_t seconds); bool operator!=(const BDateTime& dateTime) const; bool operator==(const BDateTime& dateTime) const; diff --git a/src/kits/support/DateTime.cpp b/src/kits/support/DateTime.cpp index 0d7c197..5778ccf 100644 --- a/src/kits/support/DateTime.cpp +++ b/src/kits/support/DateTime.cpp @@ -1371,7 +1371,7 @@ BDateTime::SetTime(const BTime& time) 1.1.1970 - 00:00:00. If the current date is before 1.1.1970 the function returns -1; */ -int32 +time_t BDateTime::Time_t() const { BDate date(1970, 1, 1); @@ -1392,7 +1392,7 @@ BDateTime::Time_t() const tm_struct.tm_isdst = -1; // return secs_since_jan1_1970 or -1 on error - return int32(mktime(&tm_struct)); + return mktime(&tm_struct); } @@ -1401,8 +1401,14 @@ BDateTime::Time_t() const 1.1.1970 - 00:00:00. */ void -BDateTime::SetTime_t(uint32 seconds) +BDateTime::SetTime_t(time_t seconds) { + time_t timePart = seconds % kSecondsPerDay; + if (timePart < 0) { + timePart += kSecondsPerDay; + seconds -= kSecondsPerDay; + } + BTime time; time.AddSeconds(seconds % kSecondsPerDay); fTime.SetTime(time); ############################################################################ Commit: 185471c84479a23ff1cd2eed751002c986287524 URL: http://cgit.haiku-os.org/haiku/commit/?id=185471c Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Thu Oct 10 15:25:18 2013 UTC HttpRequest: follow 302 redirects by default. ---------------------------------------------------------------------------- diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index a49db2f..0c2a91d 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -40,7 +40,8 @@ BHttpRequest::BHttpRequest(const BUrl& url, BUrlResult& result, bool ssl, fRequestStatus(kRequestInitialState), fOptHeaders(NULL), fOptInputData(NULL), - fOptInputDataSize(-1) + fOptInputDataSize(-1), + fOptFollowLocation(true) { _ResetOptions(); if (ssl) @@ -299,12 +300,7 @@ BHttpRequest::_ProtocolLoop() if (fResult.StatusCode() == B_HTTP_STATUS_MOVED_PERMANENTLY) { BString locationUrl = fHeaders["Location"]; - // Absolute path - if (locationUrl[0] == '/') - fUrl.SetPath(locationUrl); - // URI - else - fUrl.SetUrlString(locationUrl); + fUrl.Redirect(locationUrl); if (--maxRedirs > 0) { newRequest = true; ############################################################################ Revision: hrev46212 Commit: eab89314ceedf030ca7a1d42934357e9110f41f6 URL: http://cgit.haiku-os.org/haiku/commit/?id=eab8931 Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Thu Oct 10 15:30:39 2013 UTC NetworkCookie: fix date validity check * January 1st 1970 is a perfectly valid expiration date for a cookie, and shouldn't magically turn it into a session cookie. ---------------------------------------------------------------------------- diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp b/src/kits/network/libnetapi/NetworkCookie.cpp index 253e624..4b5c4fb 100644 --- a/src/kits/network/libnetapi/NetworkCookie.cpp +++ b/src/kits/network/libnetapi/NetworkCookie.cpp @@ -232,7 +232,7 @@ BNetworkCookie::SetExpirationDate(time_t expireDate) BNetworkCookie& BNetworkCookie::SetExpirationDate(BDateTime& expireDate) { - if (expireDate.Time_t() <= 0) { + if (!expireDate.IsValid()) { fExpiration.SetTime_t(0); fSessionCookie = true; fExpirationStringValid = false;