LCOV - code coverage report
Current view: top level - netwerk/protocol/http - nsHttpAuthCache.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 38 276 13.8 %
Date: 2017-07-14 16:53:18 Functions: 8 33 24.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : // HttpLog.h should generally be included first
       7             : #include "HttpLog.h"
       8             : 
       9             : #include "nsHttpAuthCache.h"
      10             : 
      11             : #include <stdlib.h>
      12             : 
      13             : #include "mozilla/Attributes.h"
      14             : #include "nsString.h"
      15             : #include "nsCRT.h"
      16             : #include "nsIObserverService.h"
      17             : #include "mozilla/Services.h"
      18             : #include "mozilla/DebugOnly.h"
      19             : #include "nsNetUtil.h"
      20             : 
      21             : namespace mozilla {
      22             : namespace net {
      23             : 
      24             : static inline void
      25           6 : GetAuthKey(const char *scheme, const char *host, int32_t port, nsACString const &originSuffix, nsCString &key)
      26             : {
      27           6 :     key.Truncate();
      28           6 :     key.Append(originSuffix);
      29           6 :     key.Append(':');
      30           6 :     key.Append(scheme);
      31           6 :     key.AppendLiteral("://");
      32           6 :     key.Append(host);
      33           6 :     key.Append(':');
      34           6 :     key.AppendInt(port);
      35           6 : }
      36             : 
      37             : // return true if the two strings are equal or both empty.  an empty string
      38             : // is either null or zero length.
      39             : static bool
      40           0 : StrEquivalent(const char16_t *a, const char16_t *b)
      41             : {
      42             :     static const char16_t emptyStr[] = {0};
      43             : 
      44           0 :     if (!a)
      45           0 :         a = emptyStr;
      46           0 :     if (!b)
      47           0 :         b = emptyStr;
      48             : 
      49           0 :     return nsCRT::strcmp(a, b) == 0;
      50             : }
      51             : 
      52             : //-----------------------------------------------------------------------------
      53             : // nsHttpAuthCache <public>
      54             : //-----------------------------------------------------------------------------
      55             : 
      56           4 : nsHttpAuthCache::nsHttpAuthCache()
      57             :     : mDB(nullptr)
      58           8 :     , mObserver(new OriginClearObserver(this))
      59             : {
      60           8 :     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
      61           4 :     if (obsSvc) {
      62           4 :         obsSvc->AddObserver(mObserver, "clear-origin-attributes-data", false);
      63             :     }
      64           4 : }
      65             : 
      66           0 : nsHttpAuthCache::~nsHttpAuthCache()
      67             : {
      68           0 :     if (mDB) {
      69           0 :         DebugOnly<nsresult> rv = ClearAll();
      70           0 :         MOZ_ASSERT(NS_SUCCEEDED(rv));
      71             :     }
      72           0 :     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
      73           0 :     if (obsSvc) {
      74           0 :         obsSvc->RemoveObserver(mObserver, "clear-origin-attributes-data");
      75           0 :         mObserver->mOwner = nullptr;
      76             :     }
      77           0 : }
      78             : 
      79             : nsresult
      80           4 : nsHttpAuthCache::Init()
      81             : {
      82           4 :     NS_ENSURE_TRUE(!mDB, NS_ERROR_ALREADY_INITIALIZED);
      83             : 
      84           4 :     LOG(("nsHttpAuthCache::Init\n"));
      85             : 
      86           4 :     mDB = PL_NewHashTable(128, (PLHashFunction) PL_HashString,
      87             :                                (PLHashComparator) PL_CompareStrings,
      88             :                                (PLHashComparator) 0, &gHashAllocOps, this);
      89           4 :     if (!mDB)
      90           0 :         return NS_ERROR_OUT_OF_MEMORY;
      91             : 
      92           4 :     return NS_OK;
      93             : }
      94             : 
      95             : nsresult
      96           6 : nsHttpAuthCache::GetAuthEntryForPath(const char *scheme,
      97             :                                      const char *host,
      98             :                                      int32_t     port,
      99             :                                      const char *path,
     100             :                                      nsACString const &originSuffix,
     101             :                                      nsHttpAuthEntry **entry)
     102             : {
     103           6 :     LOG(("nsHttpAuthCache::GetAuthEntryForPath [key=%s://%s:%d path=%s]\n",
     104             :         scheme, host, port, path));
     105             : 
     106          12 :     nsAutoCString key;
     107           6 :     nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, originSuffix, key);
     108           6 :     if (!node)
     109           6 :         return NS_ERROR_NOT_AVAILABLE;
     110             : 
     111           0 :     *entry = node->LookupEntryByPath(path);
     112           0 :     return *entry ? NS_OK : NS_ERROR_NOT_AVAILABLE;
     113             : }
     114             : 
     115             : nsresult
     116           0 : nsHttpAuthCache::GetAuthEntryForDomain(const char *scheme,
     117             :                                        const char *host,
     118             :                                        int32_t     port,
     119             :                                        const char *realm,
     120             :                                        nsACString const &originSuffix,
     121             :                                        nsHttpAuthEntry **entry)
     122             : 
     123             : {
     124           0 :     LOG(("nsHttpAuthCache::GetAuthEntryForDomain [key=%s://%s:%d realm=%s]\n",
     125             :         scheme, host, port, realm));
     126             : 
     127           0 :     nsAutoCString key;
     128           0 :     nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, originSuffix, key);
     129           0 :     if (!node)
     130           0 :         return NS_ERROR_NOT_AVAILABLE;
     131             : 
     132           0 :     *entry = node->LookupEntryByRealm(realm);
     133           0 :     return *entry ? NS_OK : NS_ERROR_NOT_AVAILABLE;
     134             : }
     135             : 
     136             : nsresult
     137           0 : nsHttpAuthCache::SetAuthEntry(const char *scheme,
     138             :                               const char *host,
     139             :                               int32_t     port,
     140             :                               const char *path,
     141             :                               const char *realm,
     142             :                               const char *creds,
     143             :                               const char *challenge,
     144             :                               nsACString const &originSuffix,
     145             :                               const nsHttpAuthIdentity *ident,
     146             :                               nsISupports *metadata)
     147             : {
     148             :     nsresult rv;
     149             : 
     150           0 :     LOG(("nsHttpAuthCache::SetAuthEntry [key=%s://%s:%d realm=%s path=%s metadata=%p]\n",
     151             :         scheme, host, port, realm, path, metadata));
     152             : 
     153           0 :     if (!mDB) {
     154           0 :         rv = Init();
     155           0 :         if (NS_FAILED(rv)) return rv;
     156             :     }
     157             : 
     158           0 :     nsAutoCString key;
     159           0 :     nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, originSuffix, key);
     160             : 
     161           0 :     if (!node) {
     162             :         // create a new entry node and set the given entry
     163           0 :         node = new nsHttpAuthNode();
     164           0 :         if (!node)
     165           0 :             return NS_ERROR_OUT_OF_MEMORY;
     166           0 :         rv = node->SetAuthEntry(path, realm, creds, challenge, ident, metadata);
     167           0 :         if (NS_FAILED(rv))
     168           0 :             delete node;
     169             :         else
     170           0 :             PL_HashTableAdd(mDB, strdup(key.get()), node);
     171           0 :         return rv;
     172             :     }
     173             : 
     174           0 :     return node->SetAuthEntry(path, realm, creds, challenge, ident, metadata);
     175             : }
     176             : 
     177             : void
     178           0 : nsHttpAuthCache::ClearAuthEntry(const char *scheme,
     179             :                                 const char *host,
     180             :                                 int32_t     port,
     181             :                                 const char *realm,
     182             :                                 nsACString const &originSuffix)
     183             : {
     184           0 :     if (!mDB)
     185           0 :         return;
     186             : 
     187           0 :     nsAutoCString key;
     188           0 :     GetAuthKey(scheme, host, port, originSuffix, key);
     189           0 :     PL_HashTableRemove(mDB, key.get());
     190             : }
     191             : 
     192             : nsresult
     193           0 : nsHttpAuthCache::ClearAll()
     194             : {
     195           0 :     LOG(("nsHttpAuthCache::ClearAll\n"));
     196             : 
     197           0 :     if (mDB) {
     198           0 :         PL_HashTableDestroy(mDB);
     199           0 :         mDB = 0;
     200             :     }
     201           0 :     return NS_OK;
     202             : }
     203             : 
     204             : //-----------------------------------------------------------------------------
     205             : // nsHttpAuthCache <private>
     206             : //-----------------------------------------------------------------------------
     207             : 
     208             : nsHttpAuthNode *
     209           6 : nsHttpAuthCache::LookupAuthNode(const char *scheme,
     210             :                                 const char *host,
     211             :                                 int32_t     port,
     212             :                                 nsACString const &originSuffix,
     213             :                                 nsCString  &key)
     214             : {
     215           6 :     if (!mDB)
     216           0 :         return nullptr;
     217             : 
     218           6 :     GetAuthKey(scheme, host, port, originSuffix, key);
     219             : 
     220           6 :     return (nsHttpAuthNode *) PL_HashTableLookup(mDB, key.get());
     221             : }
     222             : 
     223             : void *
     224           8 : nsHttpAuthCache::AllocTable(void *self, size_t size)
     225             : {
     226           8 :     return malloc(size);
     227             : }
     228             : 
     229             : void
     230           0 : nsHttpAuthCache::FreeTable(void *self, void *item)
     231             : {
     232           0 :     free(item);
     233           0 : }
     234             : 
     235             : PLHashEntry *
     236           0 : nsHttpAuthCache::AllocEntry(void *self, const void *key)
     237             : {
     238           0 :     return (PLHashEntry *) malloc(sizeof(PLHashEntry));
     239             : }
     240             : 
     241             : void
     242           0 : nsHttpAuthCache::FreeEntry(void *self, PLHashEntry *he, unsigned flag)
     243             : {
     244           0 :     if (flag == HT_FREE_VALUE) {
     245             :         // this would only happen if PL_HashTableAdd were to replace an
     246             :         // existing entry in the hash table, but we _always_ do a lookup
     247             :         // before adding a new entry to avoid this case.
     248           0 :         NS_NOTREACHED("should never happen");
     249             :     }
     250           0 :     else if (flag == HT_FREE_ENTRY) {
     251             :         // three wonderful flavors of freeing memory ;-)
     252           0 :         delete (nsHttpAuthNode *) he->value;
     253           0 :         free((char *) he->key);
     254           0 :         free(he);
     255             :     }
     256           0 : }
     257             : 
     258             : PLHashAllocOps nsHttpAuthCache::gHashAllocOps =
     259             : {
     260             :     nsHttpAuthCache::AllocTable,
     261             :     nsHttpAuthCache::FreeTable,
     262             :     nsHttpAuthCache::AllocEntry,
     263             :     nsHttpAuthCache::FreeEntry
     264             : };
     265             : 
     266           8 : NS_IMPL_ISUPPORTS(nsHttpAuthCache::OriginClearObserver, nsIObserver)
     267             : 
     268             : NS_IMETHODIMP
     269           0 : nsHttpAuthCache::OriginClearObserver::Observe(nsISupports *subject,
     270             :                                               const char *      topic,
     271             :                                               const char16_t * data_unicode)
     272             : {
     273           0 :     NS_ENSURE_TRUE(mOwner, NS_ERROR_NOT_AVAILABLE);
     274             : 
     275           0 :     OriginAttributesPattern pattern;
     276           0 :     if (!pattern.Init(nsDependentString(data_unicode))) {
     277           0 :         NS_ERROR("Cannot parse origin attributes pattern");
     278           0 :         return NS_ERROR_FAILURE;
     279             :     }
     280             : 
     281           0 :     mOwner->ClearOriginData(pattern);
     282           0 :     return NS_OK;
     283             : }
     284             : 
     285             : static int
     286           0 : RemoveEntriesForPattern(PLHashEntry *entry, int32_t number, void *arg)
     287             : {
     288           0 :     nsDependentCString key(static_cast<const char*>(entry->key));
     289             : 
     290             :     // Extract the origin attributes suffix from the key.
     291           0 :     int32_t colon = key.Find(NS_LITERAL_CSTRING(":"));
     292           0 :     MOZ_ASSERT(colon != kNotFound);
     293           0 :     nsDependentCSubstring oaSuffix;
     294           0 :     oaSuffix.Rebind(key.BeginReading(), colon);
     295             : 
     296             :     // Build the OriginAttributes object of it...
     297           0 :     OriginAttributes oa;
     298           0 :     DebugOnly<bool> rv = oa.PopulateFromSuffix(oaSuffix);
     299           0 :     MOZ_ASSERT(rv);
     300             : 
     301             :     // ...and match it against the given pattern.
     302           0 :     OriginAttributesPattern const *pattern = static_cast<OriginAttributesPattern const*>(arg);
     303           0 :     if (pattern->Matches(oa)) {
     304           0 :         return HT_ENUMERATE_NEXT | HT_ENUMERATE_REMOVE;
     305             :     }
     306           0 :     return HT_ENUMERATE_NEXT;
     307             : }
     308             : 
     309             : void
     310           0 : nsHttpAuthCache::ClearOriginData(OriginAttributesPattern const &pattern)
     311             : {
     312           0 :     if (!mDB) {
     313           0 :         return;
     314             :     }
     315           0 :     PL_HashTableEnumerateEntries(mDB, RemoveEntriesForPattern, (void*)&pattern);
     316             : }
     317             : 
     318             : //-----------------------------------------------------------------------------
     319             : // nsHttpAuthIdentity
     320             : //-----------------------------------------------------------------------------
     321             : 
     322             : nsresult
     323           0 : nsHttpAuthIdentity::Set(const char16_t *domain,
     324             :                         const char16_t *user,
     325             :                         const char16_t *pass)
     326             : {
     327             :     char16_t *newUser, *newPass, *newDomain;
     328             : 
     329           0 :     int domainLen = domain ? NS_strlen(domain) : 0;
     330           0 :     int userLen   = user   ? NS_strlen(user)   : 0;
     331           0 :     int passLen   = pass   ? NS_strlen(pass)   : 0;
     332             : 
     333           0 :     int len = userLen + 1 + passLen + 1 + domainLen + 1;
     334           0 :     newUser = (char16_t *) malloc(len * sizeof(char16_t));
     335           0 :     if (!newUser)
     336           0 :         return NS_ERROR_OUT_OF_MEMORY;
     337             : 
     338           0 :     if (user)
     339           0 :         memcpy(newUser, user, userLen * sizeof(char16_t));
     340           0 :     newUser[userLen] = 0;
     341             : 
     342           0 :     newPass = &newUser[userLen + 1];
     343           0 :     if (pass)
     344           0 :         memcpy(newPass, pass, passLen * sizeof(char16_t));
     345           0 :     newPass[passLen] = 0;
     346             : 
     347           0 :     newDomain = &newPass[passLen + 1];
     348           0 :     if (domain)
     349           0 :         memcpy(newDomain, domain, domainLen * sizeof(char16_t));
     350           0 :     newDomain[domainLen] = 0;
     351             : 
     352             :     // wait until the end to clear member vars in case input params
     353             :     // reference our members!
     354           0 :     if (mUser)
     355           0 :         free(mUser);
     356           0 :     mUser = newUser;
     357           0 :     mPass = newPass;
     358           0 :     mDomain = newDomain;
     359           0 :     return NS_OK;
     360             : }
     361             : 
     362             : void
     363          12 : nsHttpAuthIdentity::Clear()
     364             : {
     365          12 :     if (mUser) {
     366           0 :         free(mUser);
     367           0 :         mUser = nullptr;
     368           0 :         mPass = nullptr;
     369           0 :         mDomain = nullptr;
     370             :     }
     371          12 : }
     372             : 
     373             : bool
     374           0 : nsHttpAuthIdentity::Equals(const nsHttpAuthIdentity &ident) const
     375             : {
     376             :     // we could probably optimize this with a single loop, but why bother?
     377           0 :     return StrEquivalent(mUser, ident.mUser) &&
     378           0 :            StrEquivalent(mPass, ident.mPass) &&
     379           0 :            StrEquivalent(mDomain, ident.mDomain);
     380             : }
     381             : 
     382             : //-----------------------------------------------------------------------------
     383             : // nsHttpAuthEntry
     384             : //-----------------------------------------------------------------------------
     385             : 
     386           0 : nsHttpAuthEntry::~nsHttpAuthEntry()
     387             : {
     388           0 :     if (mRealm)
     389           0 :         free(mRealm);
     390             : 
     391           0 :     while (mRoot) {
     392           0 :         nsHttpAuthPath *ap = mRoot;
     393           0 :         mRoot = mRoot->mNext;
     394           0 :         free(ap);
     395             :     }
     396           0 : }
     397             : 
     398             : nsresult
     399           0 : nsHttpAuthEntry::AddPath(const char *aPath)
     400             : {
     401             :     // null path matches empty path
     402           0 :     if (!aPath)
     403           0 :         aPath = "";
     404             : 
     405           0 :     nsHttpAuthPath *tempPtr = mRoot;
     406           0 :     while (tempPtr) {
     407           0 :         const char *curpath = tempPtr->mPath;
     408           0 :         if (strncmp(aPath, curpath, strlen(curpath)) == 0)
     409           0 :             return NS_OK; // subpath already exists in the list
     410             : 
     411           0 :         tempPtr = tempPtr->mNext;
     412             : 
     413             :     }
     414             : 
     415             :     //Append the aPath
     416             :     nsHttpAuthPath *newAuthPath;
     417           0 :     int newpathLen = strlen(aPath);
     418           0 :     newAuthPath = (nsHttpAuthPath *) malloc(sizeof(nsHttpAuthPath) + newpathLen);
     419           0 :     if (!newAuthPath)
     420           0 :         return NS_ERROR_OUT_OF_MEMORY;
     421             : 
     422           0 :     memcpy(newAuthPath->mPath, aPath, newpathLen+1);
     423           0 :     newAuthPath->mNext = nullptr;
     424             : 
     425           0 :     if (!mRoot)
     426           0 :         mRoot = newAuthPath; //first entry
     427             :     else
     428           0 :         mTail->mNext = newAuthPath; // Append newAuthPath
     429             : 
     430             :     //update the tail pointer.
     431           0 :     mTail = newAuthPath;
     432           0 :     return NS_OK;
     433             : }
     434             : 
     435             : nsresult
     436           0 : nsHttpAuthEntry::Set(const char *path,
     437             :                      const char *realm,
     438             :                      const char *creds,
     439             :                      const char *chall,
     440             :                      const nsHttpAuthIdentity *ident,
     441             :                      nsISupports *metadata)
     442             : {
     443             :     char *newRealm, *newCreds, *newChall;
     444             : 
     445           0 :     int realmLen = realm ? strlen(realm) : 0;
     446           0 :     int credsLen = creds ? strlen(creds) : 0;
     447           0 :     int challLen = chall ? strlen(chall) : 0;
     448             : 
     449           0 :     int len = realmLen + 1 + credsLen + 1 + challLen + 1;
     450           0 :     newRealm = (char *) malloc(len);
     451           0 :     if (!newRealm)
     452           0 :         return NS_ERROR_OUT_OF_MEMORY;
     453             : 
     454           0 :     if (realm)
     455           0 :         memcpy(newRealm, realm, realmLen);
     456           0 :     newRealm[realmLen] = 0;
     457             : 
     458           0 :     newCreds = &newRealm[realmLen + 1];
     459           0 :     if (creds)
     460           0 :         memcpy(newCreds, creds, credsLen);
     461           0 :     newCreds[credsLen] = 0;
     462             : 
     463           0 :     newChall = &newCreds[credsLen + 1];
     464           0 :     if (chall)
     465           0 :         memcpy(newChall, chall, challLen);
     466           0 :     newChall[challLen] = 0;
     467             : 
     468           0 :     nsresult rv = NS_OK;
     469           0 :     if (ident) {
     470           0 :         rv = mIdent.Set(*ident);
     471             :     }
     472           0 :     else if (mIdent.IsEmpty()) {
     473             :         // If we are not given an identity and our cached identity has not been
     474             :         // initialized yet (so is currently empty), initialize it now by
     475             :         // filling it with nulls.  We need to do that because consumers expect
     476             :         // that mIdent is initialized after this function returns.
     477           0 :         rv = mIdent.Set(nullptr, nullptr, nullptr);
     478             :     }
     479           0 :     if (NS_FAILED(rv)) {
     480           0 :         free(newRealm);
     481           0 :         return rv;
     482             :     }
     483             : 
     484           0 :     rv = AddPath(path);
     485           0 :     if (NS_FAILED(rv)) {
     486           0 :         free(newRealm);
     487           0 :         return rv;
     488             :     }
     489             : 
     490             :     // wait until the end to clear member vars in case input params
     491             :     // reference our members!
     492           0 :     if (mRealm)
     493           0 :         free(mRealm);
     494             : 
     495           0 :     mRealm = newRealm;
     496           0 :     mCreds = newCreds;
     497           0 :     mChallenge = newChall;
     498           0 :     mMetaData = metadata;
     499             : 
     500           0 :     return NS_OK;
     501             : }
     502             : 
     503             : //-----------------------------------------------------------------------------
     504             : // nsHttpAuthNode
     505             : //-----------------------------------------------------------------------------
     506             : 
     507           0 : nsHttpAuthNode::nsHttpAuthNode()
     508             : {
     509           0 :     LOG(("Creating nsHttpAuthNode @%p\n", this));
     510           0 : }
     511             : 
     512           0 : nsHttpAuthNode::~nsHttpAuthNode()
     513             : {
     514           0 :     LOG(("Destroying nsHttpAuthNode @%p\n", this));
     515             : 
     516           0 :     mList.Clear();
     517           0 : }
     518             : 
     519             : nsHttpAuthEntry *
     520           0 : nsHttpAuthNode::LookupEntryByPath(const char *path)
     521             : {
     522             :     nsHttpAuthEntry *entry;
     523             : 
     524             :     // null path matches empty path
     525           0 :     if (!path)
     526           0 :         path = "";
     527             : 
     528             :     // look for an entry that either matches or contains this directory.
     529             :     // ie. we'll give out credentials if the given directory is a sub-
     530             :     // directory of an existing entry.
     531           0 :     for (uint32_t i=0; i<mList.Length(); ++i) {
     532           0 :         entry = mList[i];
     533           0 :         nsHttpAuthPath *authPath = entry->RootPath();
     534           0 :         while (authPath) {
     535           0 :             const char *entryPath = authPath->mPath;
     536             :             // proxy auth entries have no path, so require exact match on
     537             :             // empty path string.
     538           0 :             if (entryPath[0] == '\0') {
     539           0 :                 if (path[0] == '\0')
     540           0 :                     return entry;
     541             :             }
     542           0 :             else if (strncmp(path, entryPath, strlen(entryPath)) == 0)
     543           0 :                 return entry;
     544             : 
     545           0 :             authPath = authPath->mNext;
     546             :         }
     547             :     }
     548           0 :     return nullptr;
     549             : }
     550             : 
     551             : nsHttpAuthEntry *
     552           0 : nsHttpAuthNode::LookupEntryByRealm(const char *realm)
     553             : {
     554             :     nsHttpAuthEntry *entry;
     555             : 
     556             :     // null realm matches empty realm
     557           0 :     if (!realm)
     558           0 :         realm = "";
     559             : 
     560             :     // look for an entry that matches this realm
     561             :     uint32_t i;
     562           0 :     for (i=0; i<mList.Length(); ++i) {
     563           0 :         entry = mList[i];
     564           0 :         if (strcmp(realm, entry->Realm()) == 0)
     565           0 :             return entry;
     566             :     }
     567           0 :     return nullptr;
     568             : }
     569             : 
     570             : nsresult
     571           0 : nsHttpAuthNode::SetAuthEntry(const char *path,
     572             :                              const char *realm,
     573             :                              const char *creds,
     574             :                              const char *challenge,
     575             :                              const nsHttpAuthIdentity *ident,
     576             :                              nsISupports *metadata)
     577             : {
     578             :     // look for an entry with a matching realm
     579           0 :     nsHttpAuthEntry *entry = LookupEntryByRealm(realm);
     580           0 :     if (!entry) {
     581           0 :         entry = new nsHttpAuthEntry(path, realm, creds, challenge, ident, metadata);
     582           0 :         if (!entry)
     583           0 :             return NS_ERROR_OUT_OF_MEMORY;
     584             : 
     585             :         // We want the latest identity be at the begining of the list so that
     586             :         // the newest working credentials are sent first on new requests.
     587             :         // Changing a realm is sometimes used to "timeout" authrozization.
     588           0 :         mList.InsertElementAt(0, entry);
     589             :     }
     590             :     else {
     591             :         // update the entry...
     592           0 :         nsresult rv = entry->Set(path, realm, creds, challenge, ident, metadata);
     593           0 :         NS_ENSURE_SUCCESS(rv, rv);
     594             :     }
     595             : 
     596           0 :     return NS_OK;
     597             : }
     598             : 
     599             : void
     600           0 : nsHttpAuthNode::ClearAuthEntry(const char *realm)
     601             : {
     602           0 :     nsHttpAuthEntry *entry = LookupEntryByRealm(realm);
     603           0 :     if (entry) {
     604           0 :         mList.RemoveElement(entry); // double search OK
     605             :     }
     606           0 : }
     607             : 
     608             : } // namespace net
     609             : } // namespace mozilla

Generated by: LCOV version 1.13