зеркало из https://github.com/mozilla/pjs.git
Backout bug 552605 and bug 619048 due to increase in random failures in reftests on a CLOSED TREE
This commit is contained in:
Родитель
2b48d2f010
Коммит
9f6d678f5c
|
@ -1,7 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Bug 89419</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="http://mochi.test:8888/tests/docshell/test/chrome/bug89419.sjs">
|
||||
</body>
|
|
@ -44,9 +44,6 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_HTTP_FILES = \
|
||||
bug89419.sjs \
|
||||
blue.png \
|
||||
red.png \
|
||||
92598_nostore.html \
|
||||
92598_nostore.html^headers^ \
|
||||
112564_nocache.html \
|
||||
|
@ -61,9 +58,6 @@ _HTTP_FILES = \
|
|||
$(NULL)
|
||||
|
||||
_TEST_FILES = \
|
||||
test_bug89419.xul \
|
||||
bug89419_window.xul \
|
||||
89419.html \
|
||||
test_bug92598.xul \
|
||||
bug92598_window.xul \
|
||||
92598_nostore.html \
|
||||
|
|
Двоичные данные
docshell/test/chrome/blue.png
Двоичные данные
docshell/test/chrome/blue.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 2.7 KiB |
|
@ -1,13 +0,0 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
var redirectstate = "/docshell/test/chrome/bug89419.sjs";
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
if (getState(redirectstate) == "") {
|
||||
response.setHeader("Location", "red.png", false);
|
||||
setState(redirectstate, "red");
|
||||
} else {
|
||||
response.setHeader("Location", "blue.png", false);
|
||||
setState(redirectstate, "");
|
||||
}
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window id="89419Test"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="600"
|
||||
height="600"
|
||||
onload="setTimeout(nextTest,0);"
|
||||
title="bug 89419 test">
|
||||
|
||||
<script type="application/javascript" src= "chrome://mochikit/content/chrome-harness.js" />
|
||||
<script type="application/javascript" src="docshell_helpers.js" />
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
|
||||
<script type="application/javascript"><![CDATA[
|
||||
// Define the generator-iterator for the tests.
|
||||
var tests = testIterator();
|
||||
|
||||
////
|
||||
// Execute the next test in the generator function.
|
||||
//
|
||||
function nextTest() {
|
||||
tests.next();
|
||||
}
|
||||
|
||||
////
|
||||
// Generator function for test steps for bug 89419:
|
||||
// A visited link should have the :visited style applied
|
||||
// to it when displayed on a page which was fetched from
|
||||
// the bfcache.
|
||||
//
|
||||
function testIterator()
|
||||
{
|
||||
// Load a test page containing an image referring to the sjs that returns
|
||||
// a different redirect every time it's loaded.
|
||||
doPageNavigation({
|
||||
uri: getHttpUrl("89419.html"),
|
||||
onNavComplete: nextTest,
|
||||
preventBFCache: true
|
||||
});
|
||||
yield;
|
||||
|
||||
var first = snapshotWindow(TestWindow.getWindow());
|
||||
|
||||
doPageNavigation({
|
||||
uri: "about:blank",
|
||||
onNavComplete: nextTest
|
||||
});
|
||||
yield;
|
||||
|
||||
var second = snapshotWindow(TestWindow.getWindow());
|
||||
function snapshotsEqual(snap1, snap2) {
|
||||
return compareSnapshots(snap1, snap2, true)[0];
|
||||
}
|
||||
ok(!snapshotsEqual(first, second), "about:blank should not be the same as the image web page");
|
||||
|
||||
doPageNavigation({
|
||||
back: true,
|
||||
onNavComplete: nextTest
|
||||
});
|
||||
yield;
|
||||
|
||||
var third = snapshotWindow(TestWindow.getWindow());
|
||||
ok(!snapshotsEqual(third, second), "going back should not be the same as about:blank");
|
||||
ok(snapshotsEqual(first, third), "going back should be the same as the initial load");
|
||||
|
||||
// Tell the framework the test is finished. Include the final 'yield'
|
||||
// statement to prevent a StopIteration exception from being thrown.
|
||||
finish();
|
||||
yield;
|
||||
}
|
||||
|
||||
]]></script>
|
||||
|
||||
<browser type="content-primary" flex="1" id="content" src="about:blank"/>
|
||||
</window>
|
Двоичные данные
docshell/test/chrome/red.png
Двоичные данные
docshell/test/chrome/red.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 82 B |
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=89419.xul
|
||||
-->
|
||||
<window title="Mozilla Bug 89419"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<title>Test for Bug 89419</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">
|
||||
Mozilla Bug 89419</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 89419 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.open("bug89419_window.xul", "bug89419",
|
||||
"chrome,width=600,height=600");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
</window>
|
|
@ -69,6 +69,9 @@ static PRUint32 gTotalDDBSize = 0;
|
|||
// Returns true if an image of aWidth x aHeight is allowed and legal.
|
||||
static PRBool AllowedImageSize(PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
NS_ASSERTION(aWidth > 0, "invalid image width");
|
||||
NS_ASSERTION(aHeight > 0, "invalid image height");
|
||||
|
||||
// reject over-wide or over-tall images
|
||||
const PRInt32 k64KLimit = 0x0000FFFF;
|
||||
if (NS_UNLIKELY(aWidth > k64KLimit || aHeight > k64KLimit )) {
|
||||
|
@ -76,8 +79,9 @@ static PRBool AllowedImageSize(PRInt32 aWidth, PRInt32 aHeight)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// protect against invalid sizes
|
||||
if (NS_UNLIKELY(aHeight <= 0 || aWidth <= 0)) {
|
||||
// protect against division by zero - this really shouldn't happen
|
||||
// if our consumers were well behaved, but they aren't (bug 368427)
|
||||
if (NS_UNLIKELY(aHeight == 0)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,6 +276,35 @@ public:
|
|||
|
||||
NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
|
||||
/**
|
||||
* A class that implements nsIProgressEventSink and forwards all calls to it to
|
||||
* the original notification callbacks of the channel. Also implements
|
||||
* nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls,
|
||||
* and forwards everything else to the channel's notification callbacks.
|
||||
*/
|
||||
class nsProgressNotificationProxy : public nsIProgressEventSink
|
||||
, public nsIChannelEventSink
|
||||
, public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
nsProgressNotificationProxy(nsIChannel* channel,
|
||||
imgIRequest* proxy)
|
||||
: mImageRequest(proxy) {
|
||||
channel->GetNotificationCallbacks(getter_AddRefs(mOriginalCallbacks));
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
private:
|
||||
~nsProgressNotificationProxy() {}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> mOriginalCallbacks;
|
||||
nsCOMPtr<nsIRequest> mImageRequest;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS3(nsProgressNotificationProxy,
|
||||
nsIProgressEventSink,
|
||||
nsIChannelEventSink,
|
||||
|
@ -285,8 +314,7 @@ NS_IMETHODIMP
|
|||
nsProgressNotificationProxy::OnProgress(nsIRequest* request,
|
||||
nsISupports* ctxt,
|
||||
PRUint64 progress,
|
||||
PRUint64 progressMax)
|
||||
{
|
||||
PRUint64 progressMax) {
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
request->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
|
||||
|
@ -304,8 +332,7 @@ NS_IMETHODIMP
|
|||
nsProgressNotificationProxy::OnStatus(nsIRequest* request,
|
||||
nsISupports* ctxt,
|
||||
nsresult status,
|
||||
const PRUnichar* statusArg)
|
||||
{
|
||||
const PRUnichar* statusArg) {
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
request->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
|
||||
|
@ -323,8 +350,7 @@ NS_IMETHODIMP
|
|||
nsProgressNotificationProxy::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
nsIAsyncVerifyRedirectCallback *cb) {
|
||||
// Tell the original original callbacks about it too
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
newChannel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
|
@ -344,8 +370,7 @@ nsProgressNotificationProxy::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsProgressNotificationProxy::GetInterface(const nsIID& iid,
|
||||
void** result)
|
||||
{
|
||||
void** result) {
|
||||
if (iid.Equals(NS_GET_IID(nsIProgressEventSink))) {
|
||||
*result = static_cast<nsIProgressEventSink*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
|
@ -361,13 +386,17 @@ nsProgressNotificationProxy::GetInterface(const nsIID& iid,
|
|||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
static PRBool NewRequestAndEntry(imgRequest **request, imgCacheEntry **entry)
|
||||
static PRBool NewRequestAndEntry(nsIURI *uri, imgRequest **request, imgCacheEntry **entry)
|
||||
{
|
||||
// If file, force revalidation on expiration
|
||||
PRBool isFile;
|
||||
uri->SchemeIs("file", &isFile);
|
||||
|
||||
*request = new imgRequest();
|
||||
if (!*request)
|
||||
return PR_FALSE;
|
||||
|
||||
*entry = new imgCacheEntry(*request);
|
||||
*entry = new imgCacheEntry(*request, /* mustValidateIfExpired = */ isFile);
|
||||
if (!*entry) {
|
||||
delete *request;
|
||||
return PR_FALSE;
|
||||
|
@ -391,9 +420,6 @@ static PRBool ShouldRevalidateEntry(imgCacheEntry *aEntry,
|
|||
if (aFlags & nsIRequest::VALIDATE_ALWAYS) {
|
||||
bValidateEntry = PR_TRUE;
|
||||
}
|
||||
else if (aEntry->GetMustValidate()) {
|
||||
bValidateEntry = PR_TRUE;
|
||||
}
|
||||
//
|
||||
// The cache entry has expired... Determine whether the stale cache
|
||||
// entry can be used without validation...
|
||||
|
@ -407,7 +433,7 @@ static PRBool ShouldRevalidateEntry(imgCacheEntry *aEntry,
|
|||
if (aFlags & (nsIRequest::VALIDATE_NEVER |
|
||||
nsIRequest::VALIDATE_ONCE_PER_SESSION))
|
||||
{
|
||||
bValidateEntry = PR_FALSE;
|
||||
bValidateEntry = aEntry->GetMustValidateIfExpired();
|
||||
}
|
||||
//
|
||||
// LOAD_FROM_CACHE allows a stale cache entry to be used... Otherwise,
|
||||
|
@ -495,15 +521,13 @@ static PRUint32 SecondsFromPRTime(PRTime prTime)
|
|||
return PRUint32(PRInt64(prTime) / PRInt64(PR_USEC_PER_SEC));
|
||||
}
|
||||
|
||||
imgCacheEntry::imgCacheEntry(imgRequest *request)
|
||||
imgCacheEntry::imgCacheEntry(imgRequest *request, PRBool mustValidateIfExpired /* = PR_FALSE */)
|
||||
: mRequest(request),
|
||||
mDataSize(0),
|
||||
mTouchedTime(SecondsFromPRTime(PR_Now())),
|
||||
mExpiryTime(0),
|
||||
mMustValidate(PR_FALSE),
|
||||
// We start off as evicted so we don't try to update the cache. PutIntoCache
|
||||
// will set this to false.
|
||||
mEvicted(PR_TRUE),
|
||||
mMustValidateIfExpired(mustValidateIfExpired),
|
||||
mEvicted(PR_FALSE),
|
||||
mHasNoProxies(PR_TRUE)
|
||||
{}
|
||||
|
||||
|
@ -1174,9 +1198,6 @@ PRBool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
|||
return NS_SUCCEEDED(rv);
|
||||
|
||||
} else {
|
||||
// We will rely on Necko to cache this request when it's possible, and to
|
||||
// tell imgCacheValidator::OnStartRequest whether the request came from its
|
||||
// cache.
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
rv = NewImageChannel(getter_AddRefs(newChannel),
|
||||
aURI,
|
||||
|
@ -1190,6 +1211,16 @@ PRBool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(newChannel));
|
||||
|
||||
if (cacheChan) {
|
||||
// since this channel supports nsICachingChannel, we can ask it
|
||||
// to only stream us data if the data comes off the net.
|
||||
PRUint32 loadFlags;
|
||||
if (NS_SUCCEEDED(newChannel->GetLoadFlags(&loadFlags)))
|
||||
newChannel->SetLoadFlags(loadFlags | nsICachingChannel::LOAD_ONLY_IF_MODIFIED);
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> req;
|
||||
rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver,
|
||||
aLoadFlags, aExistingRequest, getter_AddRefs(req));
|
||||
|
@ -1198,18 +1229,18 @@ PRBool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
|||
}
|
||||
|
||||
// Make sure that OnStatus/OnProgress calls have the right request set...
|
||||
nsRefPtr<nsProgressNotificationProxy> progressproxy =
|
||||
new nsProgressNotificationProxy(newChannel, req);
|
||||
if (!progressproxy)
|
||||
nsCOMPtr<nsIInterfaceRequestor> requestor(
|
||||
new nsProgressNotificationProxy(newChannel, req));
|
||||
if (!requestor)
|
||||
return PR_FALSE;
|
||||
newChannel->SetNotificationCallbacks(requestor);
|
||||
|
||||
nsRefPtr<imgCacheValidator> hvc = new imgCacheValidator(progressproxy, request, aCX);
|
||||
imgCacheValidator *hvc = new imgCacheValidator(request, aCX);
|
||||
if (!hvc) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
newChannel->SetNotificationCallbacks(hvc);
|
||||
|
||||
NS_ADDREF(hvc);
|
||||
request->mValidator = hvc;
|
||||
|
||||
imgRequestProxy* proxy = static_cast<imgRequestProxy*>
|
||||
|
@ -1228,6 +1259,8 @@ PRBool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
|||
if (NS_SUCCEEDED(rv))
|
||||
NS_ADDREF(*aProxyRequest = req.get());
|
||||
|
||||
NS_RELEASE(hvc);
|
||||
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
}
|
||||
|
@ -1600,7 +1633,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI,
|
|||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!NewRequestAndEntry(getter_AddRefs(request), getter_AddRefs(entry)))
|
||||
if (!NewRequestAndEntry(aURI, getter_AddRefs(request), getter_AddRefs(entry)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
|
@ -1792,7 +1825,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
requestFlags, nsnull, _retval);
|
||||
static_cast<imgRequestProxy*>(*_retval)->NotifyListener();
|
||||
} else {
|
||||
if (!NewRequestAndEntry(getter_AddRefs(request), getter_AddRefs(entry)))
|
||||
if (!NewRequestAndEntry(uri, getter_AddRefs(request), getter_AddRefs(entry)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// We use originalURI here to fulfil the imgIRequest contract on GetURI.
|
||||
|
@ -1809,7 +1842,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
NS_RELEASE(pl);
|
||||
|
||||
// Try to add the new request into the cache.
|
||||
PutIntoCache(originalURI, entry);
|
||||
PutIntoCache(uri, entry);
|
||||
|
||||
rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
|
||||
requestFlags, nsnull, _retval);
|
||||
|
@ -1998,20 +2031,14 @@ NS_IMETHODIMP ProxyListener::OnDataAvailable(nsIRequest *aRequest, nsISupports *
|
|||
* http validate class. check a channel for a 304
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS5(imgCacheValidator, nsIStreamListener, nsIRequestObserver,
|
||||
nsIChannelEventSink, nsIInterfaceRequestor,
|
||||
nsIAsyncVerifyRedirectCallback)
|
||||
NS_IMPL_ISUPPORTS2(imgCacheValidator, nsIStreamListener, nsIRequestObserver)
|
||||
|
||||
imgLoader imgCacheValidator::sImgLoader;
|
||||
|
||||
imgCacheValidator::imgCacheValidator(nsProgressNotificationProxy* progress,
|
||||
imgRequest *request, void *aContext)
|
||||
: mProgressProxy(progress),
|
||||
mRequest(request),
|
||||
mContext(aContext)
|
||||
{
|
||||
NewRequestAndEntry(getter_AddRefs(mNewRequest), getter_AddRefs(mNewEntry));
|
||||
}
|
||||
imgCacheValidator::imgCacheValidator(imgRequest *request, void *aContext) :
|
||||
mRequest(request),
|
||||
mContext(aContext)
|
||||
{}
|
||||
|
||||
imgCacheValidator::~imgCacheValidator()
|
||||
{
|
||||
|
@ -2034,22 +2061,14 @@ void imgCacheValidator::AddProxy(imgRequestProxy *aProxy)
|
|||
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
|
||||
{
|
||||
// If this request is coming from cache and has the same URI as our
|
||||
// imgRequest, the request all our proxies are pointing at is valid, and all
|
||||
// we have to do is tell them to notify their listeners.
|
||||
// If this request is coming from cache, the request all our proxies are
|
||||
// pointing at is valid, and all we have to do is tell them to notify their
|
||||
// listeners.
|
||||
nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(aRequest));
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
if (cacheChan && channel) {
|
||||
PRBool isFromCache = PR_FALSE;
|
||||
cacheChan->IsFromCache(&isFromCache);
|
||||
if (cacheChan) {
|
||||
PRBool isFromCache;
|
||||
if (NS_SUCCEEDED(cacheChan->IsFromCache(&isFromCache)) && isFromCache) {
|
||||
|
||||
nsCOMPtr<nsIURI> channelURI;
|
||||
PRBool sameURI = PR_FALSE;
|
||||
channel->GetURI(getter_AddRefs(channelURI));
|
||||
if (channelURI)
|
||||
channelURI->Equals(mRequest->mCurrentURI, &sameURI);
|
||||
|
||||
if (isFromCache && sameURI) {
|
||||
PRUint32 count = mProxies.Count();
|
||||
for (PRInt32 i = count-1; i>=0; i--) {
|
||||
imgRequestProxy *proxy = static_cast<imgRequestProxy *>(mProxies[i]);
|
||||
|
@ -2066,24 +2085,21 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
|
|||
proxy->SyncNotifyListener();
|
||||
}
|
||||
|
||||
// We don't need to load this any more.
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mRequest->SetLoadId(mContext);
|
||||
mRequest->mValidator = nsnull;
|
||||
|
||||
mRequest = nsnull;
|
||||
|
||||
mNewRequest = nsnull;
|
||||
mNewEntry = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// We can't load out of cache. We have to create a whole new request for the
|
||||
// data that's coming in off the channel.
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
nsRefPtr<imgCacheEntry> entry;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
||||
mRequest->GetURI(getter_AddRefs(uri));
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
|
@ -2098,24 +2114,34 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
|
|||
mRequest->mValidator = nsnull;
|
||||
mRequest = nsnull;
|
||||
|
||||
imgRequest *request;
|
||||
|
||||
if (!NewRequestAndEntry(uri, &request, getter_AddRefs(entry)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// We use originalURI here to fulfil the imgIRequest contract on GetURI.
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
channel->GetOriginalURI(getter_AddRefs(originalURI));
|
||||
mNewRequest->Init(originalURI, uri, channel, channel, mNewEntry, NS_GetCurrentThread(), mContext);
|
||||
request->Init(originalURI, uri, channel, channel, entry, NS_GetCurrentThread(), mContext);
|
||||
|
||||
ProxyListener *pl = new ProxyListener(static_cast<nsIStreamListener *>(mNewRequest));
|
||||
ProxyListener *pl = new ProxyListener(static_cast<nsIStreamListener *>(request));
|
||||
if (!pl) {
|
||||
request->CancelAndAbort(NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_RELEASE(request);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mDestListener = static_cast<nsIStreamListener*>(pl);
|
||||
|
||||
// Try to add the new request into the cache. Note that the entry must be in
|
||||
// the cache before the proxies' ownership changes, because adding a proxy
|
||||
// changes the caching behaviour for imgRequests.
|
||||
sImgLoader.PutIntoCache(originalURI, mNewEntry);
|
||||
sImgLoader.PutIntoCache(uri, entry);
|
||||
|
||||
PRUint32 count = mProxies.Count();
|
||||
for (PRInt32 i = count-1; i>=0; i--) {
|
||||
imgRequestProxy *proxy = static_cast<imgRequestProxy *>(mProxies[i]);
|
||||
proxy->ChangeOwner(mNewRequest);
|
||||
proxy->ChangeOwner(request);
|
||||
|
||||
// Proxies waiting on cache validation should be deferring notifications.
|
||||
// Undefer them.
|
||||
|
@ -2129,8 +2155,10 @@ NS_IMETHODIMP imgCacheValidator::OnStartRequest(nsIRequest *aRequest, nsISupport
|
|||
proxy->SyncNotifyListener();
|
||||
}
|
||||
|
||||
mNewRequest = nsnull;
|
||||
mNewEntry = nsnull;
|
||||
NS_RELEASE(request);
|
||||
|
||||
if (!mDestListener)
|
||||
return NS_OK;
|
||||
|
||||
return mDestListener->OnStartRequest(aRequest, ctxt);
|
||||
}
|
||||
|
@ -2150,6 +2178,15 @@ NS_IMETHODIMP imgCacheValidator::OnStopRequest(nsIRequest *aRequest, nsISupports
|
|||
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
|
||||
NS_IMETHODIMP imgCacheValidator::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(aRequest));
|
||||
if (cacheChan) {
|
||||
PRBool isFromCache;
|
||||
if (NS_SUCCEEDED(cacheChan->IsFromCache(&isFromCache)) && isFromCache)
|
||||
NS_ERROR("OnDataAvailable not suppressed by LOAD_ONLY_IF_MODIFIED load flag");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mDestListener) {
|
||||
// XXX see bug 113959
|
||||
PRUint32 _retval;
|
||||
|
@ -2159,62 +2196,3 @@ NS_IMETHODIMP imgCacheValidator::OnDataAvailable(nsIRequest *aRequest, nsISuppor
|
|||
|
||||
return mDestListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
|
||||
}
|
||||
|
||||
/** nsIInterfaceRequestor methods **/
|
||||
|
||||
NS_IMETHODIMP imgCacheValidator::GetInterface(const nsIID & aIID, void **aResult)
|
||||
{
|
||||
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink)))
|
||||
return QueryInterface(aIID, aResult);
|
||||
|
||||
return mProgressProxy->GetInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
// These functions are materially the same as the same functions in imgRequest.
|
||||
// We duplicate them because we're verifying whether cache loads are necessary,
|
||||
// not unconditionally loading.
|
||||
|
||||
/** nsIChannelEventSink methods **/
|
||||
NS_IMETHODIMP imgCacheValidator::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel, PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
// Note all cache information we get from the old channel.
|
||||
mNewRequest->SetCacheValidation(mNewEntry, oldChannel);
|
||||
|
||||
// Prepare for callback
|
||||
mRedirectCallback = callback;
|
||||
mRedirectChannel = newChannel;
|
||||
|
||||
return mProgressProxy->AsyncOnChannelRedirect(oldChannel, newChannel, flags, this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP imgCacheValidator::OnRedirectVerifyCallback(nsresult aResult)
|
||||
{
|
||||
// If we've already been told to abort, just do so.
|
||||
if (NS_FAILED(aResult)) {
|
||||
mRedirectCallback->OnRedirectVerifyCallback(aResult);
|
||||
mRedirectCallback = nsnull;
|
||||
mRedirectChannel = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// make sure we have a protocol that returns data rather than opens
|
||||
// an external application, e.g. mailto:
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mRedirectChannel->GetURI(getter_AddRefs(uri));
|
||||
PRBool doesNotReturnData = PR_FALSE;
|
||||
NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
&doesNotReturnData);
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (doesNotReturnData) {
|
||||
result = NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nsnull;
|
||||
mRedirectChannel = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
#include "imgRequest.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIChannelPolicy.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsIChannel.h"
|
||||
|
||||
#ifdef LOADER_THREADSAFE
|
||||
#include "prlock.h"
|
||||
|
@ -68,7 +66,7 @@ class nsILoadGroup;
|
|||
class imgCacheEntry
|
||||
{
|
||||
public:
|
||||
imgCacheEntry(imgRequest *request);
|
||||
imgCacheEntry(imgRequest *request, PRBool mustValidateIfExpired = PR_FALSE);
|
||||
~imgCacheEntry();
|
||||
|
||||
nsrefcnt AddRef()
|
||||
|
@ -125,13 +123,13 @@ public:
|
|||
Touch();
|
||||
}
|
||||
|
||||
PRBool GetMustValidate() const
|
||||
PRBool GetMustValidateIfExpired() const
|
||||
{
|
||||
return mMustValidate;
|
||||
return mMustValidateIfExpired;
|
||||
}
|
||||
void SetMustValidate(PRBool aValidate)
|
||||
void SetMustValidateIfExpired(PRBool aValidate)
|
||||
{
|
||||
mMustValidate = aValidate;
|
||||
mMustValidateIfExpired = aValidate;
|
||||
Touch();
|
||||
}
|
||||
|
||||
|
@ -180,7 +178,7 @@ private: // data
|
|||
PRInt32 mTouchedTime;
|
||||
PRInt32 mExpiryTime;
|
||||
nsExpirationState mExpirationState;
|
||||
PRPackedBool mMustValidate : 1;
|
||||
PRPackedBool mMustValidateIfExpired : 1;
|
||||
PRPackedBool mEvicted : 1;
|
||||
PRPackedBool mHasNoProxies : 1;
|
||||
};
|
||||
|
@ -376,33 +374,6 @@ private:
|
|||
nsCOMPtr<nsIStreamListener> mDestListener;
|
||||
};
|
||||
|
||||
/**
|
||||
* A class that implements nsIProgressEventSink and forwards all calls to it to
|
||||
* the original notification callbacks of the channel. Also implements
|
||||
* nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls,
|
||||
* and forwards everything else to the channel's notification callbacks.
|
||||
*/
|
||||
class nsProgressNotificationProxy : public nsIProgressEventSink
|
||||
, public nsIChannelEventSink
|
||||
, public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
nsProgressNotificationProxy(nsIChannel* channel,
|
||||
imgIRequest* proxy)
|
||||
: mImageRequest(proxy) {
|
||||
channel->GetNotificationCallbacks(getter_AddRefs(mOriginalCallbacks));
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
private:
|
||||
~nsProgressNotificationProxy() {}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> mOriginalCallbacks;
|
||||
nsCOMPtr<nsIRequest> mImageRequest;
|
||||
};
|
||||
|
||||
/**
|
||||
* validate checker
|
||||
|
@ -410,36 +381,25 @@ class nsProgressNotificationProxy : public nsIProgressEventSink
|
|||
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class imgCacheValidator : public nsIStreamListener,
|
||||
public nsIChannelEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIAsyncVerifyRedirectCallback
|
||||
class imgCacheValidator : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
imgCacheValidator(nsProgressNotificationProxy* progress, imgRequest *request, void *aContext);
|
||||
imgCacheValidator(imgRequest *request, void *aContext);
|
||||
virtual ~imgCacheValidator();
|
||||
|
||||
void AddProxy(imgRequestProxy *aProxy);
|
||||
|
||||
/* additional members */
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIStreamListener> mDestListener;
|
||||
nsRefPtr<nsProgressNotificationProxy> mProgressProxy;
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||
nsCOMPtr<nsIChannel> mRedirectChannel;
|
||||
|
||||
nsRefPtr<imgRequest> mRequest;
|
||||
nsCOMArray<imgIRequest> mProxies;
|
||||
|
||||
nsRefPtr<imgRequest> mNewRequest;
|
||||
nsRefPtr<imgCacheEntry> mNewEntry;
|
||||
|
||||
void *mContext;
|
||||
|
||||
static imgLoader sImgLoader;
|
||||
|
|
|
@ -191,16 +191,16 @@ imgRequest::imgRequest() :
|
|||
|
||||
imgRequest::~imgRequest()
|
||||
{
|
||||
if (mURI) {
|
||||
if (mKeyURI) {
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(spec);
|
||||
mKeyURI->GetSpec(spec);
|
||||
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequest::~imgRequest()", "keyuri", spec.get());
|
||||
} else
|
||||
LOG_FUNC(gImgLog, "imgRequest::~imgRequest()");
|
||||
}
|
||||
|
||||
nsresult imgRequest::Init(nsIURI *aURI,
|
||||
nsIURI *aCurrentURI,
|
||||
nsIURI *aKeyURI,
|
||||
nsIRequest *aRequest,
|
||||
nsIChannel *aChannel,
|
||||
imgCacheEntry *aCacheEntry,
|
||||
|
@ -211,7 +211,7 @@ nsresult imgRequest::Init(nsIURI *aURI,
|
|||
|
||||
NS_ABORT_IF_FALSE(!mImage, "Multiple calls to init");
|
||||
NS_ABORT_IF_FALSE(aURI, "No uri");
|
||||
NS_ABORT_IF_FALSE(aCurrentURI, "No current uri");
|
||||
NS_ABORT_IF_FALSE(aKeyURI, "No key uri");
|
||||
NS_ABORT_IF_FALSE(aRequest, "No request");
|
||||
NS_ABORT_IF_FALSE(aChannel, "No channel");
|
||||
|
||||
|
@ -220,7 +220,7 @@ nsresult imgRequest::Init(nsIURI *aURI,
|
|||
mStatusTracker = new imgStatusTracker(nsnull);
|
||||
|
||||
mURI = aURI;
|
||||
mCurrentURI = aCurrentURI;
|
||||
mKeyURI = aKeyURI;
|
||||
mRequest = aRequest;
|
||||
mChannel = aChannel;
|
||||
mTimedChannel = do_QueryInterface(mChannel);
|
||||
|
@ -281,8 +281,8 @@ nsresult imgRequest::AddProxy(imgRequestProxy *proxy)
|
|||
// If we're empty before adding, we have to tell the loader we now have
|
||||
// proxies.
|
||||
if (mObservers.IsEmpty()) {
|
||||
NS_ABORT_IF_FALSE(mURI, "Trying to SetHasProxies without key uri.");
|
||||
imgLoader::SetHasProxies(mURI);
|
||||
NS_ABORT_IF_FALSE(mKeyURI, "Trying to SetHasProxies without key uri.");
|
||||
imgLoader::SetHasProxies(mKeyURI);
|
||||
}
|
||||
|
||||
// If we don't have any current observers, we should restart any animation.
|
||||
|
@ -322,14 +322,14 @@ nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus, PRBoo
|
|||
// been cancelled and thus removed from the cache, tell the image loader so
|
||||
// we can be evicted from the cache.
|
||||
if (mCacheEntry) {
|
||||
NS_ABORT_IF_FALSE(mURI, "Removing last observer without key uri.");
|
||||
NS_ABORT_IF_FALSE(mKeyURI, "Removing last observer without key uri.");
|
||||
|
||||
imgLoader::SetHasNoProxies(mURI, mCacheEntry);
|
||||
imgLoader::SetHasNoProxies(mKeyURI, mCacheEntry);
|
||||
}
|
||||
#if defined(PR_LOGGING)
|
||||
else {
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(spec);
|
||||
mKeyURI->GetSpec(spec);
|
||||
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::RemoveProxy no cache entry", "uri", spec.get());
|
||||
}
|
||||
#endif
|
||||
|
@ -410,8 +410,8 @@ nsresult imgRequest::GetKeyURI(nsIURI **aKeyURI)
|
|||
{
|
||||
LOG_FUNC(gImgLog, "imgRequest::GetKeyURI");
|
||||
|
||||
if (mURI) {
|
||||
*aKeyURI = mURI;
|
||||
if (mKeyURI) {
|
||||
*aKeyURI = mKeyURI;
|
||||
NS_ADDREF(*aKeyURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ void imgRequest::RemoveFromCache()
|
|||
if (mCacheEntry)
|
||||
imgLoader::RemoveFromCache(mCacheEntry);
|
||||
else
|
||||
imgLoader::RemoveFromCache(mURI);
|
||||
imgLoader::RemoveFromCache(mKeyURI);
|
||||
}
|
||||
|
||||
mCacheEntry = nsnull;
|
||||
|
@ -507,71 +507,6 @@ void imgRequest::UpdateCacheEntrySize()
|
|||
}
|
||||
}
|
||||
|
||||
void imgRequest::SetCacheValidation(imgCacheEntry* aCacheEntry, nsIRequest* aRequest)
|
||||
{
|
||||
/* get the expires info */
|
||||
if (aCacheEntry) {
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aRequest));
|
||||
if (cacheChannel) {
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cacheChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (cacheToken) {
|
||||
nsCOMPtr<nsICacheEntryInfo> entryDesc(do_QueryInterface(cacheToken));
|
||||
if (entryDesc) {
|
||||
PRUint32 expiration;
|
||||
/* get the expiration time from the caching channel's token */
|
||||
entryDesc->GetExpirationTime(&expiration);
|
||||
|
||||
// Expiration time defaults to 0. We set the expiration time on our
|
||||
// entry if it hasn't been set yet.
|
||||
if (aCacheEntry->GetExpiryTime() == 0)
|
||||
aCacheEntry->SetExpiryTime(expiration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether the cache entry must be revalidated when we try to use it.
|
||||
// Currently, only HTTP specifies this information...
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
|
||||
if (httpChannel) {
|
||||
PRBool bMustRevalidate = PR_FALSE;
|
||||
|
||||
httpChannel->IsNoStoreResponse(&bMustRevalidate);
|
||||
|
||||
if (!bMustRevalidate) {
|
||||
httpChannel->IsNoCacheResponse(&bMustRevalidate);
|
||||
}
|
||||
|
||||
if (!bMustRevalidate) {
|
||||
nsCAutoString cacheHeader;
|
||||
|
||||
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Cache-Control"),
|
||||
cacheHeader);
|
||||
if (PL_strcasestr(cacheHeader.get(), "must-revalidate")) {
|
||||
bMustRevalidate = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache entries default to not needing to validate. We ensure that
|
||||
// multiple calls to this function don't override an earlier decision to
|
||||
// validate by making validation a one-way decision.
|
||||
if (bMustRevalidate)
|
||||
aCacheEntry->SetMustValidate(bMustRevalidate);
|
||||
}
|
||||
|
||||
// We always need to validate file URIs.
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
PRBool isfile = PR_FALSE;
|
||||
uri->SchemeIs("file", &isfile);
|
||||
if (isfile)
|
||||
aCacheEntry->SetMustValidate(isfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
imgRequest::LockImage()
|
||||
{
|
||||
|
@ -815,6 +750,8 @@ NS_IMETHODIMP imgRequest::OnDiscard(imgIRequest *aRequest)
|
|||
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");
|
||||
|
||||
// Figure out if we're multipart
|
||||
|
@ -886,7 +823,55 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
|
|||
}
|
||||
}
|
||||
|
||||
SetCacheValidation(mCacheEntry, aRequest);
|
||||
/* get the expires info */
|
||||
if (mCacheEntry) {
|
||||
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aRequest));
|
||||
if (cacheChannel) {
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cacheChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (cacheToken) {
|
||||
nsCOMPtr<nsICacheEntryInfo> entryDesc(do_QueryInterface(cacheToken));
|
||||
if (entryDesc) {
|
||||
PRUint32 expiration;
|
||||
/* get the expiration time from the caching channel's token */
|
||||
entryDesc->GetExpirationTime(&expiration);
|
||||
|
||||
/* set the expiration time on our entry */
|
||||
mCacheEntry->SetExpiryTime(expiration);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Determine whether the cache entry must be revalidated when it expires.
|
||||
// If so, then the cache entry must *not* be used during HISTORY loads if
|
||||
// it has expired.
|
||||
//
|
||||
// Currently, only HTTP specifies this information...
|
||||
//
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
|
||||
if (httpChannel) {
|
||||
PRBool bMustRevalidate = PR_FALSE;
|
||||
|
||||
rv = httpChannel->IsNoStoreResponse(&bMustRevalidate);
|
||||
|
||||
if (!bMustRevalidate) {
|
||||
rv = httpChannel->IsNoCacheResponse(&bMustRevalidate);
|
||||
}
|
||||
|
||||
if (!bMustRevalidate) {
|
||||
nsCAutoString cacheHeader;
|
||||
|
||||
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Cache-Control"),
|
||||
cacheHeader);
|
||||
if (PL_strcasestr(cacheHeader.get(), "must-revalidate")) {
|
||||
bMustRevalidate = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
mCacheEntry->SetMustValidateIfExpired(bMustRevalidate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
|
||||
if (mObservers.IsEmpty()) {
|
||||
|
@ -1254,8 +1239,6 @@ imgRequest::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
|||
NS_ASSERTION(mChannel == oldChannel, "Got a channel redirect for an unknown channel!");
|
||||
NS_ASSERTION(newChannel, "Got a redirect to a NULL channel!");
|
||||
|
||||
SetCacheValidation(mCacheEntry, oldChannel);
|
||||
|
||||
// Prepare for callback
|
||||
mRedirectCallback = callback;
|
||||
mNewRedirectChannel = newChannel;
|
||||
|
@ -1292,19 +1275,21 @@ imgRequest::OnRedirectVerifyCallback(nsresult result)
|
|||
mTimedChannel = do_QueryInterface(mChannel);
|
||||
mNewRedirectChannel = nsnull;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
// Don't make any cache changes if we're going to point to the same thing. We
|
||||
// compare specs and not just URIs here because URIs that compare as
|
||||
// .Equals() might have different hashes.
|
||||
nsCAutoString oldspec;
|
||||
if (mCurrentURI)
|
||||
mCurrentURI->GetSpec(oldspec);
|
||||
if (mKeyURI)
|
||||
mKeyURI->GetSpec(oldspec);
|
||||
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnChannelRedirect", "old", oldspec.get());
|
||||
#endif
|
||||
|
||||
// make sure we have a protocol that returns data rather than opens
|
||||
// an external application, e.g. mailto:
|
||||
mChannel->GetURI(getter_AddRefs(mCurrentURI));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mChannel->GetURI(getter_AddRefs(uri));
|
||||
PRBool doesNotReturnData = PR_FALSE;
|
||||
nsresult rv =
|
||||
NS_URIChainHasFlags(mCurrentURI, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
&doesNotReturnData);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && doesNotReturnData)
|
||||
|
@ -1316,6 +1301,34 @@ imgRequest::OnRedirectVerifyCallback(nsresult result)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
mChannel->GetOriginalURI(getter_AddRefs(newURI));
|
||||
nsCAutoString newspec;
|
||||
if (newURI)
|
||||
newURI->GetSpec(newspec);
|
||||
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnChannelRedirect", "new", newspec.get());
|
||||
|
||||
if (oldspec != newspec) {
|
||||
if (mIsInCache) {
|
||||
// Remove the cache entry from the cache, but don't null out mCacheEntry
|
||||
// (as imgRequest::RemoveFromCache() does), because we need it to put
|
||||
// ourselves back in the cache.
|
||||
if (mCacheEntry)
|
||||
imgLoader::RemoveFromCache(mCacheEntry);
|
||||
else
|
||||
imgLoader::RemoveFromCache(mKeyURI);
|
||||
}
|
||||
|
||||
mKeyURI = newURI;
|
||||
|
||||
if (mIsInCache) {
|
||||
// If we don't still have a URI or cache entry, we don't want to put
|
||||
// ourselves back into the cache.
|
||||
if (mKeyURI && mCacheEntry)
|
||||
imgLoader::PutIntoCache(mKeyURI, mCacheEntry);
|
||||
}
|
||||
}
|
||||
|
||||
mRedirectCallback->OnRedirectVerifyCallback(NS_OK);
|
||||
mRedirectCallback = nsnull;
|
||||
return NS_OK;
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsresult Init(nsIURI *aURI,
|
||||
nsIURI *aCurrentURI,
|
||||
nsIURI *aKeyURI,
|
||||
nsIRequest *aRequest,
|
||||
nsIChannel *aChannel,
|
||||
imgCacheEntry *aCacheEntry,
|
||||
|
@ -129,12 +129,6 @@ public:
|
|||
return mWindowId;
|
||||
}
|
||||
|
||||
// Set the cache validation information (expiry time, whether we must
|
||||
// validate, etc) on the cache entry based on the request information.
|
||||
// If this function is called multiple times, the information set earliest
|
||||
// wins.
|
||||
static void SetCacheValidation(imgCacheEntry* aEntry, nsIRequest* aRequest);
|
||||
|
||||
private:
|
||||
friend class imgCacheEntry;
|
||||
friend class imgRequestProxy;
|
||||
|
@ -211,11 +205,10 @@ private:
|
|||
friend class imgMemoryReporter;
|
||||
|
||||
nsCOMPtr<nsIRequest> mRequest;
|
||||
// The original URI we were loaded with. This is the same as the URI we are
|
||||
// keyed on in the cache.
|
||||
// The original URI we were loaded with.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
// The URI of the resource we ended up loading after all redirects, etc.
|
||||
nsCOMPtr<nsIURI> mCurrentURI;
|
||||
// The URI we are keyed on in the cache.
|
||||
nsCOMPtr<nsIURI> mKeyURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
// Status-tracker -- transferred to mImage, when it gets instantiated
|
||||
nsAutoPtr<imgStatusTracker> mStatusTracker;
|
||||
|
|
Двоичные данные
modules/libpr0n/test/crashtests/256-height.ico
Двоичные данные
modules/libpr0n/test/crashtests/256-height.ico
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 154 B |
Двоичные данные
modules/libpr0n/test/crashtests/256-width.ico
Двоичные данные
modules/libpr0n/test/crashtests/256-width.ico
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 154 B |
|
@ -13,8 +13,3 @@ load delaytest.html?523528-2.gif
|
|||
|
||||
# this would have exposed the leak discovered in bug 642902
|
||||
load invalid-icc-profile.jpg
|
||||
|
||||
# maximum (256) width and height icons that we currently (due to bug 668068)
|
||||
# interpret as 0-width and 0-height.
|
||||
load 256-width.ico
|
||||
load 256-height.ico
|
||||
|
|
|
@ -76,13 +76,6 @@ _TEST_FILES = imgutils.js \
|
|||
test_bug614392.html \
|
||||
test_bug657191.html \
|
||||
bug657191.sjs \
|
||||
bug89419-iframe.html \
|
||||
bug89419.sjs \
|
||||
test_bug89419-1.html \
|
||||
test_bug89419-2.html \
|
||||
test_bug552605-1.html \
|
||||
test_bug552605-2.html \
|
||||
bug552605.sjs \
|
||||
$(NULL)
|
||||
|
||||
# Tests disabled due to intermittent orange
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
var redirectstate = "/modules/libpr0n/test/mochitest/bug89419.sjs";
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
if (getState(redirectstate) == "") {
|
||||
response.setHeader("Location", "red.png", false);
|
||||
setState(redirectstate, "red");
|
||||
} else {
|
||||
response.setHeader("Location", "blue.png", false);
|
||||
setState(redirectstate, "");
|
||||
}
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Bug 89419 iframe</title>
|
||||
<body>
|
||||
<img src="bug89419.sjs" width="100" height="100" />
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
function handleRequest(request, response)
|
||||
{
|
||||
var redirectstate = "/modules/libpr0n/test/mochitest/bug89419.sjs";
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
if (getState(redirectstate) == "") {
|
||||
response.setHeader("Location", "red.png", false);
|
||||
setState(redirectstate, "red");
|
||||
} else {
|
||||
response.setHeader("Location", "blue.png", false);
|
||||
setState(redirectstate, "");
|
||||
}
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=552605
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 552605</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552605">Mozilla Bug 552605</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
var first, second;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function checkFirst()
|
||||
{
|
||||
var testimage = document.getElementById('test-image');
|
||||
first = document.createElement('canvas')
|
||||
var ctx = first.getContext('2d');
|
||||
ctx.drawImage(testimage, 0, 0);
|
||||
|
||||
var newimg = new Image();
|
||||
newimg.onload = checkSecond;
|
||||
newimg.src = "bug552605.sjs";
|
||||
document.body.appendChild(newimg);
|
||||
}
|
||||
|
||||
function checkSecond()
|
||||
{
|
||||
var testimage = document.getElementById('test-image');
|
||||
second = document.createElement('canvas')
|
||||
var ctx = second.getContext('2d');
|
||||
ctx.drawImage(testimage, 0, 0);
|
||||
|
||||
// Check that the images are the same, since they're in the same document.
|
||||
[correct, val1, val2] = compareSnapshots(first, second, true);
|
||||
ok(correct, "Image should be the same for all loads.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="content"> <!-- style="display: none" -->
|
||||
<img src="bug552605.sjs" onload="checkFirst()" id="test-image"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,53 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=552605
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 552605</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=552605">Mozilla Bug 552605</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
var count = 0;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function check()
|
||||
{
|
||||
count++;
|
||||
if (count != 2)
|
||||
return;
|
||||
|
||||
var image1 = document.getElementById('test-image1');
|
||||
var image2 = document.getElementById('test-image2');
|
||||
var first = document.createElement('canvas')
|
||||
var ctx = first.getContext('2d');
|
||||
ctx.drawImage(image1, 0, 0);
|
||||
|
||||
var second = document.createElement('canvas');
|
||||
ctx = second.getContext('2d');
|
||||
ctx.drawImage(image2, 0, 0);
|
||||
|
||||
// Check that the images are the same, since they're in the same document.
|
||||
[correct, val1, val2] = compareSnapshots(first, second, true);
|
||||
ok(correct, "Image should be the same for all loads.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="content"> <!-- style="display: none" -->
|
||||
<img src="bug552605.sjs" onload="check()" id="test-image1"></iframe>
|
||||
<img src="bug552605.sjs" onload="check()" id="test-image2"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,68 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=89419
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 89419</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 89419</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
var first, second, third;
|
||||
var correct, val1, val2;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function checkFirst()
|
||||
{
|
||||
var iframeelem = document.getElementById('test-iframe');
|
||||
first = snapshotWindow(iframeelem.contentWindow, false);
|
||||
|
||||
iframeelem.onload = checkSecond;
|
||||
iframeelem.contentWindow.location.reload(false);
|
||||
}
|
||||
|
||||
function checkSecond()
|
||||
{
|
||||
var iframeelem = document.getElementById('test-iframe');
|
||||
second = snapshotWindow(iframeelem.contentWindow, false);
|
||||
|
||||
// Check that we actually reloaded.
|
||||
[correct, val1, val2] = compareSnapshots(first, second, false);
|
||||
ok(correct, "Image should have changed after the first reload.");
|
||||
|
||||
iframeelem.onload = checkThird;
|
||||
iframeelem.contentWindow.location.reload(false);
|
||||
}
|
||||
|
||||
function checkThird()
|
||||
{
|
||||
var iframeelem = document.getElementById('test-iframe');
|
||||
third = snapshotWindow(iframeelem.contentWindow, false);
|
||||
|
||||
// Check that we actually reloaded.
|
||||
[correct, val1, val2] = compareSnapshots(second, third, false);
|
||||
ok(correct, "Image should have changed after the second reload.");
|
||||
|
||||
// Make sure we looped back to the first image.
|
||||
[correct, val1, val2] = compareSnapshots(first, third, true);
|
||||
ok(correct, "Third image should match first image.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="content"> <!-- style="display: none" -->
|
||||
<iframe id="test-iframe" src="bug89419-iframe.html" onload="checkFirst()"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,68 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=89419
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 89419</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=89419">Mozilla Bug 89419</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
var first, second, third;
|
||||
var correct, val1, val2;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function checkFirst()
|
||||
{
|
||||
var iframeelem = document.getElementById('test-iframe');
|
||||
first = snapshotWindow(iframeelem.contentWindow, false);
|
||||
|
||||
iframeelem.onload = checkSecond;
|
||||
iframeelem.contentWindow.location.href = iframeelem.contentWindow.location.href;
|
||||
}
|
||||
|
||||
function checkSecond()
|
||||
{
|
||||
var iframeelem = document.getElementById('test-iframe');
|
||||
second = snapshotWindow(iframeelem.contentWindow, false);
|
||||
|
||||
// Check that we actually reloaded.
|
||||
[correct, val1, val2] = compareSnapshots(first, second, false);
|
||||
ok(correct, "Image should have changed after the first reload.");
|
||||
|
||||
iframeelem.onload = checkThird;
|
||||
iframeelem.contentWindow.location.href = iframeelem.contentWindow.location.href;
|
||||
}
|
||||
|
||||
function checkThird()
|
||||
{
|
||||
var iframeelem = document.getElementById('test-iframe');
|
||||
third = snapshotWindow(iframeelem.contentWindow, false);
|
||||
|
||||
// Check that we actually reloaded.
|
||||
[correct, val1, val2] = compareSnapshots(second, third, false);
|
||||
ok(correct, "Image should have changed after the second reload.");
|
||||
|
||||
// Make sure we looped back to the first image.
|
||||
[correct, val1, val2] = compareSnapshots(first, third, true);
|
||||
ok(correct, "Third image should match first image.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="content"> <!-- style="display: none" -->
|
||||
<iframe id="test-iframe" src="bug89419-iframe.html" onload="checkFirst()"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,7 +3,7 @@ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|||
var gWindowUtils;
|
||||
|
||||
try {
|
||||
gWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
gWindowUtils = window.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIDOMWindowUtils);
|
||||
if (gWindowUtils && !gWindowUtils.compareCanvases)
|
||||
gWindowUtils = null;
|
||||
} catch (e) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче