diff --git a/headers/os/net/HttpAuthentication.h b/headers/os/net/HttpAuthentication.h index 8726917d70..0d71fc4191 100644 --- a/headers/os/net/HttpAuthentication.h +++ b/headers/os/net/HttpAuthentication.h @@ -1,13 +1,14 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2014 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_HTTP_AUTHENTICATION_H_ #define _B_HTTP_AUTHENTICATION_H_ -#include +#include #include +#include // HTTP authentication method enum BHttpAuthenticationMethod { @@ -89,6 +90,8 @@ private: BHttpAuthenticationQop fDigestQop; BString fAuthorizationString; + + mutable BLocker fLock; }; #endif // _B_HTTP_AUTHENTICATION_H_ diff --git a/headers/os/net/UrlContext.h b/headers/os/net/UrlContext.h index 6a4541f073..eed081397e 100644 --- a/headers/os/net/UrlContext.h +++ b/headers/os/net/UrlContext.h @@ -1,5 +1,5 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2014 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_URL_CONTEXT_H_ @@ -8,15 +8,16 @@ #include #include +#include namespace BPrivate { - template class HashMap; + template class SynchronizedHashMap; class HashString; } -class BUrlContext { +class BUrlContext: public BReferenceable { public: BUrlContext(); ~BUrlContext(); @@ -25,7 +26,7 @@ public: void SetCookieJar( const BNetworkCookieJar& cookieJar); void AddAuthentication(const BUrl& url, - BHttpAuthentication* const authentication); + const BHttpAuthentication& authentication); // Context accessors BNetworkCookieJar& GetCookieJar(); @@ -33,7 +34,7 @@ public: private: BNetworkCookieJar fCookieJar; - typedef BPrivate::HashMap BHttpAuthenticationMap; BHttpAuthenticationMap* fAuthenticationMap; }; diff --git a/headers/os/net/UrlRequest.h b/headers/os/net/UrlRequest.h index 641077f1f2..206b2126ec 100644 --- a/headers/os/net/UrlRequest.h +++ b/headers/os/net/UrlRequest.h @@ -1,5 +1,5 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2014 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_URL_REQUEST_H_ @@ -11,6 +11,7 @@ #include #include #include +#include class BUrlRequest { @@ -52,7 +53,7 @@ protected: const char* format, ...); protected: BUrl fUrl; - BUrlContext* fContext; + BReference fContext; BUrlProtocolListener* fListener; bool fQuit; diff --git a/src/kits/network/libnetapi/HttpAuthentication.cpp b/src/kits/network/libnetapi/HttpAuthentication.cpp index 93db20cceb..32e47dbf5a 100644 --- a/src/kits/network/libnetapi/HttpAuthentication.cpp +++ b/src/kits/network/libnetapi/HttpAuthentication.cpp @@ -9,9 +9,12 @@ #include -#include +#include +#include + +#include + -#include #if DEBUG > 0 #define PRINT(x) printf x #else @@ -56,27 +59,35 @@ BHttpAuthentication::BHttpAuthentication(const BString& username, const BString& void BHttpAuthentication::SetUserName(const BString& username) { + fLock.Lock(); fUserName = username; + fLock.Unlock(); } void BHttpAuthentication::SetPassword(const BString& password) { + fLock.Lock(); fPassword = password; + fLock.Unlock(); } void BHttpAuthentication::SetMethod(BHttpAuthenticationMethod method) { + fLock.Lock(); fAuthenticationMethod = method; + fLock.Unlock(); } status_t BHttpAuthentication::Initialize(const BString& wwwAuthenticate) { + BPrivate::AutoLocker lock(fLock); + fAuthenticationMethod = B_HTTP_AUTHENTICATION_NONE; fDigestQop = B_HTTP_QOP_NONE; @@ -171,6 +182,7 @@ BHttpAuthentication::Initialize(const BString& wwwAuthenticate) const BString& BHttpAuthentication::UserName() const { + BPrivate::AutoLocker lock(fLock); return fUserName; } @@ -178,6 +190,7 @@ BHttpAuthentication::UserName() const const BString& BHttpAuthentication::Password() const { + BPrivate::AutoLocker lock(fLock); return fPassword; } @@ -185,6 +198,7 @@ BHttpAuthentication::Password() const BHttpAuthenticationMethod BHttpAuthentication::Method() const { + BPrivate::AutoLocker lock(fLock); return fAuthenticationMethod; } @@ -192,6 +206,7 @@ BHttpAuthentication::Method() const BString BHttpAuthentication::Authorization(const BUrl& url, const BString& method) const { + BPrivate::AutoLocker lock(fLock); BString authorizationString; switch (fAuthenticationMethod) { diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index 2905c01450..dcb396f286 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -378,15 +378,14 @@ BHttpRequest::_ProtocolLoop() if (authentication->Method() == B_HTTP_AUTHENTICATION_NONE) { // There is no authentication context for this // url yet, so let's create one. - authentication - = new(std::nothrow) BHttpAuthentication(); - if (authentication == NULL) - status = B_NO_MEMORY; - else { - status = authentication->Initialize( - fHeaders["WWW-Authenticate"]); - fContext->AddAuthentication(fUrl, authentication); - } + BHttpAuthentication newAuth; + newAuth.Initialize(fHeaders["WWW-Authenticate"]); + fContext->AddAuthentication(fUrl, newAuth); + + // Get the copy of the authentication we just added. + // That copy is owned by the BUrlContext and won't be + // deleted (unlike the temporary object above) + authentication = &fContext->GetAuthentication(fUrl); } newRequest = false; diff --git a/src/kits/network/libnetapi/UrlContext.cpp b/src/kits/network/libnetapi/UrlContext.cpp index d197849ffa..3818adfb59 100644 --- a/src/kits/network/libnetapi/UrlContext.cpp +++ b/src/kits/network/libnetapi/UrlContext.cpp @@ -52,21 +52,25 @@ BUrlContext::SetCookieJar(const BNetworkCookieJar& cookieJar) void BUrlContext::AddAuthentication(const BUrl& url, - BHttpAuthentication* const authentication) + const BHttpAuthentication& authentication) { BString domain = url.Host(); domain += url.Path(); BPrivate::HashString hostHash(domain.String(), domain.Length()); + fAuthenticationMap->Lock(); + BHttpAuthentication* previous = fAuthenticationMap->Get(hostHash); - // Make sure we don't leak memory by overriding a previous - // authentication for the same domain. - if (authentication != previous) { - fAuthenticationMap->Put(hostHash, authentication); - // replaces the old one, or adds it in case previous == NULL - delete previous; + if (previous) + *previous = authentication; + else { + BHttpAuthentication* copy + = new(std::nothrow) BHttpAuthentication(authentication); + fAuthenticationMap->Put(hostHash, copy); } + + fAuthenticationMap->Unlock(); }