fixes bug 236772 "Sprint Local Bill Redirection Limit Exceeded" r=dwitte sr=dveditz

This commit is contained in:
darin%meer.net 2004-06-07 14:54:22 +00:00
Родитель fd06fee287
Коммит 67ecaf88f6
3 изменённых файлов: 45 добавлений и 20 удалений

Просмотреть файл

@ -75,6 +75,11 @@ StrBlockCopy(const nsACString &aSource1,
* creation helper
******************************************************************************/
// This is a counter that is incremented each time we allocate a new nsCookie.
// The value of the counter is stored with each nsCookie so that we can sort
// cookies by creation time (within the current browser session).
static PRUint32 gLastCreationTime;
nsCookie *
nsCookie::Create(const nsACString &aName,
const nsACString &aValue,
@ -105,8 +110,8 @@ nsCookie::Create(const nsACString &aName,
// construct the cookie. placement new, oh yeah!
return new (place) nsCookie(name, value, host, path, end,
aExpiry, aLastAccessed, aIsSession,
aIsSecure, aStatus, aPolicy);
aExpiry, aLastAccessed, ++gLastCreationTime,
aIsSession, aIsSecure, aStatus, aPolicy);
}
/******************************************************************************

Просмотреть файл

@ -77,6 +77,7 @@ class nsCookie : public nsICookie2
const char *aEnd,
nsInt64 aExpiry,
nsInt64 aLastAccessed,
PRUint32 aCreationTime,
PRBool aIsSession,
PRBool aIsSecure,
nsCookieStatus aStatus,
@ -89,6 +90,7 @@ class nsCookie : public nsICookie2
, mEnd(aEnd)
, mExpiry(aExpiry)
, mLastAccessed(aLastAccessed)
, mCreationTime(aCreationTime)
, mRefCnt(0)
, mIsSession(aIsSession != PR_FALSE)
, mIsSecure(aIsSecure != PR_FALSE)
@ -121,6 +123,7 @@ class nsCookie : public nsICookie2
inline const nsDependentCString Path() const { return nsDependentCString(mPath, mEnd); }
inline nsInt64 Expiry() const { return mExpiry; }
inline nsInt64 LastAccessed() const { return mLastAccessed; }
inline PRUint32 CreationTime() const { return mCreationTime; }
inline PRBool IsSession() const { return mIsSession; }
inline PRBool IsDomain() const { return *mHost == '.'; }
inline PRBool IsSecure() const { return mIsSecure; }
@ -131,6 +134,7 @@ class nsCookie : public nsICookie2
inline void SetLastAccessed(nsInt64 aLastAccessed) { mLastAccessed = aLastAccessed; }
inline void SetExpiry(PRInt64 aExpiry) { mExpiry = aExpiry; }
inline void SetIsSession(PRBool aIsSession) { mIsSession = aIsSession; }
inline void SetCreationTime(PRUint32 aCT) { mCreationTime = aCT; }
// linked list management helper
inline nsCookie*& Next() { return mNext; }
@ -150,6 +154,7 @@ class nsCookie : public nsICookie2
const char *mEnd;
nsInt64 mExpiry;
nsInt64 mLastAccessed;
PRUint32 mCreationTime;
PRUint32 mRefCnt : 16;
PRUint32 mIsSession : 1;
PRUint32 mIsSecure : 1;

Просмотреть файл

@ -292,31 +292,40 @@ LogSuccess(PRBool aSetCookie, nsIURI *aHostURI, const nsAFlatCString &aCookieStr
/******************************************************************************
* nsCookieService impl:
* private list sorting callbacks
*
* these functions return:
* < 0 if the first element should come before the second element,
* 0 if the first element may come before or after the second element,
* > 0 if the first element should come after the second element.
******************************************************************************/
// comparison function for sorting cookies by path length:
// returns < 0 if the first element has a greater path length than the second element,
// 0 if they both have the same path length,
// > 0 if the second element has a greater path length than the first element.
// comparison function for sorting cookies before sending to a server.
PR_STATIC_CALLBACK(int)
compareCookiesByPath(const void *aElement1,
const void *aElement2,
void *aData)
compareCookiesForSending(const void *aElement1,
const void *aElement2,
void *aData)
{
const nsCookie *cookie1 = NS_STATIC_CAST(const nsCookie*, aElement1);
const nsCookie *cookie2 = NS_STATIC_CAST(const nsCookie*, aElement2);
return cookie2->Path().Length() - cookie1->Path().Length();
// compare by cookie path length in accordance with RFC2109
int rv = cookie2->Path().Length() - cookie1->Path().Length();
if (rv == 0) {
// when path lengths match, older cookies should be listed first. this is
// required for backwards compatibility since some websites erroneously
// depend on receiving cookies in the order in which they were sent to the
// browser! see bug 236772.
rv = cookie1->CreationTime() - cookie2->CreationTime();
}
return rv;
}
// comparison function for sorting cookies by lastAccessed time:
// returns < 0 if the first element was used more recently than the second element,
// 0 if they both have the same last-use time,
// > 0 if the second element was used more recently than the first element.
// comparison function for sorting cookies by lastAccessed time, with most-
// recently-used cookies listed first.
PR_STATIC_CALLBACK(int)
compareCookiesByLRU(const void *aElement1,
const void *aElement2,
void *aData)
compareCookiesForWriting(const void *aElement1,
const void *aElement2,
void *aData)
{
const nsCookie *cookie1 = NS_STATIC_CAST(const nsCookie*, aElement1);
const nsCookie *cookie2 = NS_STATIC_CAST(const nsCookie*, aElement2);
@ -600,8 +609,9 @@ nsCookieService::GetCookieStringFromHttp(nsIURI *aHostURI,
} while (currentDot);
// return cookies in order of path length; longest to shortest.
// this is required per RFC2109.
foundCookieList.Sort(compareCookiesByPath, nsnull);
// this is required per RFC2109. if cookies match in length,
// then sort by creation time (see bug 236772).
foundCookieList.Sort(compareCookiesForSending, nsnull);
nsCAutoString cookieData;
PRInt32 count = foundCookieList.Count();
@ -1058,7 +1068,7 @@ nsCookieService::Write()
// such that least-recently-used cookies come last
nsVoidArray sortedCookieList(mCookieCount);
mHostTable.EnumerateEntries(cookieListCallback, &sortedCookieList);
sortedCookieList.Sort(compareCookiesByLRU, nsnull);
sortedCookieList.Sort(compareCookiesForWriting, nsnull);
bufferedOutputStream->Write(kHeader, sizeof(kHeader) - 1, &rv);
@ -1234,6 +1244,11 @@ nsCookieService::AddInternal(nsCookie *aCookie,
return;
}
// preserve creation time of cookie
if (oldCookie) {
aCookie->SetCreationTime(oldCookie->CreationTime());
}
} else {
// check if cookie has already expired
if (aCookie->Expiry() <= aCurrentTime) {