diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 00eed7c470d0..510738186d84 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -80,6 +80,7 @@ #include "nsPIDOMWindow.h" #include "nsIDOMDocument.h" #include "nsICachingChannel.h" +#include "nsICacheEntryDescriptor.h" // The following are for bug #13871: Prevent frameset spoofing #include "nsICodebasePrincipal.h" @@ -1959,7 +1960,7 @@ nsDocShell::GetChildSHEntry(PRInt32 aChildOffset, nsISHEntry ** aResult) NS_ENSURE_ARG_POINTER(aResult); *aResult = nsnull; - // + // A nsISHEntry for a child is *only* available when the parent is in // the progress of loading a document too... // @@ -1968,11 +1969,26 @@ nsDocShell::GetChildSHEntry(PRInt32 aChildOffset, nsISHEntry ** aResult) * By default give a loadHistory value */ PRUint32 loadType = nsIDocShellLoadInfo::loadHistory; - mLSHE->GetLoadType(&loadType); + mLSHE->GetLoadType(&loadType); + // If the user did a shift-reload on this frameset page, + // we don't want to load the subframes from history. + if (loadType == nsIDocShellLoadInfo::loadReloadBypassCache || + loadType == nsIDocShellLoadInfo::loadReloadBypassProxy || + loadType == nsIDocShellLoadInfo::loadReloadBypassProxyAndCache) + return rv; nsCOMPtr container(do_QueryInterface(mLSHE)); if (container) { rv = container->GetChildAt(aChildOffset, aResult); if (*aResult) { + // Check the child SHEnty's expiration status. + // If the page has already expired, we don't want to + // load the page from history. + PRBool expired = PR_FALSE; + (*aResult)->GetExpirationStatus(&expired); + if (expired) { + *aResult = nsnull; + return rv; + } (*aResult)->SetLoadType(loadType); } } @@ -4997,7 +5013,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, UpdateCurrentGlobalHistory(); PRBool updateHistory = PR_TRUE; PRBool equalUri = PR_FALSE; - PRBool shAvailable = PR_TRUE; + PRBool shAvailable = PR_TRUE; // Get the post data from the channel nsCOMPtr inputStream; @@ -5029,14 +5045,13 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, } } } // mSessionHistory - // Determine if this type of load should update history. - // We do want to update SHEntry with the new cacheKey if - // the user hit shift-relaod + + // Determine if this type of load should update history. if (aLoadType == LOAD_BYPASS_HISTORY || aLoadType & LOAD_CMD_HISTORY || aLoadType & LOAD_CMD_RELOAD) updateHistory = PR_FALSE; - + /* If the url to be loaded is the same as the one already there, * and the original loadType is LOAD_NORMAL or LOAD_LINK, @@ -5446,6 +5461,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsCOMPtr referrerURI; nsCOMPtr cacheKey; nsCOMPtr cacheToken; + PRPackedBool expired = PR_FALSE; if (aChannel) { nsCOMPtr cacheChannel(do_QueryInterface(aChannel)); @@ -5478,11 +5494,26 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, */ if (!cacheToken) entry->SetSaveHistoryStateFlag(PR_FALSE); - + else { + // Check if the page has expired from cache + nsCOMPtr cacheEntryDesc(do_QueryInterface(cacheToken)); + if (cacheEntryDesc) { + PRUint32 expTime; + + cacheEntryDesc->GetExpirationTime(&expTime); + PRUint32 now = PRTimeToSeconds(PR_Now()); + printf("Exptime = %d, Now = %d\n", expTime, now); + if (expTime <= now) + expired = PR_TRUE; + + } + } + if (expired == PR_TRUE) + entry->SetExpirationStatus(PR_TRUE); // If no Session History component is available in the parent DocShell - // heirarchy, then AddChildSHEntry(...) will fail and the new entry + // hierarchy, then AddChildSHEntry(...) will fail and the new entry // will be deleted when it loses scope... // if (mLoadType != LOAD_NORMAL_REPLACE) { diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 0a906c90937d..04100f73237a 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -259,6 +259,18 @@ protected: NS_IMETHOD EnsureScriptEnvironment(); NS_IMETHOD EnsureFind(); + static inline PRUint32 + PRTimeToSeconds(PRTime t_usec) + { + PRTime usec_per_sec; + PRUint32 t_sec; + LL_I2L(usec_per_sec, PR_USEC_PER_SEC); + LL_DIV(t_usec, t_usec, usec_per_sec); + LL_L2I(t_sec, t_usec); + return t_sec; + } + + virtual nsresult FindTarget(const PRUnichar *aTargetName, PRBool *aIsNewWindow, diff --git a/xpfe/components/shistory/public/nsISHEntry.idl b/xpfe/components/shistory/public/nsISHEntry.idl index a3bc772715c3..eeae10a9989b 100644 --- a/xpfe/components/shistory/public/nsISHEntry.idl +++ b/xpfe/components/shistory/public/nsISHEntry.idl @@ -77,6 +77,9 @@ attribute nsISupports cacheKey; /** attribute to indicate whether layoutHistoryState should be saved */ attribute boolean saveHistoryStateFlag; +/** attribute to indicate whether the page is already expired in cache */ +attribute boolean expirationStatus; + /** Additional ways to create an entry */ void create(in nsIURI aURI, in wstring aTitle, in nsIDOMDocument aDocument, in nsIInputStream aInputStream, in nsILayoutHistoryState aHistoryLayoutState, diff --git a/xpfe/components/shistory/src/nsSHEntry.cpp b/xpfe/components/shistory/src/nsSHEntry.cpp index 0a2c8d28a501..8eeda0a2abe6 100644 --- a/xpfe/components/shistory/src/nsSHEntry.cpp +++ b/xpfe/components/shistory/src/nsSHEntry.cpp @@ -237,6 +237,21 @@ NS_IMETHODIMP nsSHEntry::SetSaveHistoryStateFlag(PRBool aFlag) return NS_OK; } + +NS_IMETHODIMP nsSHEntry::GetExpirationStatus(PRBool * aFlag) +{ + NS_ENSURE_ARG_POINTER(aFlag); + + *aFlag = mExpired; + return NS_OK; +} + +NS_IMETHODIMP nsSHEntry::SetExpirationStatus(PRBool aFlag) +{ + mExpired = aFlag; + return NS_OK; +} + nsresult nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, nsIDOMDocument * aDOMDocument, nsIInputStream * aInputStream, nsILayoutHistoryState * aHistoryLayoutState, @@ -260,6 +275,9 @@ nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, nsIDOMDocument * aDOM // By default we save HistoryLayoutState SetSaveHistoryStateFlag(PR_TRUE); + //By default the page is not expired + SetExpirationStatus(PR_FALSE); + return NS_OK; } diff --git a/xpfe/components/shistory/src/nsSHEntry.h b/xpfe/components/shistory/src/nsSHEntry.h index f42a8f1da3f8..645f808048a9 100644 --- a/xpfe/components/shistory/src/nsSHEntry.h +++ b/xpfe/components/shistory/src/nsSHEntry.h @@ -66,6 +66,7 @@ private: PRUint32 mID; PRBool mIsFrameNavigation; PRBool mSaveHistoryState; + PRPackedBool mExpired; nsCOMPtr mCacheKey; nsISHEntry * mParent; // weak reference };