зеркало из https://github.com/mozilla/pjs.git
137819 r=tor sr=darin Changed images don't reload [file:// URLs]
This commit is contained in:
Родитель
6bf3930051
Коммит
3d8701754e
|
@ -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<nsIFileURL> fileUrl(do_QueryInterface(aKey));
|
||||
if (fileUrl) {
|
||||
PRUint32 lastModTime;
|
||||
entry->GetLastModified(&lastModTime);
|
||||
|
||||
nsCOMPtr<nsIFile> 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<nsISupports> sup;
|
||||
|
|
|
@ -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<nsICachingChannel> 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<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
nsCOMPtr<nsIURI> 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<nsIEventQueueService> eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIEventQueue> 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<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
nsCOMPtr<nsICacheEntryDescriptor> entry;
|
||||
nsCOMPtr<nsIURI> 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<nsIEventQueueService> eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIEventQueue> 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<nsICachingChannel> cacheChan(do_QueryInterface(aRequest));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ protected:
|
|||
void OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult statusCode);
|
||||
|
||||
private:
|
||||
friend class httpValidateChecker;
|
||||
friend class imgCacheValidator;
|
||||
|
||||
imgRequest *mOwner;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче