gecko-dev/modules/libpr0n/src/imgRequest.cpp

1109 lines
32 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <stuart@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "imgRequest.h"
#include "imgLoader.h"
#include "imgRequestProxy.h"
2001-05-08 04:21:49 +00:00
#include "imgILoader.h"
2001-10-06 05:08:16 +00:00
#include "ImageErrors.h"
2001-05-08 04:21:49 +00:00
#include "ImageLogging.h"
#include "gfxIImageFrame.h"
#include "netCore.h"
#include "nsIChannel.h"
2001-05-08 04:21:49 +00:00
#include "nsICachingChannel.h"
2001-02-25 08:37:26 +00:00
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsIMultiPartChannel.h"
#include "nsIHttpChannel.h"
#include "nsIComponentManager.h"
#include "nsIInterfaceRequestorUtils.h"
2001-05-08 04:21:49 +00:00
#include "nsIProxyObjectManager.h"
2001-01-23 02:02:29 +00:00
#include "nsIServiceManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIScriptSecurityManager.h"
Bug 430061: Don't use necko's memory cache in imglib; r/sr=stuart,vlad,bz ? .fast-update ? _profile ? _tests ? obj-ff-debug ? staticlib ? README/.fast-update ? browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf ? build/pgo/automation.py ? build/pgo/profileserver.py ? config/buildid ? config/system_wrappers ? content/base/test/TestNativeXMLHttpRequest ? content/base/test/TestPlainTextSerializer ? embedding/components/printingui/src/mac/printpde/build ? gfx/thebes/public/.gfxContext.h.swp ? gfx/thebes/test/gfxFontSelectionTest ? gfx/thebes/test/gfxSurfaceRefCountTest ? gfx/thebes/test/gfxTextRunPerfTest ? gfx/thebes/test/gfxWordCacheTest ? intl/uconv/tests/TestUConv ? intl/uconv/tests/nsconv ? intl/uconv/tests/plattest ? intl/unicharutil/tests/NormalizationTest ? js/src/host_jskwgen ? js/src/jsautokw.h ? layout/style/test/css_properties.js ? layout/style/test/host_ListCSSProperties ? layout/tools/reftest/autoconf.js ? modules/libpr0n/src/.imgContainer.cpp.swp ? modules/libpr0n/src/.imgLoader.cpp.swp ? modules/libpr0n/src/.imgLoader.h.swp ? modules/libpr0n/src/.imgRequestProxy.cpp.swp ? modules/libpr0n/src/check-all-at-removal-time ? modules/libpr0n/src/currpatch ? modules/libpr0n/src/update-every-time ? modules/plugin/samples/default/mac/build ? netwerk/cache/src/.nsMemoryCacheDevice.cpp.swp ? netwerk/dns/src/etld_data.inc ? netwerk/test/ReadNTLM ? netwerk/test/TestCookie ? netwerk/test/TestIncrementalDownload ? netwerk/test/TestOpen ? netwerk/test/TestServ ? netwerk/test/TestStreamLoader ? netwerk/test/TestUDPSocketProvider ? nsprpub/.fast-update ? nsprpub/unallmakefiles ? parser/htmlparser/robot/test/htmlrobot ? parser/htmlparser/tests/grabpage/grabpage ? parser/htmlparser/tests/html/TestParser ? rdf/tests/triplescat/triplescat ? storage/test/teststorage1 ? testing/mochitest/automation.py ? testing/mochitest/automation.pyc ? testing/mochitest/runtests.pl ? testing/mochitest/runtests.py ? testing/mochitest/ssltunnel/ssltunnel ? toolkit/components/url-classifier/tests/TestUrlClassifierUtils ? toolkit/crashreporter/client/crashreporter ? toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms ? toolkit/crashreporter/test/TestCrashReporterAPI ? toolkit/library/XUL ? toolkit/mozapps/update/src/nsUpdateService.js ? toolkit/xre/platform.ini ? tools/rb ? tools/trace-malloc ? widget/src/cocoa/libwidget.rsrc ? xpcom/io/.nsStringStream.cpp.swp ? xpcom/proxy/tests/proxy-create-threadsafety ? xpcom/sample/program/nsTestSample ? xpcom/tests/TestAutoPtr ? xpcom/tests/TestExpirationTracker ? xpcom/tests/TestHashtables ? xpcom/tests/TestINIParser ? xpcom/tests/TestPipe ? xpcom/tests/TestProxies ? xpcom/tests/TestRegistrationOrder ? xpcom/tests/TestStorageStream ? xpcom/tests/TestStringAPI ? xpcom/tests/TestStrings ? xpcom/tests/TestTArray ? xpcom/tests/TestTextFormatter ? xpcom/tests/TestThreadPool ? xpcom/tests/TestVersionComparator ? xpcom/tests/external/TestMinStringAPI ? xpfe/bootstrap/appleevents/mozillaSuite.rsrc Index: modules/libpr0n/build/nsImageModule.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libpr0n/build/nsImageModule.cpp,v retrieving revision 1.20
2008-09-04 23:00:42 +00:00
#include "nsICacheVisitor.h"
#include "nsString.h"
2001-03-14 00:39:48 +00:00
#include "nsXPIDLString.h"
#include "plstr.h" // PL_strcasestr(...)
#if defined(PR_LOGGING)
PRLogModuleInfo *gImgLog = PR_NewLogModule("imgRequest");
#endif
NS_IMPL_ISUPPORTS8(imgRequest, imgILoad,
imgIDecoderObserver, imgIContainerObserver,
nsIStreamListener, nsIRequestObserver,
nsISupportsWeakReference,
nsIChannelEventSink,
nsIInterfaceRequestor)
imgRequest::imgRequest() :
mImageStatus(imgIRequest::STATUS_NONE), mState(0), mCacheId(0),
mValidator(nsnull), mImageSniffers("image-sniffing-services"),
mIsMultiPartChannel(PR_FALSE), mLoading(PR_FALSE), mProcessing(PR_FALSE),
mHadLastPart(PR_FALSE), mGotData(PR_FALSE), mIsCacheable(PR_TRUE)
{
/* member initializers and constructor code */
}
imgRequest::~imgRequest()
{
if (mKeyURI) {
nsCAutoString 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 *aKeyURI,
nsIRequest *aRequest,
nsIChannel *aChannel,
Bug 430061: Don't use necko's memory cache in imglib; r/sr=stuart,vlad,bz ? .fast-update ? _profile ? _tests ? obj-ff-debug ? staticlib ? README/.fast-update ? browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf ? build/pgo/automation.py ? build/pgo/profileserver.py ? config/buildid ? config/system_wrappers ? content/base/test/TestNativeXMLHttpRequest ? content/base/test/TestPlainTextSerializer ? embedding/components/printingui/src/mac/printpde/build ? gfx/thebes/public/.gfxContext.h.swp ? gfx/thebes/test/gfxFontSelectionTest ? gfx/thebes/test/gfxSurfaceRefCountTest ? gfx/thebes/test/gfxTextRunPerfTest ? gfx/thebes/test/gfxWordCacheTest ? intl/uconv/tests/TestUConv ? intl/uconv/tests/nsconv ? intl/uconv/tests/plattest ? intl/unicharutil/tests/NormalizationTest ? js/src/host_jskwgen ? js/src/jsautokw.h ? layout/style/test/css_properties.js ? layout/style/test/host_ListCSSProperties ? layout/tools/reftest/autoconf.js ? modules/libpr0n/src/.imgContainer.cpp.swp ? modules/libpr0n/src/.imgLoader.cpp.swp ? modules/libpr0n/src/.imgLoader.h.swp ? modules/libpr0n/src/.imgRequestProxy.cpp.swp ? modules/libpr0n/src/check-all-at-removal-time ? modules/libpr0n/src/currpatch ? modules/libpr0n/src/update-every-time ? modules/plugin/samples/default/mac/build ? netwerk/cache/src/.nsMemoryCacheDevice.cpp.swp ? netwerk/dns/src/etld_data.inc ? netwerk/test/ReadNTLM ? netwerk/test/TestCookie ? netwerk/test/TestIncrementalDownload ? netwerk/test/TestOpen ? netwerk/test/TestServ ? netwerk/test/TestStreamLoader ? netwerk/test/TestUDPSocketProvider ? nsprpub/.fast-update ? nsprpub/unallmakefiles ? parser/htmlparser/robot/test/htmlrobot ? parser/htmlparser/tests/grabpage/grabpage ? parser/htmlparser/tests/html/TestParser ? rdf/tests/triplescat/triplescat ? storage/test/teststorage1 ? testing/mochitest/automation.py ? testing/mochitest/automation.pyc ? testing/mochitest/runtests.pl ? testing/mochitest/runtests.py ? testing/mochitest/ssltunnel/ssltunnel ? toolkit/components/url-classifier/tests/TestUrlClassifierUtils ? toolkit/crashreporter/client/crashreporter ? toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms ? toolkit/crashreporter/test/TestCrashReporterAPI ? toolkit/library/XUL ? toolkit/mozapps/update/src/nsUpdateService.js ? toolkit/xre/platform.ini ? tools/rb ? tools/trace-malloc ? widget/src/cocoa/libwidget.rsrc ? xpcom/io/.nsStringStream.cpp.swp ? xpcom/proxy/tests/proxy-create-threadsafety ? xpcom/sample/program/nsTestSample ? xpcom/tests/TestAutoPtr ? xpcom/tests/TestExpirationTracker ? xpcom/tests/TestHashtables ? xpcom/tests/TestINIParser ? xpcom/tests/TestPipe ? xpcom/tests/TestProxies ? xpcom/tests/TestRegistrationOrder ? xpcom/tests/TestStorageStream ? xpcom/tests/TestStringAPI ? xpcom/tests/TestStrings ? xpcom/tests/TestTArray ? xpcom/tests/TestTextFormatter ? xpcom/tests/TestThreadPool ? xpcom/tests/TestVersionComparator ? xpcom/tests/external/TestMinStringAPI ? xpfe/bootstrap/appleevents/mozillaSuite.rsrc Index: modules/libpr0n/build/nsImageModule.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libpr0n/build/nsImageModule.cpp,v retrieving revision 1.20
2008-09-04 23:00:42 +00:00
imgCacheEntry *aCacheEntry,
void *aCacheId,
void *aLoadId)
{
2001-05-08 04:21:49 +00:00
LOG_FUNC(gImgLog, "imgRequest::Init");
NS_ABORT_IF_FALSE(!mImage, "Multiple calls to init");
NS_ABORT_IF_FALSE(aURI, "No uri");
NS_ABORT_IF_FALSE(aKeyURI, "No key uri");
NS_ABORT_IF_FALSE(aRequest, "No request");
NS_ABORT_IF_FALSE(aChannel, "No channel");
mProperties = do_CreateInstance("@mozilla.org/properties;1");
if (!mProperties)
return NS_ERROR_OUT_OF_MEMORY;
mURI = aURI;
mKeyURI = aKeyURI;
mRequest = aRequest;
mChannel = aChannel;
mChannel->GetNotificationCallbacks(getter_AddRefs(mPrevChannelSink));
NS_ASSERTION(mPrevChannelSink != this,
"Initializing with a channel that already calls back to us!");
mChannel->SetNotificationCallbacks(this);
/* set our loading flag to true here.
Setting it here lets checks to see if the load is in progress
before OnStartRequest gets called, letting 'this' properly get removed
from the cache in certain cases.
*/
mLoading = PR_TRUE;
mCacheEntry = aCacheEntry;
mCacheId = aCacheId;
SetLoadId(aLoadId);
2001-01-23 02:02:29 +00:00
return NS_OK;
}
void imgRequest::SetCacheEntry(imgCacheEntry *entry)
{
mCacheEntry = entry;
}
PRBool imgRequest::HasCacheEntry() const
{
return mCacheEntry != nsnull;
}
nsresult imgRequest::AddProxy(imgRequestProxy *proxy)
{
NS_PRECONDITION(proxy, "null imgRequestProxy passed in");
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::AddProxy", "proxy", proxy);
// If we're empty before adding, we have to tell the loader we now have
// proxies.
if (mObservers.IsEmpty()) {
NS_ABORT_IF_FALSE(mKeyURI, "Trying to SetHasProxies without key uri.");
imgLoader::SetHasProxies(mKeyURI);
}
2007-12-20 07:30:04 +00:00
return mObservers.AppendElementUnlessExists(proxy) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus, PRBool aNotify)
{
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::RemoveProxy", "proxy", proxy);
2007-12-20 07:30:04 +00:00
mObservers.RemoveElement(proxy);
/* Check mState below before we potentially call Cancel() below. Since
Cancel() may result in OnStopRequest being called back before Cancel()
returns, leaving mState in a different state then the one it was in at
this point.
*/
if (aNotify) {
// make sure that observer gets an OnStopDecode message sent to it
if (!(mState & onStopDecode)) {
proxy->OnStopDecode(aStatus, nsnull);
}
2002-01-16 03:23:50 +00:00
}
// make sure that observer gets an OnStopRequest message sent to it
if (!(mState & onStopRequest)) {
proxy->OnStopRequest(nsnull, nsnull, NS_BINDING_ABORTED, PR_TRUE);
}
if (mImage && !HaveProxyWithObserver(nsnull)) {
LOG_MSG(gImgLog, "imgRequest::RemoveProxy", "stopping animation");
mImage->StopAnimation();
}
if (mObservers.IsEmpty()) {
// If we have no observers, there's nothing holding us alive. If we haven't
// 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(mKeyURI, "Removing last observer without key uri.");
imgLoader::SetHasNoProxies(mKeyURI, mCacheEntry);
}
#if defined(PR_LOGGING)
else {
nsCAutoString spec;
mKeyURI->GetSpec(spec);
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::RemoveProxy no cache entry", "uri", spec.get());
}
#endif
/* If |aStatus| is a failure code, then cancel the load if it is still in progress.
Otherwise, let the load continue, keeping 'this' in the cache with no observers.
This way, if a proxy is destroyed without calling cancel on it, it won't leak
and won't leave a bad pointer in mObservers.
*/
if (mRequest && mLoading && NS_FAILED(aStatus)) {
LOG_MSG(gImgLog, "imgRequest::RemoveProxy", "load in progress. canceling");
mImageStatus |= imgIRequest::STATUS_LOAD_PARTIAL;
this->Cancel(NS_BINDING_ABORTED);
}
/* break the cycle from the cache entry. */
mCacheEntry = nsnull;
}
// If a proxy is removed for a reason other than its owner being
// changed, remove the proxy from the loadgroup.
if (aStatus != NS_IMAGELIB_CHANGING_OWNER)
proxy->RemoveFromLoadGroup(PR_TRUE);
return NS_OK;
}
nsresult imgRequest::NotifyProxyListener(imgRequestProxy *proxy)
{
nsCOMPtr<imgIRequest> kungFuDeathGrip(proxy);
// OnStartRequest
if (mState & onStartRequest)
proxy->OnStartRequest(nsnull, nsnull);
2001-04-09 00:45:06 +00:00
// OnStartDecode
2001-02-20 22:43:56 +00:00
if (mState & onStartDecode)
proxy->OnStartDecode();
2001-04-09 00:45:06 +00:00
// OnStartContainer
2001-02-20 22:43:56 +00:00
if (mState & onStartContainer)
proxy->OnStartContainer(mImage);
2001-04-09 00:45:06 +00:00
// Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
2001-04-10 05:06:57 +00:00
PRUint32 nframes = 0;
if (mImage)
mImage->GetNumFrames(&nframes);
2001-04-09 00:45:06 +00:00
if (nframes > 0) {
nsCOMPtr<gfxIImageFrame> frame;
// get the current frame or only frame
mImage->GetCurrentFrame(getter_AddRefs(frame));
NS_ENSURE_TRUE(frame, NS_ERROR_OUT_OF_MEMORY);
2001-04-09 00:45:06 +00:00
// OnStartFrame
proxy->OnStartFrame(frame);
2001-04-09 00:45:06 +00:00
if (!(mState & onStopContainer)) {
// OnDataAvailable
nsIntRect r;
frame->GetRect(r); // XXX we should only send the currently decoded rectangle here.
proxy->OnDataAvailable(frame, &r);
2001-04-09 00:45:06 +00:00
} else {
// OnDataAvailable
nsIntRect r;
2001-04-09 00:45:06 +00:00
frame->GetRect(r); // We're done loading this image, send the the whole rect
proxy->OnDataAvailable(frame, &r);
2001-04-09 00:45:06 +00:00
// OnStopFrame
proxy->OnStopFrame(frame);
2001-04-09 00:45:06 +00:00
}
}
2001-04-09 00:45:06 +00:00
// OnStopContainer
2001-02-20 22:43:56 +00:00
if (mState & onStopContainer)
proxy->OnStopContainer(mImage);
2001-04-09 00:45:06 +00:00
// OnStopDecode
2001-02-20 22:43:56 +00:00
if (mState & onStopDecode)
proxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nsnull);
if (mImage && !HaveProxyWithObserver(proxy) && proxy->HasObserver()) {
LOG_MSG(gImgLog, "imgRequest::NotifyProxyListener", "resetting animation");
2001-02-23 23:48:08 +00:00
mImage->ResetAnimation();
2001-02-23 23:48:08 +00:00
}
if (mState & onStopRequest) {
proxy->OnStopRequest(nsnull, nsnull,
GetResultFromImageStatus(mImageStatus),
mHadLastPart);
}
2001-04-09 00:45:06 +00:00
2001-02-20 22:43:56 +00:00
return NS_OK;
}
nsresult imgRequest::GetResultFromImageStatus(PRUint32 aStatus) const
{
nsresult rv = NS_OK;
2001-05-08 04:21:49 +00:00
if (aStatus & imgIRequest::STATUS_ERROR)
rv = NS_IMAGELIB_ERROR_FAILURE;
2001-05-08 04:21:49 +00:00
else if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE)
rv = NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
return rv;
}
void imgRequest::Cancel(nsresult aStatus)
{
/* The Cancel() method here should only be called by this class. */
LOG_SCOPE(gImgLog, "imgRequest::Cancel");
2001-02-20 22:43:56 +00:00
2001-02-24 00:31:08 +00:00
if (mImage) {
2001-05-08 04:21:49 +00:00
LOG_MSG(gImgLog, "imgRequest::Cancel", "stopping animation");
2001-02-24 00:31:08 +00:00
mImage->StopAnimation();
2001-02-24 00:31:08 +00:00
}
if (!(mImageStatus & imgIRequest::STATUS_LOAD_PARTIAL))
mImageStatus |= imgIRequest::STATUS_ERROR;
if (aStatus != NS_IMAGELIB_ERROR_NO_DECODER) {
RemoveFromCache();
}
if (mRequest && mLoading)
mRequest->Cancel(aStatus);
}
void imgRequest::CancelAndAbort(nsresult aStatus)
{
LOG_SCOPE(gImgLog, "imgRequest::CancelAndAbort");
Cancel(aStatus);
// It's possible for the channel to fail to open after we've set our
// notification callbacks. In that case, make sure to break the cycle between
// the channel and us, because it won't.
if (mChannel) {
mChannel->SetNotificationCallbacks(mPrevChannelSink);
mPrevChannelSink = nsnull;
}
}
nsresult imgRequest::GetURI(nsIURI **aURI)
{
LOG_FUNC(gImgLog, "imgRequest::GetURI");
if (mURI) {
*aURI = mURI;
NS_ADDREF(*aURI);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult imgRequest::GetKeyURI(nsIURI **aKeyURI)
{
LOG_FUNC(gImgLog, "imgRequest::GetKeyURI");
if (mKeyURI) {
*aKeyURI = mKeyURI;
NS_ADDREF(*aKeyURI);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult imgRequest::GetPrincipal(nsIPrincipal **aPrincipal)
{
LOG_FUNC(gImgLog, "imgRequest::GetPrincipal");
if (mPrincipal) {
NS_ADDREF(*aPrincipal = mPrincipal);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult imgRequest::GetSecurityInfo(nsISupports **aSecurityInfo)
{
LOG_FUNC(gImgLog, "imgRequest::GetSecurityInfo");
// Missing security info means this is not a security load
// i.e. it is not an error when security info is missing
NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
return NS_OK;
}
void imgRequest::RemoveFromCache()
{
LOG_SCOPE(gImgLog, "imgRequest::RemoveFromCache");
if (mIsCacheable) {
if (mCacheEntry)
imgLoader::RemoveFromCache(mCacheEntry);
else
imgLoader::RemoveFromCache(mKeyURI);
mCacheEntry = nsnull;
}
}
PRBool imgRequest::HaveProxyWithObserver(imgRequestProxy* aProxyToIgnore) const
{
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
imgRequestProxy* proxy;
2007-12-20 07:30:04 +00:00
while (iter.HasMore()) {
proxy = iter.GetNext();
if (proxy == aProxyToIgnore) {
continue;
}
if (proxy->HasObserver()) {
return PR_TRUE;
}
}
return PR_FALSE;
}
PRInt32 imgRequest::Priority() const
{
PRInt32 priority = nsISupportsPriority::PRIORITY_NORMAL;
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
if (p)
p->GetPriority(&priority);
return priority;
}
void imgRequest::AdjustPriority(imgRequestProxy *proxy, PRInt32 delta)
{
// only the first proxy is allowed to modify the priority of this image load.
//
// XXX(darin): this is probably not the most optimal algorithm as we may want
// to increase the priority of requests that have a lot of proxies. the key
// concern though is that image loads remain lower priority than other pieces
// of content such as link clicks, CSS, and JS.
//
2007-12-20 07:30:04 +00:00
if (mObservers.SafeElementAt(0, nsnull) != proxy)
return;
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
if (p)
p->AdjustPriority(delta);
}
void imgRequest::SetCacheable(PRBool cacheable)
{
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequest::SetIsCacheable", "cacheable", cacheable);
mIsCacheable = cacheable;
if (!mIsCacheable)
mCacheEntry = nsnull;
}
/** imgILoad methods **/
NS_IMETHODIMP imgRequest::SetImage(imgIContainer *aImage)
{
2001-05-08 04:21:49 +00:00
LOG_FUNC(gImgLog, "imgRequest::SetImage");
mImage = aImage;
2001-02-20 22:43:56 +00:00
return NS_OK;
}
NS_IMETHODIMP imgRequest::GetImage(imgIContainer **aImage)
{
LOG_FUNC(gImgLog, "imgRequest::GetImage");
*aImage = mImage;
NS_IF_ADDREF(*aImage);
return NS_OK;
}
NS_IMETHODIMP imgRequest::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel)
{
LOG_FUNC(gImgLog, "imgRequest::GetIsMultiPartChannel");
*aIsMultiPartChannel = mIsMultiPartChannel;
return NS_OK;
}
2001-03-10 01:11:54 +00:00
/** imgIContainerObserver methods **/
/* [noscript] void frameChanged (in imgIContainer container, in gfxIImageFrame newframe, in nsIntRect dirtyRect); */
NS_IMETHODIMP imgRequest::FrameChanged(imgIContainer *container,
gfxIImageFrame *newframe,
nsIntRect * dirtyRect)
2001-02-20 22:43:56 +00:00
{
LOG_SCOPE(gImgLog, "imgRequest::FrameChanged");
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->FrameChanged(container, newframe, dirtyRect);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
2001-02-20 23:45:51 +00:00
/** imgIDecoderObserver methods **/
/* void onStartDecode (in imgIRequest request); */
NS_IMETHODIMP imgRequest::OnStartDecode(imgIRequest *request)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartDecode");
2001-02-20 22:43:56 +00:00
mState |= onStartDecode;
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStartDecode();
2001-02-20 22:43:56 +00:00
}
/* In the case of streaming jpegs, it is possible to get multiple OnStartDecodes which
indicates the beginning of a new decode.
The cache entry's size therefore needs to be reset to 0 here. If we do not do this,
the code in imgRequest::OnStopFrame will continue to increase the data size cumulatively.
*/
if (mCacheEntry)
mCacheEntry->SetDataSize(0);
return NS_OK;
}
NS_IMETHODIMP imgRequest::OnStartRequest(imgIRequest *aRequest)
{
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStartRequest");
return NS_OK;
}
/* void onStartContainer (in imgIRequest request, in imgIContainer image); */
NS_IMETHODIMP imgRequest::OnStartContainer(imgIRequest *request, imgIContainer *image)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartContainer");
2001-05-01 02:53:27 +00:00
NS_ASSERTION(image, "imgRequest::OnStartContainer called with a null image!");
if (!image) return NS_ERROR_UNEXPECTED;
2001-02-20 22:43:56 +00:00
mState |= onStartContainer;
mImageStatus |= imgIRequest::STATUS_SIZE_AVAILABLE;
2001-02-20 22:43:56 +00:00
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStartContainer(image);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
/* void onStartFrame (in imgIRequest request, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequest::OnStartFrame(imgIRequest *request,
gfxIImageFrame *frame)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStartFrame");
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStartFrame(frame);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
/* [noscript] void onDataAvailable (in imgIRequest request, in gfxIImageFrame frame, [const] in nsIntRect rect); */
NS_IMETHODIMP imgRequest::OnDataAvailable(imgIRequest *request,
gfxIImageFrame *frame,
const nsIntRect * rect)
{
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable");
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnDataAvailable(frame, rect);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
/* void onStopFrame (in imgIRequest request, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request,
gfxIImageFrame *frame)
{
NS_ASSERTION(frame, "imgRequest::OnStopFrame called with NULL frame");
if (!frame) return NS_ERROR_UNEXPECTED;
LOG_SCOPE(gImgLog, "imgRequest::OnStopFrame");
mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE;
if (mCacheEntry) {
Bug 430061: Don't use necko's memory cache in imglib; r/sr=stuart,vlad,bz ? .fast-update ? _profile ? _tests ? obj-ff-debug ? staticlib ? README/.fast-update ? browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf ? build/pgo/automation.py ? build/pgo/profileserver.py ? config/buildid ? config/system_wrappers ? content/base/test/TestNativeXMLHttpRequest ? content/base/test/TestPlainTextSerializer ? embedding/components/printingui/src/mac/printpde/build ? gfx/thebes/public/.gfxContext.h.swp ? gfx/thebes/test/gfxFontSelectionTest ? gfx/thebes/test/gfxSurfaceRefCountTest ? gfx/thebes/test/gfxTextRunPerfTest ? gfx/thebes/test/gfxWordCacheTest ? intl/uconv/tests/TestUConv ? intl/uconv/tests/nsconv ? intl/uconv/tests/plattest ? intl/unicharutil/tests/NormalizationTest ? js/src/host_jskwgen ? js/src/jsautokw.h ? layout/style/test/css_properties.js ? layout/style/test/host_ListCSSProperties ? layout/tools/reftest/autoconf.js ? modules/libpr0n/src/.imgContainer.cpp.swp ? modules/libpr0n/src/.imgLoader.cpp.swp ? modules/libpr0n/src/.imgLoader.h.swp ? modules/libpr0n/src/.imgRequestProxy.cpp.swp ? modules/libpr0n/src/check-all-at-removal-time ? modules/libpr0n/src/currpatch ? modules/libpr0n/src/update-every-time ? modules/plugin/samples/default/mac/build ? netwerk/cache/src/.nsMemoryCacheDevice.cpp.swp ? netwerk/dns/src/etld_data.inc ? netwerk/test/ReadNTLM ? netwerk/test/TestCookie ? netwerk/test/TestIncrementalDownload ? netwerk/test/TestOpen ? netwerk/test/TestServ ? netwerk/test/TestStreamLoader ? netwerk/test/TestUDPSocketProvider ? nsprpub/.fast-update ? nsprpub/unallmakefiles ? parser/htmlparser/robot/test/htmlrobot ? parser/htmlparser/tests/grabpage/grabpage ? parser/htmlparser/tests/html/TestParser ? rdf/tests/triplescat/triplescat ? storage/test/teststorage1 ? testing/mochitest/automation.py ? testing/mochitest/automation.pyc ? testing/mochitest/runtests.pl ? testing/mochitest/runtests.py ? testing/mochitest/ssltunnel/ssltunnel ? toolkit/components/url-classifier/tests/TestUrlClassifierUtils ? toolkit/crashreporter/client/crashreporter ? toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms ? toolkit/crashreporter/test/TestCrashReporterAPI ? toolkit/library/XUL ? toolkit/mozapps/update/src/nsUpdateService.js ? toolkit/xre/platform.ini ? tools/rb ? tools/trace-malloc ? widget/src/cocoa/libwidget.rsrc ? xpcom/io/.nsStringStream.cpp.swp ? xpcom/proxy/tests/proxy-create-threadsafety ? xpcom/sample/program/nsTestSample ? xpcom/tests/TestAutoPtr ? xpcom/tests/TestExpirationTracker ? xpcom/tests/TestHashtables ? xpcom/tests/TestINIParser ? xpcom/tests/TestPipe ? xpcom/tests/TestProxies ? xpcom/tests/TestRegistrationOrder ? xpcom/tests/TestStorageStream ? xpcom/tests/TestStringAPI ? xpcom/tests/TestStrings ? xpcom/tests/TestTArray ? xpcom/tests/TestTextFormatter ? xpcom/tests/TestThreadPool ? xpcom/tests/TestVersionComparator ? xpcom/tests/external/TestMinStringAPI ? xpfe/bootstrap/appleevents/mozillaSuite.rsrc Index: modules/libpr0n/build/nsImageModule.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libpr0n/build/nsImageModule.cpp,v retrieving revision 1.20
2008-09-04 23:00:42 +00:00
PRUint32 cacheSize = mCacheEntry->GetDataSize();
PRUint32 imageSize = 0;
frame->GetImageDataLength(&imageSize);
mCacheEntry->SetDataSize(cacheSize + imageSize);
Bug 430061: Don't use necko's memory cache in imglib; r/sr=stuart,vlad,bz ? .fast-update ? _profile ? _tests ? obj-ff-debug ? staticlib ? README/.fast-update ? browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf ? build/pgo/automation.py ? build/pgo/profileserver.py ? config/buildid ? config/system_wrappers ? content/base/test/TestNativeXMLHttpRequest ? content/base/test/TestPlainTextSerializer ? embedding/components/printingui/src/mac/printpde/build ? gfx/thebes/public/.gfxContext.h.swp ? gfx/thebes/test/gfxFontSelectionTest ? gfx/thebes/test/gfxSurfaceRefCountTest ? gfx/thebes/test/gfxTextRunPerfTest ? gfx/thebes/test/gfxWordCacheTest ? intl/uconv/tests/TestUConv ? intl/uconv/tests/nsconv ? intl/uconv/tests/plattest ? intl/unicharutil/tests/NormalizationTest ? js/src/host_jskwgen ? js/src/jsautokw.h ? layout/style/test/css_properties.js ? layout/style/test/host_ListCSSProperties ? layout/tools/reftest/autoconf.js ? modules/libpr0n/src/.imgContainer.cpp.swp ? modules/libpr0n/src/.imgLoader.cpp.swp ? modules/libpr0n/src/.imgLoader.h.swp ? modules/libpr0n/src/.imgRequestProxy.cpp.swp ? modules/libpr0n/src/check-all-at-removal-time ? modules/libpr0n/src/currpatch ? modules/libpr0n/src/update-every-time ? modules/plugin/samples/default/mac/build ? netwerk/cache/src/.nsMemoryCacheDevice.cpp.swp ? netwerk/dns/src/etld_data.inc ? netwerk/test/ReadNTLM ? netwerk/test/TestCookie ? netwerk/test/TestIncrementalDownload ? netwerk/test/TestOpen ? netwerk/test/TestServ ? netwerk/test/TestStreamLoader ? netwerk/test/TestUDPSocketProvider ? nsprpub/.fast-update ? nsprpub/unallmakefiles ? parser/htmlparser/robot/test/htmlrobot ? parser/htmlparser/tests/grabpage/grabpage ? parser/htmlparser/tests/html/TestParser ? rdf/tests/triplescat/triplescat ? storage/test/teststorage1 ? testing/mochitest/automation.py ? testing/mochitest/automation.pyc ? testing/mochitest/runtests.pl ? testing/mochitest/runtests.py ? testing/mochitest/ssltunnel/ssltunnel ? toolkit/components/url-classifier/tests/TestUrlClassifierUtils ? toolkit/crashreporter/client/crashreporter ? toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms ? toolkit/crashreporter/test/TestCrashReporterAPI ? toolkit/library/XUL ? toolkit/mozapps/update/src/nsUpdateService.js ? toolkit/xre/platform.ini ? tools/rb ? tools/trace-malloc ? widget/src/cocoa/libwidget.rsrc ? xpcom/io/.nsStringStream.cpp.swp ? xpcom/proxy/tests/proxy-create-threadsafety ? xpcom/sample/program/nsTestSample ? xpcom/tests/TestAutoPtr ? xpcom/tests/TestExpirationTracker ? xpcom/tests/TestHashtables ? xpcom/tests/TestINIParser ? xpcom/tests/TestPipe ? xpcom/tests/TestProxies ? xpcom/tests/TestRegistrationOrder ? xpcom/tests/TestStorageStream ? xpcom/tests/TestStringAPI ? xpcom/tests/TestStrings ? xpcom/tests/TestTArray ? xpcom/tests/TestTextFormatter ? xpcom/tests/TestThreadPool ? xpcom/tests/TestVersionComparator ? xpcom/tests/external/TestMinStringAPI ? xpfe/bootstrap/appleevents/mozillaSuite.rsrc Index: modules/libpr0n/build/nsImageModule.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libpr0n/build/nsImageModule.cpp,v retrieving revision 1.20
2008-09-04 23:00:42 +00:00
#ifdef DEBUG_joe
nsCAutoString url;
mURI->GetSpec(url);
printf("CACHEPUT: %d %s %d\n", time(NULL), url.get(), cacheSize + imageSize);
#endif
}
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStopFrame(frame);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
/* void onStopContainer (in imgIRequest request, in imgIContainer image); */
NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request,
imgIContainer *image)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStopContainer");
2001-02-20 22:43:56 +00:00
mState |= onStopContainer;
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStopContainer(image);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
/* void onStopDecode (in imgIRequest request, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgRequest::OnStopDecode(imgIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aStatusArg)
{
LOG_SCOPE(gImgLog, "imgRequest::OnStopDecode");
NS_ASSERTION(!(mState & onStopDecode), "OnStopDecode called multiple times.");
2001-04-09 00:45:06 +00:00
2001-02-20 22:43:56 +00:00
mState |= onStopDecode;
if (NS_FAILED(aStatus) && !(mImageStatus & imgIRequest::STATUS_LOAD_PARTIAL)) {
mImageStatus |= imgIRequest::STATUS_ERROR;
2001-08-21 20:17:22 +00:00
}
2001-02-20 22:43:56 +00:00
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStopDecode(GetResultFromImageStatus(mImageStatus), aStatusArg);
2001-02-20 22:43:56 +00:00
}
return NS_OK;
}
NS_IMETHODIMP imgRequest::OnStopRequest(imgIRequest *aRequest,
PRBool aLastPart)
{
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStopRequest");
return NS_OK;
}
/** nsIRequestObserver methods **/
2001-02-22 08:41:20 +00:00
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt)
{
nsresult rv;
LOG_SCOPE(gImgLog, "imgRequest::OnStartRequest");
NS_ASSERTION(!mDecoder, "imgRequest::OnStartRequest -- we already have a decoder");
nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));
if (mpchan)
mIsMultiPartChannel = PR_TRUE;
/*
* If mRequest is null here, then we need to set it so that we'll be able to
* cancel it if our Cancel() method is called. Note that this can only
* happen for multipart channels. We could simply not null out mRequest for
* non-last parts, if GetIsLastPart() were reliable, but it's not. See
* https://bugzilla.mozilla.org/show_bug.cgi?id=339610
*/
if (!mRequest) {
NS_ASSERTION(mpchan,
"We should have an mRequest here unless we're multipart");
nsCOMPtr<nsIChannel> chan;
mpchan->GetBaseChannel(getter_AddRefs(chan));
mRequest = chan;
}
/* set our state variables to their initial values, but advance mState
to onStartRequest. */
mImageStatus = imgIRequest::STATUS_NONE;
mState = onStartRequest;
2001-03-14 00:39:48 +00:00
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
if (channel)
channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
2001-03-14 00:39:48 +00:00
/* set our loading flag to true */
mLoading = PR_TRUE;
/* notify our kids */
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStartRequest(aRequest, ctxt);
}
/* Get our principal */
2001-02-22 08:41:20 +00:00
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
if (chan) {
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService("@mozilla.org/scriptsecuritymanager;1");
if (secMan) {
nsresult rv = secMan->GetChannelPrincipal(chan,
getter_AddRefs(mPrincipal));
if (NS_FAILED(rv)) {
return rv;
}
}
}
2001-02-22 08:41:20 +00:00
/* 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) {
2001-03-19 21:57:39 +00:00
PRUint32 expiration;
/* get the expiration time from the caching channel's token */
entryDesc->GetExpirationTime(&expiration);
/* set the expiration time on our entry */
Bug 430061: Don't use necko's memory cache in imglib; r/sr=stuart,vlad,bz ? .fast-update ? _profile ? _tests ? obj-ff-debug ? staticlib ? README/.fast-update ? browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf ? build/pgo/automation.py ? build/pgo/profileserver.py ? config/buildid ? config/system_wrappers ? content/base/test/TestNativeXMLHttpRequest ? content/base/test/TestPlainTextSerializer ? embedding/components/printingui/src/mac/printpde/build ? gfx/thebes/public/.gfxContext.h.swp ? gfx/thebes/test/gfxFontSelectionTest ? gfx/thebes/test/gfxSurfaceRefCountTest ? gfx/thebes/test/gfxTextRunPerfTest ? gfx/thebes/test/gfxWordCacheTest ? intl/uconv/tests/TestUConv ? intl/uconv/tests/nsconv ? intl/uconv/tests/plattest ? intl/unicharutil/tests/NormalizationTest ? js/src/host_jskwgen ? js/src/jsautokw.h ? layout/style/test/css_properties.js ? layout/style/test/host_ListCSSProperties ? layout/tools/reftest/autoconf.js ? modules/libpr0n/src/.imgContainer.cpp.swp ? modules/libpr0n/src/.imgLoader.cpp.swp ? modules/libpr0n/src/.imgLoader.h.swp ? modules/libpr0n/src/.imgRequestProxy.cpp.swp ? modules/libpr0n/src/check-all-at-removal-time ? modules/libpr0n/src/currpatch ? modules/libpr0n/src/update-every-time ? modules/plugin/samples/default/mac/build ? netwerk/cache/src/.nsMemoryCacheDevice.cpp.swp ? netwerk/dns/src/etld_data.inc ? netwerk/test/ReadNTLM ? netwerk/test/TestCookie ? netwerk/test/TestIncrementalDownload ? netwerk/test/TestOpen ? netwerk/test/TestServ ? netwerk/test/TestStreamLoader ? netwerk/test/TestUDPSocketProvider ? nsprpub/.fast-update ? nsprpub/unallmakefiles ? parser/htmlparser/robot/test/htmlrobot ? parser/htmlparser/tests/grabpage/grabpage ? parser/htmlparser/tests/html/TestParser ? rdf/tests/triplescat/triplescat ? storage/test/teststorage1 ? testing/mochitest/automation.py ? testing/mochitest/automation.pyc ? testing/mochitest/runtests.pl ? testing/mochitest/runtests.py ? testing/mochitest/ssltunnel/ssltunnel ? toolkit/components/url-classifier/tests/TestUrlClassifierUtils ? toolkit/crashreporter/client/crashreporter ? toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms ? toolkit/crashreporter/test/TestCrashReporterAPI ? toolkit/library/XUL ? toolkit/mozapps/update/src/nsUpdateService.js ? toolkit/xre/platform.ini ? tools/rb ? tools/trace-malloc ? widget/src/cocoa/libwidget.rsrc ? xpcom/io/.nsStringStream.cpp.swp ? xpcom/proxy/tests/proxy-create-threadsafety ? xpcom/sample/program/nsTestSample ? xpcom/tests/TestAutoPtr ? xpcom/tests/TestExpirationTracker ? xpcom/tests/TestHashtables ? xpcom/tests/TestINIParser ? xpcom/tests/TestPipe ? xpcom/tests/TestProxies ? xpcom/tests/TestRegistrationOrder ? xpcom/tests/TestStorageStream ? xpcom/tests/TestStringAPI ? xpcom/tests/TestStrings ? xpcom/tests/TestTArray ? xpcom/tests/TestTextFormatter ? xpcom/tests/TestThreadPool ? xpcom/tests/TestVersionComparator ? xpcom/tests/external/TestMinStringAPI ? xpfe/bootstrap/appleevents/mozillaSuite.rsrc Index: modules/libpr0n/build/nsImageModule.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libpr0n/build/nsImageModule.cpp,v retrieving revision 1.20
2008-09-04 23:00:42 +00:00
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;
}
}
Bug 430061: Don't use necko's memory cache in imglib; r/sr=stuart,vlad,bz ? .fast-update ? _profile ? _tests ? obj-ff-debug ? staticlib ? README/.fast-update ? browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf ? build/pgo/automation.py ? build/pgo/profileserver.py ? config/buildid ? config/system_wrappers ? content/base/test/TestNativeXMLHttpRequest ? content/base/test/TestPlainTextSerializer ? embedding/components/printingui/src/mac/printpde/build ? gfx/thebes/public/.gfxContext.h.swp ? gfx/thebes/test/gfxFontSelectionTest ? gfx/thebes/test/gfxSurfaceRefCountTest ? gfx/thebes/test/gfxTextRunPerfTest ? gfx/thebes/test/gfxWordCacheTest ? intl/uconv/tests/TestUConv ? intl/uconv/tests/nsconv ? intl/uconv/tests/plattest ? intl/unicharutil/tests/NormalizationTest ? js/src/host_jskwgen ? js/src/jsautokw.h ? layout/style/test/css_properties.js ? layout/style/test/host_ListCSSProperties ? layout/tools/reftest/autoconf.js ? modules/libpr0n/src/.imgContainer.cpp.swp ? modules/libpr0n/src/.imgLoader.cpp.swp ? modules/libpr0n/src/.imgLoader.h.swp ? modules/libpr0n/src/.imgRequestProxy.cpp.swp ? modules/libpr0n/src/check-all-at-removal-time ? modules/libpr0n/src/currpatch ? modules/libpr0n/src/update-every-time ? modules/plugin/samples/default/mac/build ? netwerk/cache/src/.nsMemoryCacheDevice.cpp.swp ? netwerk/dns/src/etld_data.inc ? netwerk/test/ReadNTLM ? netwerk/test/TestCookie ? netwerk/test/TestIncrementalDownload ? netwerk/test/TestOpen ? netwerk/test/TestServ ? netwerk/test/TestStreamLoader ? netwerk/test/TestUDPSocketProvider ? nsprpub/.fast-update ? nsprpub/unallmakefiles ? parser/htmlparser/robot/test/htmlrobot ? parser/htmlparser/tests/grabpage/grabpage ? parser/htmlparser/tests/html/TestParser ? rdf/tests/triplescat/triplescat ? storage/test/teststorage1 ? testing/mochitest/automation.py ? testing/mochitest/automation.pyc ? testing/mochitest/runtests.pl ? testing/mochitest/runtests.py ? testing/mochitest/ssltunnel/ssltunnel ? toolkit/components/url-classifier/tests/TestUrlClassifierUtils ? toolkit/crashreporter/client/crashreporter ? toolkit/crashreporter/google-breakpad/src/tools/mac/dump_syms/dump_syms ? toolkit/crashreporter/test/TestCrashReporterAPI ? toolkit/library/XUL ? toolkit/mozapps/update/src/nsUpdateService.js ? toolkit/xre/platform.ini ? tools/rb ? tools/trace-malloc ? widget/src/cocoa/libwidget.rsrc ? xpcom/io/.nsStringStream.cpp.swp ? xpcom/proxy/tests/proxy-create-threadsafety ? xpcom/sample/program/nsTestSample ? xpcom/tests/TestAutoPtr ? xpcom/tests/TestExpirationTracker ? xpcom/tests/TestHashtables ? xpcom/tests/TestINIParser ? xpcom/tests/TestPipe ? xpcom/tests/TestProxies ? xpcom/tests/TestRegistrationOrder ? xpcom/tests/TestStorageStream ? xpcom/tests/TestStringAPI ? xpcom/tests/TestStrings ? xpcom/tests/TestTArray ? xpcom/tests/TestTextFormatter ? xpcom/tests/TestThreadPool ? xpcom/tests/TestVersionComparator ? xpcom/tests/external/TestMinStringAPI ? xpfe/bootstrap/appleevents/mozillaSuite.rsrc Index: modules/libpr0n/build/nsImageModule.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libpr0n/build/nsImageModule.cpp,v retrieving revision 1.20
2008-09-04 23:00:42 +00:00
mCacheEntry->SetMustValidateIfExpired(bMustRevalidate);
}
2001-02-24 23:45:30 +00:00
}
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
if (mObservers.IsEmpty()) {
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
}
return NS_OK;
}
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status); */
NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt, nsresult status)
{
2001-05-08 04:21:49 +00:00
LOG_FUNC(gImgLog, "imgRequest::OnStopRequest");
2001-02-20 22:43:56 +00:00
mState |= onStopRequest;
2001-03-14 00:39:48 +00:00
/* set our loading flag to false */
mLoading = PR_FALSE;
/* set our processing flag to false */
mProcessing = PR_FALSE;
2001-02-20 22:43:56 +00:00
mHadLastPart = PR_TRUE;
nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));
if (mpchan) {
PRBool lastPart;
nsresult rv = mpchan->GetIsLastPart(&lastPart);
if (NS_SUCCEEDED(rv))
mHadLastPart = lastPart;
}
// XXXldb What if this is a non-last part of a multipart request?
// xxx before we release our reference to mRequest, lets
// save the last status that we saw so that the
// imgRequestProxy will have access to it.
if (mRequest) {
mRequest = nsnull; // we no longer need the request
}
// stop holding a ref to the channel, since we don't need it anymore
if (mChannel) {
mChannel->SetNotificationCallbacks(mPrevChannelSink);
mPrevChannelSink = nsnull;
mChannel = nsnull;
}
2001-05-01 02:53:27 +00:00
// If mImage is still null, we didn't properly load the image.
if (NS_FAILED(status) || !mImage) {
this->Cancel(status); // sets status, stops animations, removes from cache
2001-04-09 00:45:06 +00:00
} else {
mImageStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
}
if (mDecoder) {
mDecoder->Flush();
mDecoder->Close();
mDecoder = nsnull; // release the decoder so that it can rest peacefully ;)
}
2001-04-09 00:45:06 +00:00
// if there was an error loading the image, (mState & onStopDecode) won't be true.
// Send an onStopDecode message
if (!(mState & onStopDecode)) {
this->OnStopDecode(nsnull, status, nsnull);
2001-04-09 00:45:06 +00:00
}
/* notify the kids */
2007-12-20 07:30:04 +00:00
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
while (iter.HasMore()) {
iter.GetNext()->OnStopRequest(aRequest, ctxt, status, mHadLastPart);
}
2001-02-20 22:43:56 +00:00
return NS_OK;
}
2001-03-14 00:39:48 +00:00
/* prototype for this defined below */
static NS_METHOD sniff_mimetype_callback(nsIInputStream* in, void* closure, const char* fromRawSegment,
PRUint32 toOffset, PRUint32 count, PRUint32 *writeCount);
2001-03-14 00:39:48 +00:00
/** nsIStreamListener methods **/
2001-02-22 08:41:20 +00:00
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */
NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
{
2001-05-08 04:21:49 +00:00
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "count", count);
NS_ASSERTION(aRequest, "imgRequest::OnDataAvailable -- no request!");
2001-03-14 00:39:48 +00:00
mGotData = PR_TRUE;
2001-03-14 00:39:48 +00:00
if (!mProcessing) {
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable |First time through... finding mimetype|");
2001-03-14 00:39:48 +00:00
/* set our processing flag to true if this is the first OnDataAvailable() */
mProcessing = PR_TRUE;
/* look at the first few bytes and see if we can tell what the data is from that
* since servers tend to lie. :(
*/
PRUint32 out;
inStr->ReadSegments(sniff_mimetype_callback, this, count, &out);
#ifdef NS_DEBUG
/* NS_WARNING if the content type from the channel isn't the same if the sniffing */
#endif
if (mContentType.IsEmpty()) {
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable |sniffing of mimetype failed|");
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
nsresult rv = NS_ERROR_FAILURE;
if (chan) {
rv = chan->GetContentType(mContentType);
}
2001-03-14 00:39:48 +00:00
if (NS_FAILED(rv)) {
PR_LOG(gImgLog, PR_LOG_ERROR,
("[this=%p] imgRequest::OnDataAvailable -- Content type unavailable from the channel\n",
2001-03-14 00:39:48 +00:00
this));
2001-08-21 20:17:22 +00:00
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
2001-03-14 00:39:48 +00:00
return NS_BINDING_ABORTED;
2001-03-14 00:39:48 +00:00
}
2001-05-08 04:21:49 +00:00
LOG_MSG(gImgLog, "imgRequest::OnDataAvailable", "Got content type from the channel");
2001-03-14 00:39:48 +00:00
}
/* set our mimetype as a property */
nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));
if (contentType) {
contentType->SetData(mContentType);
mProperties->Set("type", contentType);
}
/* set our content disposition as a property */
nsCAutoString disposition;
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
if (httpChannel) {
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-disposition"), disposition);
} else {
nsCOMPtr<nsIMultiPartChannel> multiPartChannel(do_QueryInterface(aRequest));
if (multiPartChannel) {
multiPartChannel->GetContentDisposition(disposition);
}
}
if (!disposition.IsEmpty()) {
nsCOMPtr<nsISupportsCString> contentDisposition(do_CreateInstance("@mozilla.org/supports-cstring;1"));
if (contentDisposition) {
contentDisposition->SetData(disposition);
mProperties->Set("content-disposition", contentDisposition);
}
}
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "content type", mContentType.get());
2001-03-14 00:39:48 +00:00
nsCAutoString conid(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;2?type=") + mContentType);
2001-03-14 00:39:48 +00:00
mDecoder = do_CreateInstance(conid.get());
2001-03-14 00:39:48 +00:00
if (!mDecoder) {
PR_LOG(gImgLog, PR_LOG_WARNING,
("[this=%p] imgRequest::OnDataAvailable -- Decoder not available\n", this));
2001-03-14 00:39:48 +00:00
// no image decoder for this mimetype :(
2001-08-21 20:17:22 +00:00
this->Cancel(NS_IMAGELIB_ERROR_NO_DECODER);
2001-03-14 00:39:48 +00:00
2001-04-09 00:45:06 +00:00
return NS_IMAGELIB_ERROR_NO_DECODER;
2001-03-14 00:39:48 +00:00
}
nsresult rv = mDecoder->Init(static_cast<imgILoad*>(this));
2001-04-30 23:00:02 +00:00
if (NS_FAILED(rv)) {
PR_LOG(gImgLog, PR_LOG_WARNING,
("[this=%p] imgRequest::OnDataAvailable -- mDecoder->Init failed\n", this));
2001-08-21 20:17:22 +00:00
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
2001-04-30 23:00:02 +00:00
return NS_BINDING_ABORTED;
}
2001-03-14 00:39:48 +00:00
}
2001-02-20 22:43:56 +00:00
if (!mDecoder) {
PR_LOG(gImgLog, PR_LOG_WARNING,
("[this=%p] imgRequest::OnDataAvailable -- no decoder\n", this));
2001-02-25 09:02:25 +00:00
2001-08-21 20:17:22 +00:00
this->Cancel(NS_IMAGELIB_ERROR_NO_DECODER);
return NS_BINDING_ABORTED;
2001-02-20 22:43:56 +00:00
}
PRUint32 wrote;
nsresult rv = mDecoder->WriteFrom(inStr, count, &wrote);
if (NS_FAILED(rv)) {
PR_LOG(gImgLog, PR_LOG_WARNING,
("[this=%p] imgRequest::OnDataAvailable -- mDecoder->WriteFrom failed\n", this));
2001-08-21 20:17:22 +00:00
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
return NS_BINDING_ABORTED;
}
return NS_OK;
}
2001-03-14 00:39:48 +00:00
static NS_METHOD sniff_mimetype_callback(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
imgRequest *request = static_cast<imgRequest*>(closure);
2001-03-14 00:39:48 +00:00
NS_ASSERTION(request, "request is null!");
if (count > 0)
request->SniffMimeType(fromRawSegment, count);
*writeCount = 0;
return NS_ERROR_FAILURE;
}
void
imgRequest::SniffMimeType(const char *buf, PRUint32 len)
{
imgLoader::GetMimeTypeFromContent(buf, len, mContentType);
// The vast majority of the time, imgLoader will find a gif/jpeg/png image
// and fill mContentType with the sniffed MIME type.
if (!mContentType.IsEmpty())
return;
// When our sniffing fails, we want to query registered image decoders
// to see if they can identify the image. If we always trusted the server
// to send the right MIME, images sent as text/plain would not be rendered.
const nsCOMArray<nsIContentSniffer>& sniffers = mImageSniffers.GetEntries();
PRUint32 length = sniffers.Count();
for (PRUint32 i = 0; i < length; ++i) {
nsresult rv =
sniffers[i]->GetMIMETypeFromContent(nsnull, (const PRUint8 *) buf, len, mContentType);
if (NS_SUCCEEDED(rv) && !mContentType.IsEmpty()) {
return;
}
}
}
/** nsIInterfaceRequestor methods **/
NS_IMETHODIMP
imgRequest::GetInterface(const nsIID & aIID, void **aResult)
{
if (!mPrevChannelSink || aIID.Equals(NS_GET_IID(nsIChannelEventSink)))
return QueryInterface(aIID, aResult);
NS_ASSERTION(mPrevChannelSink != this,
"Infinite recursion - don't keep track of channel sinks that are us!");
return mPrevChannelSink->GetInterface(aIID, aResult);
}
/** nsIChannelEventSink methods **/
/* void onChannelRedirect (in nsIChannel oldChannel, in nsIChannel newChannel, in unsigned long flags); */
NS_IMETHODIMP
imgRequest::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, PRUint32 flags)
{
NS_ASSERTION(mRequest && mChannel, "Got an OnChannelRedirect after we nulled out mRequest!");
NS_ASSERTION(mChannel == oldChannel, "Got a channel redirect for an unknown channel!");
NS_ASSERTION(newChannel, "Got a redirect to a NULL channel!");
nsresult rv = NS_OK;
nsCOMPtr<nsIChannelEventSink> sink(do_GetInterface(mPrevChannelSink));
if (sink) {
rv = sink->OnChannelRedirect(oldChannel, newChannel, flags);
if (NS_FAILED(rv))
return rv;
}
#if defined(PR_LOGGING)
nsCAutoString spec;
mKeyURI->GetSpec(spec);
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnChannelRedirect", "old", spec.get());
#endif
RemoveFromCache();
mChannel = newChannel;
newChannel->GetOriginalURI(getter_AddRefs(mKeyURI));
#if defined(PR_LOGGING)
mKeyURI->GetSpec(spec);
LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnChannelRedirect", "new", spec.get());
#endif
if (mIsCacheable) {
// If we don't still have a cache entry, we don't want to refresh the cache.
if (mKeyURI && mCacheEntry)
imgLoader::PutIntoCache(mKeyURI, mCacheEntry);
}
return rv;
}