Fix for bug # 55055 r=adamlock sr=rpotts Save CacheKey in SH

This commit is contained in:
radha%netscape.com 2001-04-13 22:20:33 +00:00
Родитель 7bf7fbfa73
Коммит 35bb1fe40c
3 изменённых файлов: 108 добавлений и 25 удалений

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

@ -21,4 +21,4 @@ dnsNotFound=%s could not be found. Please check the name and try again.
protocolNotFound=%s is not a registered protocol.
connectionFailure=The connection was refused when attempting to contact %s.
netTimeout=The operation timed out when attempting to contact %s.
repost=The page you are trying to view was generated from data you entered in an online form earlier in this browser session. If you resend the data, any action that the form carried out (such as a search or online purchase) will be repeated. To resend the data, click OK. Otherwise, click Cancel.
repost=The page you are trying to view contains POSTDATA that has expired from cache. If you resend the data, any action the form carried out (such as a search or online purchase) will be repeated. To resend the data, click OK. Otherwise, click Cancel.

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

@ -73,6 +73,7 @@
#include "nsPIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsICachingChannel.h"
// For reporting errors with the console service.
// These can go away if error reporting is propagated up past nsDocShell.
@ -3320,11 +3321,18 @@ NS_IMETHODIMP nsDocShell::DoURILoad(nsIURI* aURI, nsIURI* aReferrerURI,
nsCOMPtr<nsIHTTPChannel> httpChannel(do_QueryInterface(channel));
if(httpChannel)
{
{
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(httpChannel));
/* Get the cache Key from SH */
nsCOMPtr<nsISupports> cacheKey;
if (LSHE) {
LSHE->GetCacheKey(getter_AddRefs(cacheKey));
}
// figure out if we need to set the post data stream on the channel...
// right now, this is only done for http channels.....
if(aPostData)
{
{
// XXX it's a bit of a hack to rewind the postdata stream here but
// it has to be done in case the post data is being reused multiple
// times.
@ -3334,14 +3342,38 @@ NS_IMETHODIMP nsDocShell::DoURILoad(nsIURI* aURI, nsIURI* aReferrerURI,
postDataRandomAccess->Seek(PR_SEEK_SET, 0);
}
nsCOMPtr<nsIAtom> method = NS_NewAtom ("POST");
nsCOMPtr<nsIAtom> method = NS_NewAtom ("POST");
httpChannel->SetRequestMethod(method);
httpChannel->SetUploadStream(aPostData);
}
if (aHeadersData)
{
rv = AddHeadersToChannel(aHeadersData, httpChannel);
/* If there is a valid postdata *and* it is a History Load,
* set up the cache key on the channel, to retrieve the
* data only from the cache. When there is a postdata
* on a history load, we do not want to go out to the net
* in our first attempt. We will go out to the net for a
* post data result, *only* if it has expired from cache *and*
* the user has given us permission to do so.
*/
if (mLoadType == LOAD_HISTORY || mLoadType == LOAD_RELOAD_NORMAL) {
if (cacheChannel)
cacheChannel->SetCacheKey(cacheKey, PR_TRUE);
}
}
else {
/* If there is no postdata, set the cache key on the channel
* with the readFromCacheOnly set to false, so that cache will
* be free to get it from net if it is not found in cache.
* New cache may use it creatively on CGI pages with GET
* method and even on those that say "no-cache"
*/
if (mLoadType == LOAD_HISTORY || mLoadType == LOAD_RELOAD_NORMAL) {
if (cacheChannel)
cacheChannel->SetCacheKey(cacheKey, PR_FALSE);
}
}
if (aHeadersData)
{
rv = AddHeadersToChannel(aHeadersData, httpChannel);
}
// Set the referrer explicitly
if(aReferrerURI) // Referrer is currenly only set for link clicks here.
httpChannel->SetReferrer(aReferrerURI,
@ -4045,7 +4077,15 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI *aURI,
// Get the post data
nsCOMPtr<nsIInputStream> inputStream;
nsCOMPtr<nsISupports> cacheKey;
if (aChannel) {
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aChannel));
/* If there is a caching channel, get the Cache Key and store it
* in SH.
*/
if (cacheChannel) {
cacheChannel->GetCacheKey(getter_AddRefs(cacheKey));
}
nsCOMPtr<nsIHTTPChannel> httpChannel(do_QueryInterface(aChannel));
if(httpChannel) {
@ -4058,7 +4098,8 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI *aURI,
nsnull, // Title
nsnull, // DOMDocument
inputStream, // Post data stream
nsnull); // LayoutHistory state
nsnull, // LayoutHistory state
cacheKey); // CacheKey
// If no Session History component is available in the parent DocShell
@ -4066,13 +4107,13 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI *aURI,
// will be deleted when it loses scope...
//
if (mLoadType != LOAD_NORMAL_REPLACE) {
if (mSessionHistory) {
if (mSessionHistory) {
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory));
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
rv = shPrivate->AddEntry(entry, shouldPersist);
}
else
rv = AddChildSHEntry(nsnull, entry, mChildOffset);
else
rv = AddChildSHEntry(nsnull, entry, mChildOffset);
}
// Return the new SH entry...
@ -4102,6 +4143,7 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadTyp
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
NS_ERROR_FAILURE);
#if 0
/* Ask whether to repost form post data */
if (postData) {
nsCOMPtr<nsIPrompt> prompter;
@ -4125,7 +4167,7 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadTyp
}
}
}
#endif /* 0 */
NS_ENSURE_SUCCESS(InternalLoad(uri, mReferrerURI, nsnull, PR_TRUE, PR_FALSE, nsnull,
postData, nsnull, aLoadType, aEntry),
@ -4133,19 +4175,7 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadTyp
return NS_OK;
}
/*
NS_IMETHODIMP
nsDocShell::GetSHEForChild(PRInt32 aChildOffset, nsISHEntry ** aResult)
{
if (OSHE) {
nsCOMPtr<nsISHContainer> container(do_QueryInterface(OSHE));
if (container)
return container->GetChildAt(aChildOffset, aResult);
}
return NS_ERROR_FAILURE;
}
*/
NS_IMETHODIMP
nsDocShell::PersistLayoutHistoryState()
{

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

@ -102,6 +102,7 @@ typedef unsigned long HMTX;
#include "nsPIDOMWindow.h"
#include "nsIController.h"
#include "nsIFocusController.h"
#include "nsIFileStream.h"
#include "nsIHTTPChannel.h" // add this to the ick include list...we need it to QI for post data interface
#include "nsHTTPEnums.h"
@ -113,6 +114,7 @@ typedef unsigned long HMTX;
#include "nsIIOService.h"
#include "nsIURL.h"
#include "nsIProtocolHandler.h"
#include "nsICachingChannel.h"
//XXX for nsIPostData; this is wrong; we shouldn't see the nsIDocument type
#include "nsIDocument.h"
@ -1165,6 +1167,57 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress,
prompter->Alert(nsnull, msg);
nsTextFormatter::smprintf_free(msg);
} // end NS_ERROR_NET_TIMEOUT
else if (aStatus == NS_ERROR_DOCUMENT_NOT_CACHED) {
/* A document that was requested to be fetched *only* from
* the cache is not in cache. May be this is one of those
* postdata results. Throw a dialog to the user,
* saying that the page has expired from cache and ask if
* they wish to refetch the page from the net.
*/
nsCOMPtr<nsIPrompt> prompter;
PRBool repost;
nsCOMPtr<nsIStringBundle> stringBundle;
GetPromptAndStringBundle(getter_AddRefs(prompter),
getter_AddRefs(stringBundle));
if (stringBundle && prompter) {
nsXPIDLString messageStr;
nsresult rv = stringBundle->GetStringFromName(NS_ConvertASCIItoUCS2("repost").GetUnicode(),
getter_Copies(messageStr));
if (NS_SUCCEEDED(rv) && messageStr) {
prompter->Confirm(nsnull, messageStr, &repost);
/* If the user pressed cancel in the dialog,
* return failure. Don't try to load the page with out
* the post data.
*/
if (!repost)
return NS_OK;
/* The user does want to repost the data to the server.
* Initiate a new load again.
*/
/* Get the postdata if any from the channel */
nsCOMPtr<nsIInputStream> inputStream;
nsCOMPtr<nsIURI> referrer;
if (channel) {
nsCOMPtr<nsIHTTPChannel> httpChannel(do_QueryInterface(channel));
if(httpChannel) {
httpChannel->GetUploadStream(getter_AddRefs(inputStream));
httpChannel->GetReferrer(getter_AddRefs(referrer));
}
}
nsCOMPtr<nsIRandomAccessStore> postDataRandomAccess(do_QueryInterface(inputStream));
if (postDataRandomAccess)
{
postDataRandomAccess->Seek(PR_SEEK_SET, 0);
}
InternalLoad(url, referrer, nsnull, PR_TRUE, PR_FALSE, nsnull, inputStream,
nsnull, LOAD_RELOAD_BYPASS_PROXY_AND_CACHE, nsnull);
}
}
}
} // if we have a host
return NS_OK;