2001-01-22 22:01:03 +00:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
2004-04-18 22:01:16 +00:00
* * * * * * 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 .
*
2001-01-22 22:01:03 +00:00
* The Original Code is mozilla . org code .
2004-04-18 22:01:16 +00:00
*
* 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 .
*
2001-01-22 22:01:03 +00:00
* Contributor ( s ) :
2006-03-14 06:24:02 +00:00
* Stuart Parmenter < stuart @ mozilla . com >
2004-04-18 22:01:16 +00:00
*
* 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 * * * * * */
2001-01-22 22:01:03 +00:00
2001-02-20 23:27:48 +00:00
# include "imgRequest.h"
2001-01-22 22:01:03 +00:00
2002-05-24 20:54:44 +00:00
# include "imgLoader.h"
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
# 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"
2002-05-03 07:49:43 +00:00
# include "netCore.h"
2001-01-22 22:01:03 +00:00
# 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"
2001-01-22 22:01:03 +00:00
# include "nsIInputStream.h"
2002-03-10 22:29:14 +00:00
# include "nsIMultiPartChannel.h"
2002-09-18 22:08:12 +00:00
# include "nsIHttpChannel.h"
2001-03-25 11:57:25 +00:00
2001-01-22 22:01:03 +00:00
# include "nsIComponentManager.h"
2008-12-22 22:20:46 +00:00
# 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"
2005-03-23 21:09:02 +00:00
# include "nsISupportsPrimitives.h"
2007-11-09 02:55:41 +00:00
# include "nsIScriptSecurityManager.h"
2001-01-22 22:01:03 +00:00
2008-09-04 23:00:42 +00:00
# include "nsICacheVisitor.h"
2001-01-22 22:01:03 +00:00
# include "nsString.h"
2001-03-14 00:39:48 +00:00
# include "nsXPIDLString.h"
2002-09-18 22:08:12 +00:00
# include "plstr.h" // PL_strcasestr(...)
2001-01-22 22:01:03 +00:00
2001-02-22 02:06:24 +00:00
# if defined(PR_LOGGING)
PRLogModuleInfo * gImgLog = PR_NewLogModule ( " imgRequest " ) ;
# endif
2001-01-22 22:01:03 +00:00
2008-12-22 22:20:46 +00:00
NS_IMPL_ISUPPORTS8 ( imgRequest , imgILoad ,
2006-03-14 06:24:02 +00:00
imgIDecoderObserver , imgIContainerObserver ,
nsIStreamListener , nsIRequestObserver ,
2008-12-22 22:20:46 +00:00
nsISupportsWeakReference ,
nsIChannelEventSink ,
nsIInterfaceRequestor )
2001-01-22 22:01:03 +00:00
2001-02-20 23:27:48 +00:00
imgRequest : : imgRequest ( ) :
2009-03-05 03:56:14 +00:00
mImageStatus ( imgIRequest : : STATUS_NONE ) , mState ( 0 ) , mCacheId ( 0 ) ,
mValidator ( nsnull ) , mImageSniffers ( " image-sniffing-services " ) ,
mIsMultiPartChannel ( PR_FALSE ) , mLoading ( PR_FALSE ) , mProcessing ( PR_FALSE ) ,
2009-03-12 04:22:50 +00:00
mHadLastPart ( PR_FALSE ) , mGotData ( PR_FALSE ) , mIsCacheable ( PR_TRUE )
2001-01-22 22:01:03 +00:00
{
/* member initializers and constructor code */
}
2001-02-20 23:27:48 +00:00
imgRequest : : ~ imgRequest ( )
2001-01-22 22:01:03 +00:00
{
2009-01-31 02:17:47 +00:00
if ( mKeyURI ) {
nsCAutoString spec ;
mKeyURI - > GetSpec ( spec ) ;
LOG_FUNC_WITH_PARAM ( gImgLog , " imgRequest::~imgRequest() " , " keyuri " , spec . get ( ) ) ;
} else
LOG_FUNC ( gImgLog , " imgRequest::~imgRequest() " ) ;
2001-01-22 22:01:03 +00:00
}
2006-03-11 20:32:47 +00:00
nsresult imgRequest : : Init ( nsIURI * aURI ,
2008-12-24 01:31:30 +00:00
nsIURI * aKeyURI ,
2006-03-11 20:32:47 +00:00
nsIRequest * aRequest ,
2008-12-22 22:20:46 +00:00
nsIChannel * aChannel ,
2008-09-04 23:00:42 +00:00
imgCacheEntry * aCacheEntry ,
2002-01-15 05:23:33 +00:00
void * aCacheId ,
void * aLoadId )
2001-01-22 22:01:03 +00:00
{
2001-05-08 04:21:49 +00:00
LOG_FUNC ( gImgLog , " imgRequest::Init " ) ;
2001-02-22 02:12:21 +00:00
2009-01-31 02:17:47 +00:00
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 " ) ;
2001-01-22 22:01:03 +00:00
2005-03-23 21:09:02 +00:00
mProperties = do_CreateInstance ( " @mozilla.org/properties;1 " ) ;
if ( ! mProperties )
return NS_ERROR_OUT_OF_MEMORY ;
2009-01-31 02:17:47 +00:00
2006-03-11 20:32:47 +00:00
mURI = aURI ;
2008-12-24 01:31:30 +00:00
mKeyURI = aKeyURI ;
2006-03-11 20:32:47 +00:00
mRequest = aRequest ;
2008-12-22 22:20:46 +00:00
mChannel = aChannel ;
mChannel - > GetNotificationCallbacks ( getter_AddRefs ( mPrevChannelSink ) ) ;
NS_ASSERTION ( mPrevChannelSink ! = this ,
" Initializing with a channel that already calls back to us! " ) ;
mChannel - > SetNotificationCallbacks ( this ) ;
2001-01-22 22:01:03 +00:00
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
/* 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 .
*/
2002-01-15 05:23:33 +00:00
mLoading = PR_TRUE ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2001-03-16 02:40:04 +00:00
mCacheEntry = aCacheEntry ;
2001-10-17 05:57:29 +00:00
mCacheId = aCacheId ;
2002-01-15 05:23:33 +00:00
SetLoadId ( aLoadId ) ;
2001-01-23 02:02:29 +00:00
return NS_OK ;
2001-01-22 22:01:03 +00:00
}
2009-01-31 02:17:47 +00:00
void imgRequest : : SetCacheEntry ( imgCacheEntry * entry )
{
mCacheEntry = entry ;
}
PRBool imgRequest : : HasCacheEntry ( ) const
{
return mCacheEntry ! = nsnull ;
}
2007-09-22 19:40:57 +00:00
nsresult imgRequest : : AddProxy ( imgRequestProxy * proxy )
2001-01-22 22:01:03 +00:00
{
2007-09-22 19:40:57 +00:00
NS_PRECONDITION ( proxy , " null imgRequestProxy passed in " ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
LOG_SCOPE_WITH_PARAM ( gImgLog , " imgRequest::AddProxy " , " proxy " , proxy ) ;
2001-02-22 02:06:24 +00:00
2009-01-31 02:17:47 +00:00
// 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 ) ?
2007-12-14 01:41:48 +00:00
NS_OK : NS_ERROR_OUT_OF_MEMORY ;
2002-01-15 05:23:33 +00:00
}
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 ) ;
2002-01-15 05:23:33 +00:00
/* 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 ) ) {
2006-06-01 18:35:21 +00:00
proxy - > OnStopRequest ( nsnull , nsnull , NS_BINDING_ABORTED , PR_TRUE ) ;
2002-01-15 05:23:33 +00:00
}
2004-07-29 17:09:42 +00:00
if ( mImage & & ! HaveProxyWithObserver ( nsnull ) ) {
LOG_MSG ( gImgLog , " imgRequest::RemoveProxy " , " stopping animation " ) ;
2002-01-15 05:23:33 +00:00
2004-07-29 17:09:42 +00:00
mImage - > StopAnimation ( ) ;
}
2002-01-15 05:23:33 +00:00
2007-09-22 19:40:57 +00:00
if ( mObservers . IsEmpty ( ) ) {
2009-01-31 02:17:47 +00:00
// 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
2002-01-15 05:23:33 +00:00
/* 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 .
*/
2006-03-11 20:32:47 +00:00
if ( mRequest & & mLoading & & NS_FAILED ( aStatus ) ) {
2002-01-15 05:23:33 +00:00
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 ;
}
2003-05-14 05:42:06 +00:00
// 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 )
2005-10-03 22:27:20 +00:00
proxy - > RemoveFromLoadGroup ( PR_TRUE ) ;
2003-05-14 05:42:06 +00:00
2002-01-15 05:23:33 +00:00
return NS_OK ;
}
nsresult imgRequest : : NotifyProxyListener ( imgRequestProxy * proxy )
{
nsCOMPtr < imgIRequest > kungFuDeathGrip ( proxy ) ;
2006-06-01 18:35:21 +00:00
// 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 )
2001-10-12 07:59:21 +00:00
proxy - > OnStartDecode ( ) ;
2001-04-09 00:45:06 +00:00
// OnStartContainer
2001-02-20 22:43:56 +00:00
if ( mState & onStartContainer )
2001-10-12 07:59:21 +00:00
proxy - > OnStartContainer ( mImage ) ;
2001-01-22 22:01:03 +00:00
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 ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
// get the current frame or only frame
mImage - > GetCurrentFrame ( getter_AddRefs ( frame ) ) ;
2008-11-24 16:57:47 +00:00
NS_ENSURE_TRUE ( frame , NS_ERROR_OUT_OF_MEMORY ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2001-04-09 00:45:06 +00:00
// OnStartFrame
2001-10-12 07:59:21 +00:00
proxy - > OnStartFrame ( frame ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2001-04-09 00:45:06 +00:00
if ( ! ( mState & onStopContainer ) ) {
// OnDataAvailable
2004-11-15 04:16:07 +00:00
nsIntRect r ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
frame - > GetRect ( r ) ; // XXX we should only send the currently decoded rectangle here.
2001-10-12 07:59:21 +00:00
proxy - > OnDataAvailable ( frame , & r ) ;
2001-04-09 00:45:06 +00:00
} else {
// OnDataAvailable
2004-11-15 04:16:07 +00:00
nsIntRect r ;
2001-04-09 00:45:06 +00:00
frame - > GetRect ( r ) ; // We're done loading this image, send the the whole rect
2001-10-12 07:59:21 +00:00
proxy - > OnDataAvailable ( frame , & r ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2001-04-09 00:45:06 +00:00
// OnStopFrame
2001-10-12 07:59:21 +00:00
proxy - > OnStopFrame ( frame ) ;
2001-04-09 00:45:06 +00:00
}
}
2001-01-22 22:01:03 +00:00
2001-04-09 00:45:06 +00:00
// OnStopContainer
2001-02-20 22:43:56 +00:00
if ( mState & onStopContainer )
2001-10-12 07:59:21 +00:00
proxy - > OnStopContainer ( mImage ) ;
2001-04-09 00:45:06 +00:00
// OnStopDecode
2001-02-20 22:43:56 +00:00
if ( mState & onStopDecode )
2001-10-12 07:59:21 +00:00
proxy - > OnStopDecode ( GetResultFromImageStatus ( mImageStatus ) , nsnull ) ;
2001-01-22 22:01:03 +00:00
2004-07-29 17:09:42 +00:00
if ( mImage & & ! HaveProxyWithObserver ( proxy ) & & proxy - > HasObserver ( ) ) {
2009-03-05 03:56:14 +00:00
LOG_MSG ( gImgLog , " imgRequest::NotifyProxyListener " , " resetting animation " ) ;
2001-02-23 23:48:08 +00:00
2002-10-10 04:43:13 +00:00
mImage - > ResetAnimation ( ) ;
2001-02-23 23:48:08 +00:00
}
2001-03-06 21:54:33 +00:00
if ( mState & onStopRequest ) {
2006-06-01 18:35:21 +00:00
proxy - > OnStopRequest ( nsnull , nsnull ,
GetResultFromImageStatus ( mImageStatus ) ,
mHadLastPart ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
}
2001-04-09 00:45:06 +00:00
2001-02-20 22:43:56 +00:00
return NS_OK ;
2001-01-22 22:01:03 +00:00
}
2001-10-12 07:59:21 +00:00
nsresult imgRequest : : GetResultFromImageStatus ( PRUint32 aStatus ) const
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
{
nsresult rv = NS_OK ;
2001-05-08 04:21:49 +00:00
if ( aStatus & imgIRequest : : STATUS_ERROR )
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
rv = NS_IMAGELIB_ERROR_FAILURE ;
2001-05-08 04:21:49 +00:00
else if ( aStatus & imgIRequest : : STATUS_LOAD_COMPLETE )
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
rv = NS_IMAGELIB_SUCCESS_LOAD_FINISHED ;
2001-02-22 02:06:24 +00:00
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
return rv ;
2001-02-26 04:22:47 +00:00
}
2001-10-12 06:43:52 +00:00
void imgRequest : : Cancel ( nsresult aStatus )
2001-02-26 04:22:47 +00:00
{
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
/* The Cancel() method here should only be called by this class. */
2001-02-26 04:22:47 +00:00
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
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
mImage - > StopAnimation ( ) ;
2001-02-24 00:31:08 +00:00
}
2001-10-12 06:43:52 +00:00
if ( ! ( mImageStatus & imgIRequest : : STATUS_LOAD_PARTIAL ) )
mImageStatus | = imgIRequest : : STATUS_ERROR ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2006-08-24 02:02:30 +00:00
if ( aStatus ! = NS_IMAGELIB_ERROR_NO_DECODER ) {
RemoveFromCache ( ) ;
}
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2009-01-29 19:18:56 +00:00
if ( mRequest & & mLoading )
mRequest - > Cancel ( aStatus ) ;
2008-12-22 22:20:46 +00:00
}
void imgRequest : : CancelAndAbort ( nsresult aStatus )
{
2009-01-31 02:17:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::CancelAndAbort " ) ;
2008-12-22 22:20:46 +00:00
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 ;
}
2001-03-06 04:46:20 +00:00
}
2001-10-12 06:43:52 +00:00
nsresult imgRequest : : GetURI ( nsIURI * * aURI )
2001-03-06 04:46:20 +00:00
{
2001-10-12 06:43:52 +00:00
LOG_FUNC ( gImgLog , " imgRequest::GetURI " ) ;
2001-03-06 04:46:20 +00:00
2001-10-12 06:43:52 +00:00
if ( mURI ) {
* aURI = mURI ;
NS_ADDREF ( * aURI ) ;
2001-04-14 02:02:19 +00:00
return NS_OK ;
2001-10-12 06:43:52 +00:00
}
return NS_ERROR_FAILURE ;
2001-04-10 06:01:08 +00:00
}
2008-12-24 01:31:30 +00:00
nsresult imgRequest : : GetKeyURI ( nsIURI * * aKeyURI )
{
LOG_FUNC ( gImgLog , " imgRequest::GetKeyURI " ) ;
if ( mKeyURI ) {
* aKeyURI = mKeyURI ;
NS_ADDREF ( * aKeyURI ) ;
return NS_OK ;
}
return NS_ERROR_FAILURE ;
}
2007-11-09 02:55:41 +00:00
nsresult imgRequest : : GetPrincipal ( nsIPrincipal * * aPrincipal )
{
LOG_FUNC ( gImgLog , " imgRequest::GetPrincipal " ) ;
if ( mPrincipal ) {
NS_ADDREF ( * aPrincipal = mPrincipal ) ;
return NS_OK ;
}
return NS_ERROR_FAILURE ;
}
2008-09-01 20:53:59 +00:00
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 ;
}
2001-10-12 06:43:52 +00:00
void imgRequest : : RemoveFromCache ( )
2001-01-22 22:01:03 +00:00
{
2001-10-12 06:43:52 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::RemoveFromCache " ) ;
2001-02-22 02:06:24 +00:00
2009-03-12 04:22:50 +00:00
if ( mIsCacheable ) {
2009-03-05 03:56:14 +00:00
if ( mCacheEntry )
imgLoader : : RemoveFromCache ( mCacheEntry ) ;
else
imgLoader : : RemoveFromCache ( mKeyURI ) ;
2009-01-31 02:17:47 +00:00
2009-03-12 04:22:50 +00:00
mCacheEntry = nsnull ;
2009-03-05 03:56:14 +00:00
}
2001-01-22 22:01:03 +00:00
}
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2004-07-29 17:09:42 +00:00
PRBool imgRequest : : HaveProxyWithObserver ( imgRequestProxy * aProxyToIgnore ) const
{
2007-12-20 07:30:04 +00:00
nsTObserverArray < imgRequestProxy * > : : ForwardIterator iter ( mObservers ) ;
2007-09-22 19:40:57 +00:00
imgRequestProxy * proxy ;
2007-12-20 07:30:04 +00:00
while ( iter . HasMore ( ) ) {
proxy = iter . GetNext ( ) ;
2004-07-29 17:09:42 +00:00
if ( proxy = = aProxyToIgnore ) {
continue ;
}
if ( proxy - > HasObserver ( ) ) {
return PR_TRUE ;
}
}
return PR_FALSE ;
}
2001-10-12 06:43:52 +00:00
2005-02-21 20:58:01 +00:00
PRInt32 imgRequest : : Priority ( ) const
{
PRInt32 priority = nsISupportsPriority : : PRIORITY_NORMAL ;
2006-03-11 20:32:47 +00:00
nsCOMPtr < nsISupportsPriority > p = do_QueryInterface ( mRequest ) ;
2005-02-21 20:58:01 +00:00
if ( p )
p - > GetPriority ( & priority ) ;
return priority ;
}
2005-02-21 22:21:21 +00:00
void imgRequest : : AdjustPriority ( imgRequestProxy * proxy , PRInt32 delta )
2005-02-21 20:58:01 +00:00
{
// 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 )
2005-02-21 20:58:01 +00:00
return ;
2006-03-11 20:32:47 +00:00
nsCOMPtr < nsISupportsPriority > p = do_QueryInterface ( mRequest ) ;
2005-02-21 20:58:01 +00:00
if ( p )
2005-02-21 22:21:21 +00:00
p - > AdjustPriority ( delta ) ;
2005-02-21 20:58:01 +00:00
}
2009-03-12 04:22:50 +00:00
void imgRequest : : SetCacheable ( PRBool cacheable )
2009-03-05 03:56:14 +00:00
{
2009-03-12 04:22:50 +00:00
LOG_FUNC_WITH_PARAM ( gImgLog , " imgRequest::SetIsCacheable " , " cacheable " , cacheable ) ;
mIsCacheable = cacheable ;
if ( ! mIsCacheable )
mCacheEntry = nsnull ;
2009-03-05 03:56:14 +00:00
}
2001-10-12 06:43:52 +00:00
/** imgILoad methods **/
2001-04-10 01:51:36 +00:00
NS_IMETHODIMP imgRequest : : SetImage ( imgIContainer * aImage )
{
2001-05-08 04:21:49 +00:00
LOG_FUNC ( gImgLog , " imgRequest::SetImage " ) ;
2001-04-10 01:51:36 +00:00
mImage = aImage ;
2001-02-22 02:06:24 +00:00
2001-02-20 22:43:56 +00:00
return NS_OK ;
2001-01-22 22:01:03 +00:00
}
2001-10-12 06:43:52 +00:00
NS_IMETHODIMP imgRequest : : GetImage ( imgIContainer * * aImage )
2001-02-22 02:06:24 +00:00
{
2001-10-12 06:43:52 +00:00
LOG_FUNC ( gImgLog , " imgRequest::GetImage " ) ;
2001-01-22 22:01:03 +00:00
2001-10-12 06:43:52 +00:00
* aImage = mImage ;
NS_IF_ADDREF ( * aImage ) ;
return NS_OK ;
2001-03-22 23:16:52 +00:00
}
2002-02-27 00:32:19 +00:00
NS_IMETHODIMP imgRequest : : GetIsMultiPartChannel ( PRBool * aIsMultiPartChannel )
{
LOG_FUNC ( gImgLog , " imgRequest::GetIsMultiPartChannel " ) ;
* aIsMultiPartChannel = mIsMultiPartChannel ;
return NS_OK ;
}
2001-01-22 22:01:03 +00:00
2001-03-10 01:11:54 +00:00
/** imgIContainerObserver methods **/
2001-01-22 22:01:03 +00:00
2004-11-15 04:16:07 +00:00
/* [noscript] void frameChanged (in imgIContainer container, in gfxIImageFrame newframe, in nsIntRect dirtyRect); */
2003-02-26 05:51:32 +00:00
NS_IMETHODIMP imgRequest : : FrameChanged ( imgIContainer * container ,
gfxIImageFrame * newframe ,
2004-11-15 04:16:07 +00:00
nsIntRect * dirtyRect )
2001-02-20 22:43:56 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::FrameChanged " ) ;
2001-02-22 02:06:24 +00:00
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-01-22 22:01:03 +00:00
2001-02-20 23:45:51 +00:00
/** imgIDecoderObserver methods **/
2001-01-26 12:05:55 +00:00
2003-02-26 05:51:32 +00:00
/* void onStartDecode (in imgIRequest request); */
NS_IMETHODIMP imgRequest : : OnStartDecode ( imgIRequest * request )
2001-01-26 12:05:55 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStartDecode " ) ;
2001-02-22 02:06:24 +00:00
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
}
2001-01-26 12:05:55 +00:00
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42: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 ) ;
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2006-06-01 18:35:21 +00:00
NS_IMETHODIMP imgRequest : : OnStartRequest ( imgIRequest * aRequest )
{
NS_NOTREACHED ( " imgRequest(imgIDecoderObserver)::OnStartRequest " ) ;
return NS_OK ;
}
2003-02-26 05:51:32 +00:00
/* void onStartContainer (in imgIRequest request, in imgIContainer image); */
NS_IMETHODIMP imgRequest : : OnStartContainer ( imgIRequest * request , imgIContainer * image )
2001-01-26 12:05:55 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStartContainer " ) ;
2001-02-22 02:06:24 +00:00
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 ;
2001-10-12 06:43:52 +00:00
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
}
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2003-02-26 05:51:32 +00:00
/* void onStartFrame (in imgIRequest request, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequest : : OnStartFrame ( imgIRequest * request ,
gfxIImageFrame * frame )
2001-01-26 12:05:55 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStartFrame " ) ;
2001-02-22 02:06:24 +00:00
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
}
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2004-11-15 04:16:07 +00:00
/* [noscript] void onDataAvailable (in imgIRequest request, in gfxIImageFrame frame, [const] in nsIntRect rect); */
2003-02-26 05:51:32 +00:00
NS_IMETHODIMP imgRequest : : OnDataAvailable ( imgIRequest * request ,
gfxIImageFrame * frame ,
2004-11-15 04:16:07 +00:00
const nsIntRect * rect )
2001-01-26 12:05:55 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnDataAvailable " ) ;
2001-02-22 02:06:24 +00:00
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
}
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2003-02-26 05:51:32 +00:00
/* void onStopFrame (in imgIRequest request, in gfxIImageFrame frame); */
NS_IMETHODIMP imgRequest : : OnStopFrame ( imgIRequest * request ,
gfxIImageFrame * frame )
2001-01-26 12:05:55 +00:00
{
2001-03-20 02:23:42 +00:00
NS_ASSERTION ( frame , " imgRequest::OnStopFrame called with NULL frame " ) ;
2001-04-16 09:17:59 +00:00
if ( ! frame ) return NS_ERROR_UNEXPECTED ;
2001-03-20 02:23:42 +00:00
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStopFrame " ) ;
2001-02-22 02:06:24 +00:00
2002-03-23 04:33:37 +00:00
mImageStatus | = imgIRequest : : STATUS_FRAME_COMPLETE ;
2001-03-16 02:40:04 +00:00
if ( mCacheEntry ) {
2008-09-04 23:00:42 +00:00
PRUint32 cacheSize = mCacheEntry - > GetDataSize ( ) ;
2001-03-16 02:40:04 +00:00
PRUint32 imageSize = 0 ;
frame - > GetImageDataLength ( & imageSize ) ;
2007-06-27 19:30:34 +00:00
mCacheEntry - > SetDataSize ( cacheSize + imageSize ) ;
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
2001-03-16 02:40:04 +00:00
}
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
}
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2003-02-26 05:51:32 +00:00
/* void onStopContainer (in imgIRequest request, in imgIContainer image); */
NS_IMETHODIMP imgRequest : : OnStopContainer ( imgIRequest * request ,
imgIContainer * image )
2001-01-26 12:05:55 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStopContainer " ) ;
2001-02-22 02:06:24 +00:00
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
}
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2003-02-26 05:51:32 +00:00
/* void onStopDecode (in imgIRequest request, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP imgRequest : : OnStopDecode ( imgIRequest * aRequest ,
nsresult aStatus ,
const PRUnichar * aStatusArg )
2001-01-26 12:05:55 +00:00
{
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStopDecode " ) ;
2001-02-22 02:06:24 +00:00
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
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 ;
2001-10-12 06:43:52 +00:00
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
}
2001-01-26 12:05:55 +00:00
return NS_OK ;
}
2006-06-01 18:35:21 +00:00
NS_IMETHODIMP imgRequest : : OnStopRequest ( imgIRequest * aRequest ,
PRBool aLastPart )
{
NS_NOTREACHED ( " imgRequest(imgIDecoderObserver)::OnStopRequest " ) ;
return NS_OK ;
}
2001-01-26 12:05:55 +00:00
2001-04-10 06:01:08 +00:00
/** nsIRequestObserver methods **/
2001-01-22 22:01:03 +00:00
2001-02-22 08:41:20 +00:00
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
NS_IMETHODIMP imgRequest : : OnStartRequest ( nsIRequest * aRequest , nsISupports * ctxt )
2001-01-22 22:01:03 +00:00
{
2002-09-18 22:08:12 +00:00
nsresult rv ;
2001-02-26 04:22:47 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnStartRequest " ) ;
2001-02-22 02:06:24 +00:00
2001-02-20 23:27:48 +00:00
NS_ASSERTION ( ! mDecoder , " imgRequest::OnStartRequest -- we already have a decoder " ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
2006-02-28 23:43:35 +00:00
nsCOMPtr < nsIMultiPartChannel > mpchan ( do_QueryInterface ( aRequest ) ) ;
if ( mpchan )
2002-02-27 00:32:19 +00:00
mIsMultiPartChannel = PR_TRUE ;
2008-09-29 20:46:53 +00:00
/*
* 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 ;
}
2006-06-01 18:35:21 +00:00
/* set our state variables to their initial values, but advance mState
to onStartRequest . */
2001-10-12 06:43:52 +00:00
mImageStatus = imgIRequest : : STATUS_NONE ;
2006-06-01 18:35:21 +00:00
mState = onStartRequest ;
2001-03-14 00:39:48 +00:00
2008-09-01 20:53:59 +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 ;
2001-03-06 04:46:20 +00:00
/* notify our kids */
2007-12-20 07:30:04 +00:00
nsTObserverArray < imgRequestProxy * > : : ForwardIterator iter ( mObservers ) ;
while ( iter . HasMore ( ) ) {
iter . GetNext ( ) - > OnStartRequest ( aRequest , ctxt ) ;
2001-03-06 04:46:20 +00:00
}
2007-11-09 02:55:41 +00:00
/* Get our principal */
2001-02-22 08:41:20 +00:00
nsCOMPtr < nsIChannel > chan ( do_QueryInterface ( aRequest ) ) ;
2007-11-09 02:55:41 +00:00
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
2001-03-16 02:40:04 +00:00
/* get the expires info */
2002-09-18 22:08:12 +00:00
if ( mCacheEntry ) {
nsCOMPtr < nsICachingChannel > cacheChannel ( do_QueryInterface ( aRequest ) ) ;
2001-03-16 02:40:04 +00:00
if ( cacheChannel ) {
nsCOMPtr < nsISupports > cacheToken ;
cacheChannel - > GetCacheToken ( getter_AddRefs ( cacheToken ) ) ;
if ( cacheToken ) {
2004-08-10 23:57:25 +00:00
nsCOMPtr < nsICacheEntryInfo > entryDesc ( do_QueryInterface ( cacheToken ) ) ;
2001-03-16 02:40:04 +00:00
if ( entryDesc ) {
2001-03-19 21:57:39 +00:00
PRUint32 expiration ;
2001-03-16 02:40:04 +00:00
/* get the expiration time from the caching channel's token */
entryDesc - > GetExpirationTime ( & expiration ) ;
/* set the expiration time on our entry */
2008-09-04 23:00:42 +00:00
mCacheEntry - > SetExpiryTime ( expiration ) ;
2001-03-16 02:40:04 +00:00
}
}
2001-03-07 00:59:49 +00:00
}
2002-09-18 22:08:12 +00:00
//
// 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 ;
}
}
2008-09-04 23:00:42 +00:00
mCacheEntry - > SetMustValidateIfExpired ( bMustRevalidate ) ;
2002-09-18 22:08:12 +00:00
}
2001-02-24 23:45:30 +00:00
}
2002-03-10 22:29:14 +00:00
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
2007-09-22 19:40:57 +00:00
if ( mObservers . IsEmpty ( ) ) {
2002-03-10 22:29:14 +00:00
this - > Cancel ( NS_IMAGELIB_ERROR_FAILURE ) ;
}
2001-01-22 22:01:03 +00:00
return NS_OK ;
}
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status); */
2001-04-10 06:01:08 +00:00
NS_IMETHODIMP imgRequest : : OnStopRequest ( nsIRequest * aRequest , nsISupports * ctxt , nsresult status )
2001-01-22 22:01:03 +00:00
{
2001-05-08 04:21:49 +00:00
LOG_FUNC ( gImgLog , " imgRequest::OnStopRequest " ) ;
2001-02-20 22:43:56 +00:00
2001-03-06 21:54:33 +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 */
2001-02-22 02:06:24 +00:00
mProcessing = PR_FALSE ;
2001-02-20 22:43:56 +00:00
2006-06-01 18:35:21 +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?
2008-12-22 22:20:46 +00:00
// xxx before we release our reference to mRequest, lets
2006-11-09 22:47:43 +00:00
// save the last status that we saw so that the
// imgRequestProxy will have access to it.
2008-12-22 22:20:46 +00:00
if ( mRequest ) {
2006-12-11 04:15:45 +00:00
mRequest = nsnull ; // we no longer need the request
}
2001-02-26 04:22:47 +00:00
2008-12-22 22:20:46 +00:00
// 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 ) {
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
this - > Cancel ( status ) ; // sets status, stops animations, removes from cache
2001-04-09 00:45:06 +00:00
} else {
2001-10-12 06:43:52 +00:00
mImageStatus | = imgIRequest : : STATUS_LOAD_COMPLETE ;
2001-02-26 04:22:47 +00:00
}
2001-02-25 08:28:36 +00:00
if ( mDecoder ) {
2001-02-26 04:22:47 +00:00
mDecoder - > Flush ( ) ;
2001-02-25 08:28:36 +00:00
mDecoder - > Close ( ) ;
mDecoder = nsnull ; // release the decoder so that it can rest peacefully ;)
}
2002-03-23 13:21:33 +00:00
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 ) ) {
2003-02-26 05:51:32 +00:00
this - > OnStopDecode ( nsnull , status , nsnull ) ;
2001-04-09 00:45:06 +00:00
}
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +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 ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
}
2001-02-20 22:43:56 +00:00
return NS_OK ;
2001-01-22 22:01:03 +00:00
}
2001-03-14 00:39:48 +00:00
/* prototype for this defined below */
2001-03-15 23:33:52 +00:00
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
2001-01-22 22:01:03 +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-01-22 22:01:03 +00:00
{
2001-05-08 04:21:49 +00:00
LOG_SCOPE_WITH_PARAM ( gImgLog , " imgRequest::OnDataAvailable " , " count " , count ) ;
2001-02-25 08:28:36 +00:00
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
NS_ASSERTION ( aRequest , " imgRequest::OnDataAvailable -- no request! " ) ;
2001-03-14 00:39:48 +00:00
2009-02-16 14:11:30 +00:00
mGotData = PR_TRUE ;
2001-03-14 00:39:48 +00:00
if ( ! mProcessing ) {
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
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
2002-03-20 22:50:33 +00:00
if ( mContentType . IsEmpty ( ) ) {
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
LOG_SCOPE ( gImgLog , " imgRequest::OnDataAvailable |sniffing of mimetype failed| " ) ;
nsCOMPtr < nsIChannel > chan ( do_QueryInterface ( aRequest ) ) ;
nsresult rv = NS_ERROR_FAILURE ;
if ( chan ) {
2002-03-20 22:50:33 +00:00
rv = chan - > GetContentType ( mContentType ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
}
2001-03-14 00:39:48 +00:00
if ( NS_FAILED ( rv ) ) {
PR_LOG ( gImgLog , PR_LOG_ERROR ,
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
( " [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
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +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
}
2005-03-23 21:09:02 +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 ) ;
}
}
2002-03-20 22:50:33 +00:00
LOG_MSG_WITH_PARAM ( gImgLog , " imgRequest::OnDataAvailable " , " content type " , mContentType . get ( ) ) ;
2001-03-14 00:39:48 +00:00
2002-03-20 22:50:33 +00:00
nsCAutoString conid ( NS_LITERAL_CSTRING ( " @mozilla.org/image/decoder;2?type= " ) + mContentType ) ;
2001-03-14 00:39:48 +00:00
2001-10-25 09:44:29 +00:00
mDecoder = do_CreateInstance ( conid . get ( ) ) ;
2001-03-14 00:39:48 +00:00
if ( ! mDecoder ) {
PR_LOG ( gImgLog , PR_LOG_WARNING ,
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
( " [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
}
2007-07-08 07:08:04 +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 ) {
2001-02-22 02:06:24 +00:00
PR_LOG ( gImgLog , PR_LOG_WARNING ,
2001-02-25 08:28:36 +00:00
( " [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 ) ;
fix for at least bugs 6074,72087,74506,75190,75180,74165,69857,75576,75326,75417,75474 r=waterson, sr=brendan
2001-04-13 02:42:56 +00:00
return NS_BINDING_ABORTED ;
2001-02-20 22:43:56 +00:00
}
2001-01-22 22:01:03 +00:00
PRUint32 wrote ;
2001-03-06 04:46:20 +00:00
nsresult rv = mDecoder - > WriteFrom ( inStr , count , & wrote ) ;
2001-04-16 09:17:59 +00:00
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 ) ;
2001-04-16 09:17:59 +00:00
return NS_BINDING_ABORTED ;
}
2001-03-06 04:46:20 +00:00
return NS_OK ;
2001-01-22 22:01:03 +00:00
}
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 )
{
2007-07-08 07:08:04 +00:00
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 )
{
2004-07-19 18:53:02 +00:00
imgLoader : : GetMimeTypeFromContent ( buf , len , mContentType ) ;
2007-09-02 16:10:57 +00:00
// 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 ;
}
}
2001-03-15 23:33:52 +00:00
}
2006-11-09 22:47:43 +00:00
2008-12-22 22:20:46 +00:00
/** 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 ;
}
2009-01-31 02:17:47 +00:00
# if defined(PR_LOGGING)
nsCAutoString spec ;
mKeyURI - > GetSpec ( spec ) ;
LOG_MSG_WITH_PARAM ( gImgLog , " imgRequest::OnChannelRedirect " , " old " , spec . get ( ) ) ;
# endif
2008-12-22 22:20:46 +00:00
RemoveFromCache ( ) ;
mChannel = newChannel ;
2008-12-24 01:31:30 +00:00
newChannel - > GetOriginalURI ( getter_AddRefs ( mKeyURI ) ) ;
2008-12-22 22:20:46 +00:00
2009-01-31 02:17:47 +00:00
# if defined(PR_LOGGING)
mKeyURI - > GetSpec ( spec ) ;
LOG_MSG_WITH_PARAM ( gImgLog , " imgRequest::OnChannelRedirect " , " new " , spec . get ( ) ) ;
# endif
2009-03-12 04:22:50 +00:00
if ( mIsCacheable ) {
2009-03-05 03:56:14 +00:00
// If we don't still have a cache entry, we don't want to refresh the cache.
if ( mKeyURI & & mCacheEntry )
imgLoader : : PutIntoCache ( mKeyURI , mCacheEntry ) ;
}
2008-12-22 22:20:46 +00:00
return rv ;
}