/* -*- 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 {
//-----------------------------------------------------------------------------
// nsHttpAuthIdentity
//-----------------------------------------------------------------------------
class nsHttpAuthIdentity {
public:
nsHttpAuthIdentity() =
default;
nsHttpAuthIdentity(
const nsAString& domain,
const nsAString& user,
const nsAString& password)
: mUser(user), mPass(password), mDomain(domain) {}
~nsHttpAuthIdentity() { Clear(); }
const nsString& Domain()
const {
return mDomain; }
const nsString& User()
const {
return mUser; }
const nsString& Password()
const {
return mPass; }
void Clear();
bool Equals(
const nsHttpAuthIdentity& ident)
const;
bool IsEmpty()
const {
return mUser.IsEmpty() && mPass.IsEmpty() && mDomain.IsEmpty();
}
private:
nsString mUser;
nsString mPass;
nsString mDomain;
};
//-----------------------------------------------------------------------------
// nsHttpAuthEntry
//-----------------------------------------------------------------------------
class nsHttpAuthEntry {
public:
const nsCString& Realm()
const {
return mRealm; }
const nsCString& Creds()
const {
return mCreds; }
const nsCString& Challenge()
const {
return mChallenge; }
const nsString& Domain()
const {
return mIdent.Domain(); }
const nsString& User()
const {
return mIdent.User(); }
const nsString& Pass()
const {
return mIdent.Password(); }
const nsHttpAuthIdentity& Identity()
const {
return mIdent; }
[[nodiscard]] nsresult AddPath(
const nsACString& aPath);
nsCOMPtr<nsISupports> mMetaData;
private:
nsHttpAuthEntry(
const nsACString& path,
const nsACString& realm,
const nsACString& creds,
const nsACString& challenge,
const nsHttpAuthIdentity* ident, nsISupports* metadata) {
DebugOnly<nsresult> rv =
Set(path, realm, creds, challenge, ident, metadata);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
~nsHttpAuthEntry() =
default;
[[nodiscard]] nsresult Set(
const nsACString& path,
const nsACString& realm,
const nsACString& creds,
const nsACString& challenge,
const nsHttpAuthIdentity* ident,
nsISupports* metadata);
nsHttpAuthIdentity mIdent;
nsTArray<nsCString> mPaths;
nsCString mRealm;
nsCString mCreds;
nsCString 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 nsACString& path);
// realm must not be null
nsHttpAuthEntry* LookupEntryByRealm(
const nsACString& realm);
EntryList::const_iterator LookupEntryItrByRealm(
const nsACString& realm)
const;
// if a matching entry is found, then credentials will be changed.
[[nodiscard]] nsresult SetAuthEntry(
const nsACString& path,
const nsACString& realm,
const nsACString& creds,
const nsACString& challenge,
const nsHttpAuthIdentity* ident,
nsISupports* metadata);
void ClearAuthEntry(
const nsACString& 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 nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& 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 nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& 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 nsACString& scheme,
const nsACString& host, int32_t port,
const nsACString& path,
const nsACString& realm,
const nsACString& creds,
const nsACString& challenge, nsACString
const& originSuffix,
const nsHttpAuthIdentity* ident, nsISupports* metadata);
void ClearAuthEntry(
const nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& 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 nsACString& scheme,
const nsACString& 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__