diff options
Diffstat (limited to 'netwerk/protocol/http/nsHttpAuthCache.h')
-rw-r--r-- | netwerk/protocol/http/nsHttpAuthCache.h | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/netwerk/protocol/http/nsHttpAuthCache.h b/netwerk/protocol/http/nsHttpAuthCache.h new file mode 100644 index 0000000000..3834c08178 --- /dev/null +++ b/netwerk/protocol/http/nsHttpAuthCache.h @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsHttpAuthCache_h__ +#define nsHttpAuthCache_h__ + +#include "nsError.h" +#include "nsTArray.h" +#include "nsClassHashtable.h" +#include "nsCOMPtr.h" +#include "nsHashKeys.h" +#include "nsStringFwd.h" +#include "nsIObserver.h" + +namespace mozilla { + +class OriginAttributesPattern; + +namespace net { + +struct nsHttpAuthPath { + struct nsHttpAuthPath* mNext; + char mPath[1]; +}; + +//----------------------------------------------------------------------------- +// nsHttpAuthIdentity +//----------------------------------------------------------------------------- + +class nsHttpAuthIdentity { + public: + nsHttpAuthIdentity() : mUser(nullptr), mPass(nullptr), mDomain(nullptr) {} + nsHttpAuthIdentity(const char16_t* domain, const char16_t* user, + const char16_t* password) + : mUser(nullptr), mPass{nullptr}, mDomain{nullptr} { + DebugOnly<nsresult> rv = Set(domain, user, password); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + } + ~nsHttpAuthIdentity() { Clear(); } + + const char16_t* Domain() const { return mDomain; } + const char16_t* User() const { return mUser; } + const char16_t* Password() const { return mPass; } + + [[nodiscard]] nsresult Set(const char16_t* domain, const char16_t* user, + const char16_t* password); + [[nodiscard]] nsresult Set(const nsHttpAuthIdentity& other) { + return Set(other.mDomain, other.mUser, other.mPass); + } + void Clear(); + + bool Equals(const nsHttpAuthIdentity& other) const; + bool IsEmpty() const { return !mUser; } + + private: + // allocated as one contiguous blob, starting at mUser. + char16_t* mUser; + char16_t* mPass; + char16_t* mDomain; +}; + +//----------------------------------------------------------------------------- +// nsHttpAuthEntry +//----------------------------------------------------------------------------- + +class nsHttpAuthEntry { + public: + const char* Realm() const { return mRealm; } + const char* Creds() const { return mCreds; } + const char* Challenge() const { return mChallenge; } + const char16_t* Domain() const { return mIdent.Domain(); } + const char16_t* User() const { return mIdent.User(); } + const char16_t* Pass() const { return mIdent.Password(); } + nsHttpAuthPath* RootPath() { return mRoot; } + + const nsHttpAuthIdentity& Identity() const { return mIdent; } + + [[nodiscard]] nsresult AddPath(const char* aPath); + + nsCOMPtr<nsISupports> mMetaData; + + private: + nsHttpAuthEntry(const char* path, const char* realm, const char* creds, + const char* challenge, const nsHttpAuthIdentity* ident, + nsISupports* metadata) + : mRoot(nullptr), + mTail(nullptr), + mRealm(nullptr), + mCreds{nullptr}, + mChallenge{nullptr} { + DebugOnly<nsresult> rv = + Set(path, realm, creds, challenge, ident, metadata); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + } + ~nsHttpAuthEntry(); + + [[nodiscard]] nsresult Set(const char* path, const char* realm, + const char* creds, const char* challenge, + const nsHttpAuthIdentity* ident, + nsISupports* metadata); + + nsHttpAuthIdentity mIdent; + + nsHttpAuthPath* mRoot; // root pointer + nsHttpAuthPath* mTail; // tail pointer + + // allocated together in one blob, starting with mRealm. + char* mRealm; + char* mCreds; + char* mChallenge; + + friend class nsHttpAuthNode; + friend class nsHttpAuthCache; + friend class mozilla::DefaultDelete<nsHttpAuthEntry>; // needs to call the + // destructor +}; + +//----------------------------------------------------------------------------- +// nsHttpAuthNode +//----------------------------------------------------------------------------- + +class nsHttpAuthNode { + private: + using EntryList = nsTArray<UniquePtr<nsHttpAuthEntry>>; + + nsHttpAuthNode(); + ~nsHttpAuthNode(); + + // path can be null, in which case we'll search for an entry + // with a null path. + nsHttpAuthEntry* LookupEntryByPath(const char* path); + + // realm must not be null + nsHttpAuthEntry* LookupEntryByRealm(const char* realm); + EntryList::const_iterator LookupEntryItrByRealm(const char* realm) const; + + // if a matching entry is found, then credentials will be changed. + [[nodiscard]] nsresult SetAuthEntry(const char* path, const char* realm, + const char* credentials, + const char* challenge, + const nsHttpAuthIdentity* ident, + nsISupports* metadata); + + void ClearAuthEntry(const char* realm); + + uint32_t EntryCount() { return mList.Length(); } + + private: + EntryList mList; + + friend class nsHttpAuthCache; + friend class mozilla::DefaultDelete<nsHttpAuthNode>; // needs to call the + // destructor +}; + +//----------------------------------------------------------------------------- +// nsHttpAuthCache +// (holds a hash table from host:port to nsHttpAuthNode) +//----------------------------------------------------------------------------- + +class nsHttpAuthCache { + public: + nsHttpAuthCache(); + ~nsHttpAuthCache(); + + // |scheme|, |host|, and |port| are required + // |path| can be null + // |entry| is either null or a weak reference + [[nodiscard]] nsresult GetAuthEntryForPath(const char* scheme, + const char* host, int32_t port, + const char* path, + nsACString const& originSuffix, + nsHttpAuthEntry** entry); + + // |scheme|, |host|, and |port| are required + // |realm| must not be null + // |entry| is either null or a weak reference + [[nodiscard]] nsresult GetAuthEntryForDomain(const char* scheme, + const char* host, int32_t port, + const char* realm, + nsACString const& originSuffix, + nsHttpAuthEntry** entry); + + // |scheme|, |host|, and |port| are required + // |path| can be null + // |realm| must not be null + // if |credentials|, |user|, |pass|, and |challenge| are each + // null, then the entry is deleted. + [[nodiscard]] nsresult SetAuthEntry( + const char* scheme, const char* host, int32_t port, const char* directory, + const char* realm, const char* credentials, const char* challenge, + nsACString const& originSuffix, const nsHttpAuthIdentity* ident, + nsISupports* metadata); + + void ClearAuthEntry(const char* scheme, const char* host, int32_t port, + const char* realm, nsACString const& originSuffix); + + // expire all existing auth list entries including proxy auths. + void ClearAll(); + + // For testing only. + void CollectKeys(nsTArray<nsCString>& aValue); + + private: + nsHttpAuthNode* LookupAuthNode(const char* scheme, const char* host, + int32_t port, nsACString const& originSuffix, + nsCString& key); + + class OriginClearObserver : public nsIObserver { + virtual ~OriginClearObserver() = default; + + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + explicit OriginClearObserver(nsHttpAuthCache* aOwner) : mOwner(aOwner) {} + nsHttpAuthCache* mOwner; + }; + + void ClearOriginData(OriginAttributesPattern const& pattern); + + private: + using AuthNodeTable = nsClassHashtable<nsCStringHashKey, nsHttpAuthNode>; + AuthNodeTable mDB; // "host:port" --> nsHttpAuthNode + RefPtr<OriginClearObserver> mObserver; +}; + +} // namespace net +} // namespace mozilla + +#endif // nsHttpAuthCache_h__ |