diff --git a/mozilla/modules/libpr0n/src/imgCache.cpp b/mozilla/modules/libpr0n/src/imgCache.cpp index bc791e8d4f4..83ef88426c4 100644 --- a/mozilla/modules/libpr0n/src/imgCache.cpp +++ b/mozilla/modules/libpr0n/src/imgCache.cpp @@ -38,6 +38,9 @@ #include "nsICacheSession.h" #include "nsICacheEntryDescriptor.h" +#include "nsIFile.h" +#include "nsIFileURL.h" + NS_IMPL_ISUPPORTS3(imgCache, imgICache, nsIObserver, nsISupportsWeakReference) imgCache::imgCache() @@ -183,6 +186,12 @@ PRBool imgCache::Put(nsIURI *aKey, imgRequest *request, nsICacheEntryDescriptor entry->MarkValid(); + // If file, force revalidation on expiration + PRBool isFile; + aKey->SchemeIs("file", &isFile); + if (isFile) + entry->SetMetaDataElement("MustValidateIfExpired", "true"); + *aEntry = entry; NS_ADDREF(*aEntry); @@ -230,6 +239,25 @@ PRBool imgCache::Get(nsIURI *aKey, PRBool *aHasExpired, imgRequest **aRequest, n } else { *aHasExpired = PR_FALSE; } + // Special treatment for file URLs - entry has expired if file has changed + nsCOMPtr fileUrl(do_QueryInterface(aKey)); + if (fileUrl) { + PRUint32 lastModTime; + entry->GetLastModified(&lastModTime); + + nsCOMPtr theFile; + rv = fileUrl->GetFile(getter_AddRefs(theFile)); + if (NS_SUCCEEDED(rv)) { + PRInt64 fileLastMod; + rv = theFile->GetLastModifiedTime(&fileLastMod); + if (NS_SUCCEEDED(rv)) { + // nsIFile uses millisec, NSPR usec + PRInt64 one_thousand = LL_INIT(0, 1000); + LL_MUL(fileLastMod, fileLastMod, one_thousand); + *aHasExpired = SecondsFromPRTime((PRTime)fileLastMod) > lastModTime; + } + } + } } nsCOMPtr sup; diff --git a/mozilla/modules/libpr0n/src/imgLoader.cpp b/mozilla/modules/libpr0n/src/imgLoader.cpp index ebe3d14d9e2..b03bc5e6a28 100644 --- a/mozilla/modules/libpr0n/src/imgLoader.cpp +++ b/mozilla/modules/libpr0n/src/imgLoader.cpp @@ -408,33 +408,29 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, if (NS_SUCCEEDED(newChannel->GetLoadFlags(&loadFlags))) newChannel->SetLoadFlags(loadFlags | nsICachingChannel::LOAD_ONLY_IF_MODIFIED); - rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, aCX, - requestFlags, aRequest, _retval); - - httpValidateChecker *hvc = new httpValidateChecker(request, aCX); - if (!hvc) { - NS_RELEASE(request); - return NS_ERROR_OUT_OF_MEMORY; - } - - NS_ADDREF(hvc); - request->mValidator = hvc; - - hvc->AddProxy(NS_STATIC_CAST(imgRequestProxy*, *_retval)); - - nsresult openRes; - openRes = newChannel->AsyncOpen(NS_STATIC_CAST(nsIStreamListener *, hvc), nsnull); - - NS_RELEASE(hvc); - - NS_RELEASE(request); - - return openRes; - } - // If it isn't caching channel, use the cached version. - // XXX we should probably do something more intelligent for local files. - bValidateRequest = PR_FALSE; + rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, aCX, + requestFlags, aRequest, _retval); + + imgCacheValidator *hvc = new imgCacheValidator(request, aCX); + if (!hvc) { + NS_RELEASE(request); + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(hvc); + request->mValidator = hvc; + + hvc->AddProxy(NS_STATIC_CAST(imgRequestProxy*, *_retval)); + + nsresult openRes; + openRes = newChannel->AsyncOpen(NS_STATIC_CAST(nsIStreamListener *, hvc), nsnull); + + NS_RELEASE(hvc); + + NS_RELEASE(request); + + return openRes; } } else if (!request) { /* Case #1: no request from the cache. do a new load */ @@ -885,9 +881,9 @@ NS_IMETHODIMP ProxyListener::OnDataAvailable(nsIRequest *aRequest, nsISupports * * http validate class. check a channel for a 304 */ -NS_IMPL_ISUPPORTS2(httpValidateChecker, nsIStreamListener, nsIRequestObserver) +NS_IMPL_ISUPPORTS2(imgCacheValidator, nsIStreamListener, nsIRequestObserver) -httpValidateChecker::httpValidateChecker(imgRequest *request, void *aContext) : +imgCacheValidator::imgCacheValidator(imgRequest *request, void *aContext) : mContext(aContext) { NS_INIT_ISUPPORTS(); @@ -897,13 +893,13 @@ httpValidateChecker::httpValidateChecker(imgRequest *request, void *aContext) : NS_ADDREF(mRequest); } -httpValidateChecker::~httpValidateChecker() +imgCacheValidator::~imgCacheValidator() { /* destructor code */ NS_IF_RELEASE(mRequest); } -void httpValidateChecker::AddProxy(imgRequestProxy *aProxy) +void imgCacheValidator::AddProxy(imgRequestProxy *aProxy) { mProxies.AppendElement(aProxy); } @@ -911,7 +907,7 @@ void httpValidateChecker::AddProxy(imgRequestProxy *aProxy) /** nsIRequestObserver methods **/ /* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */ -NS_IMETHODIMP httpValidateChecker::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt) +NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt) { nsCOMPtr cacheChan(do_QueryInterface(aRequest)); if (cacheChan) { @@ -934,61 +930,61 @@ NS_IMETHODIMP httpValidateChecker::OnStartRequest(nsIRequest *aRequest, nsISuppo mRequest = nsnull; return NS_OK; - // we're set. do nothing. - } else { - // fun stuff. - nsCOMPtr channel(do_QueryInterface(aRequest)); - nsCOMPtr entry; - nsCOMPtr uri; - - // Doom the old request's cache entry - if (mRequest->mCacheEntry) - mRequest->mCacheEntry->Doom(); - - mRequest->GetURI(getter_AddRefs(uri)); - - mRequest->mValidator = nsnull; - NS_RELEASE(mRequest); - mRequest = nsnull; - - nsresult rv; - nsCOMPtr eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr activeQ; - rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(activeQ)); - if (NS_FAILED(rv)) return rv; - - imgRequest *request; - NS_NEWXPCOM(request, imgRequest); - if (!request) return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(request); - - imgCache::Put(uri, request, getter_AddRefs(entry)); - - request->Init(channel, entry, activeQ.get(), mContext); - - ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request)); - if (!pl) { - NS_RELEASE(request); - return NS_ERROR_OUT_OF_MEMORY; - } - - mDestListener = NS_STATIC_CAST(nsIStreamListener*, pl); - - PRUint32 count; - mProxies.Count(&count); - for (PRInt32 i = count-1; i>=0; i--) { - imgRequestProxy *proxy; - mProxies.GetElementAt(i, (nsISupports**)&proxy); - proxy->ChangeOwner(request); - request->NotifyProxyListener(proxy); - NS_RELEASE(proxy); - } - - NS_RELEASE(request); } } + // fun stuff. + nsCOMPtr channel(do_QueryInterface(aRequest)); + nsCOMPtr entry; + nsCOMPtr uri; + + // Doom the old request's cache entry + if (mRequest->mCacheEntry) + mRequest->mCacheEntry->Doom(); + + mRequest->GetURI(getter_AddRefs(uri)); + + mRequest->mValidator = nsnull; + NS_RELEASE(mRequest); + mRequest = nsnull; + + nsresult rv; + nsCOMPtr eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr activeQ; + rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(activeQ)); + if (NS_FAILED(rv)) return rv; + + imgRequest *request; + NS_NEWXPCOM(request, imgRequest); + if (!request) return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(request); + + imgCache::Put(uri, request, getter_AddRefs(entry)); + + request->Init(channel, entry, activeQ.get(), mContext); + + ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request)); + if (!pl) { + NS_RELEASE(request); + return NS_ERROR_OUT_OF_MEMORY; + } + + mDestListener = NS_STATIC_CAST(nsIStreamListener*, pl); + + PRUint32 count; + mProxies.Count(&count); + for (PRInt32 i = count-1; i>=0; i--) { + imgRequestProxy *proxy; + mProxies.GetElementAt(i, (nsISupports**)&proxy); + proxy->ChangeOwner(request); + request->NotifyProxyListener(proxy); + NS_RELEASE(proxy); + } + + NS_RELEASE(request); + + if (!mDestListener) return NS_OK; @@ -997,7 +993,7 @@ NS_IMETHODIMP httpValidateChecker::OnStartRequest(nsIRequest *aRequest, nsISuppo } /* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status); */ -NS_IMETHODIMP httpValidateChecker::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt, nsresult status) +NS_IMETHODIMP imgCacheValidator::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt, nsresult status) { if (!mDestListener) return NS_OK; @@ -1018,7 +1014,7 @@ static NS_METHOD dispose_of_data(nsIInputStream* in, void* closure, } /* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */ -NS_IMETHODIMP httpValidateChecker::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) +NS_IMETHODIMP imgCacheValidator::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) { #ifdef DEBUG nsCOMPtr cacheChan(do_QueryInterface(aRequest)); diff --git a/mozilla/modules/libpr0n/src/imgLoader.h b/mozilla/modules/libpr0n/src/imgLoader.h index e096c4b67e6..4d0d2d85042 100644 --- a/mozilla/modules/libpr0n/src/imgLoader.h +++ b/mozilla/modules/libpr0n/src/imgLoader.h @@ -90,11 +90,11 @@ private: #include "nsSupportsArray.h" -class httpValidateChecker : public nsIStreamListener +class imgCacheValidator : public nsIStreamListener { public: - httpValidateChecker(imgRequest *request, void *aContext); - virtual ~httpValidateChecker(); + imgCacheValidator(imgRequest *request, void *aContext); + virtual ~imgCacheValidator(); void AddProxy(imgRequestProxy *aProxy); diff --git a/mozilla/modules/libpr0n/src/imgRequest.h b/mozilla/modules/libpr0n/src/imgRequest.h index 7efdd5d3c8c..cb248fa75f4 100644 --- a/mozilla/modules/libpr0n/src/imgRequest.h +++ b/mozilla/modules/libpr0n/src/imgRequest.h @@ -40,7 +40,7 @@ #include "nsVoidArray.h" #include "nsWeakReference.h" -class httpValidateChecker; +class imgCacheValidator; class imgRequestProxy; @@ -82,7 +82,7 @@ public: private: friend class imgRequestProxy; friend class imgLoader; - friend class httpValidateChecker; + friend class imgCacheValidator; inline void SetLoadId(void *aLoadId) { mLoadId = aLoadId; @@ -127,7 +127,7 @@ private: void *mLoadId; PRTime mLoadTime; - httpValidateChecker *mValidator; + imgCacheValidator *mValidator; PRBool mIsMultiPartChannel; }; diff --git a/mozilla/modules/libpr0n/src/imgRequestProxy.h b/mozilla/modules/libpr0n/src/imgRequestProxy.h index 234803598c4..2c9b0073f4d 100644 --- a/mozilla/modules/libpr0n/src/imgRequestProxy.h +++ b/mozilla/modules/libpr0n/src/imgRequestProxy.h @@ -78,7 +78,7 @@ protected: void OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult statusCode); private: - friend class httpValidateChecker; + friend class imgCacheValidator; imgRequest *mOwner;