browserutilities/downloadmgr/DownloadMgrClntSrv/src/DownloadMgrClntSession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 07 Jan 2010 13:31:38 +0200
changeset 37 cb62a4f66ebe
parent 36 0ed94ceaa377
child 65 5bfc169077b2
child 93 79859ed3eea9
permissions -rw-r--r--
Revision: 200951 Kit: 201001

/*
* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*     This file contains the declaration of the Client interface of Download Mgr Server.
*
*/


// INCLUDE FILES
#include "DownloadMgrLogger.h"
#include <downloadmgrclient.h>
#include "DownloadMgrServer.h"
#include "DownloadMgrStart.h"
#include "DownloadMgrDef.h"
#include "DownloadMgrDefAttrib.h"
#include "DownloadMgrHandler.h"
#include <e32svr.h>
#include <EscapeUtils.h>
#include <centralrepository.h>
#include "DownloadMgrCRKeys.h"
#include <browseruisdkcrkeys.h>
#include <coddownload.h>

// CONSTANTS
const TInt KHttpDownloadMgrObserverArrayGranularity = 4;
const TInt KHttpDownloadMgrDefalutAttribsGranularity = 4;
const TInt KDefaultMsgSlots = 16;
const TInt KNumOfSubSessions = 16;

_LIT8( KHttpScheme, "http" );
_LIT8( KHttpsScheme, "https" );

// GLOBAL FUNCTIONS
#if defined(_DEBUG)
void DMPanic( TInt aPanicCode )
    {
    User::Panic( _L("DownloadManager"), aPanicCode );
    }
#endif
 
// ================= MEMBER FUNCTIONS =======================

/**
* Extension class.
*/
NONSHARABLE_CLASS( CRHttpDownloadMgrExtension ) : public CBase
    {
    public:  // Constructors and destructor
        
        /**
        * Two-phased constructor.
        */
        static CRHttpDownloadMgrExtension* NewL();
        
        /**
        * Destructor.
        */
        virtual ~CRHttpDownloadMgrExtension();
        
        /*
        * Next uri observer setter function
        */
        void SetNextUriObserver( MHttpDownloadMgrNextUriObserver* aObserver );

        /*
        * Next uri observer getter function
        */
        MHttpDownloadMgrNextUriObserver* NextUriObserver() const;


    protected: // Constructors

        /**
        * C++ default constructor.
        */
        CRHttpDownloadMgrExtension();

        /**
        * By default Symbian 2nd phase constructor is private.
        */
        void ConstructL();

    public:      
        
        static TInt GetRepositoryValue( TUint32 aSettingId, TInt& aSettingValue );

        static TInt SetRepositoryValue( TUint32 aSettingId, TInt aSettingValue );

    public: // Data
        TInt iEventBroadcastLevel;
        
        MHttpDownloadMgrNextUriObserver* iNextUriObserver; ///< Not Owned.
  
        TInt iSessionId;
        
        TInt iAdjustEventPriorityFlag;
    };

// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::CRHttpDownloadMgrExtension
// -----------------------------------------------------------------------------
//
CRHttpDownloadMgrExtension::CRHttpDownloadMgrExtension()
:iEventBroadcastLevel( 0 )
,iAdjustEventPriorityFlag( 0 )
    {
    iNextUriObserver = NULL;
    }

// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::ConstructL
// -----------------------------------------------------------------------------
//
void CRHttpDownloadMgrExtension::ConstructL()
    {
    CLOG_ENTERFN("CRHttpDownloadMgrExtension::ConstructL");
    }

// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::NewL
// -----------------------------------------------------------------------------
//
CRHttpDownloadMgrExtension* CRHttpDownloadMgrExtension::NewL()
    {
    CRHttpDownloadMgrExtension* self = new(ELeave)CRHttpDownloadMgrExtension();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop();
    return self;
    }

// Destructor
CRHttpDownloadMgrExtension::~CRHttpDownloadMgrExtension()
    {
    CLOG_ENTERFN("CRHttpDownloadMgrExtension::~CRHttpDownloadMgrExtension");
    }

// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::SetNextUriObserver
// -----------------------------------------------------------------------------
//
void CRHttpDownloadMgrExtension::SetNextUriObserver( MHttpDownloadMgrNextUriObserver* aObserver )
    {
    iNextUriObserver = aObserver;
    }

// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::NextUriObserver
// -----------------------------------------------------------------------------
//
MHttpDownloadMgrNextUriObserver* CRHttpDownloadMgrExtension::NextUriObserver() const
    {
    return iNextUriObserver;
    }


// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::GetRepositoryValue
// -----------------------------------------------------------------------------
//
TInt CRHttpDownloadMgrExtension::GetRepositoryValue( TUint32 aSettingId, TInt& aSettingValue )
    {
    aSettingValue = KErrNotFound;
    CRepository* rep = NULL;

    TRAPD( err, rep = CRepository::NewL( KCRUidBrowserUiLV ) );
    if( (err == KErrNone) && rep )
        {
        err = rep->Get( aSettingId, aSettingValue );
        }
    delete rep;
    return err;
    }

// -----------------------------------------------------------------------------
// CRHttpDownloadMgrExtension::SetRepositoryValue
// -----------------------------------------------------------------------------
//
TInt CRHttpDownloadMgrExtension::SetRepositoryValue( TUint32 aSettingId, TInt aSettingValue )
    {
    CRepository* rep = NULL;
   
    TRAPD( err, rep = CRepository::NewL( KCRUidBrowserUiLV ) );
    if( (err == KErrNone) && rep )
        {
        err = rep->Set( aSettingId, aSettingValue );
        }
    delete rep;
    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::RHttpDownloadMgr
// ---------------------------------------------------------
//
EXPORT_C RHttpDownloadMgr::RHttpDownloadMgr()
	{
    // Reset data members as R-objects are not zero'd.
    iAppUid = TUid::Null();
    iDownloadArray = NULL;
    iObservers = NULL;
    iDefaultAttribs = NULL;
    iManagerHandler = NULL;
    iExtension = NULL;
	}

// ---------------------------------------------------------
// RHttpDownloadMgr::ConnectL
// ---------------------------------------------------------
//
EXPORT_C void RHttpDownloadMgr::ConnectL( TUid aAppUid,
                                          MHttpDownloadMgrObserver& aObserver,
                                          TBool aMaster )
    {
	CLOG_CREATE;
	
    __ASSERT_DEBUG( !Handle(), DMPanic( KErrAlreadyExists ) );
    
    TRAPD( err, DoConnectL( aAppUid, aObserver, aMaster ) );
    if( err )
        {
        Close();
        User::Leave( err );
        }
    }
    
// ---------------------------------------------------------
// RHttpDownloadMgr::DoConnectL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::DoConnectL( TUid aAppUid,
                                   MHttpDownloadMgrObserver& aObserver,
                                   TBool aMaster )   
	{
    CLOG_ENTERFN( "RHttpDownloadMgr::ConnectL" );

    TInt error = KErrNone;
    RProcess server;
    error = server.Create( KDownloadMgrServerExe, TPtr( NULL, 0 ),
                           TUidType( KNullUid, KNullUid, KUidDownloadMgrSrvExe ) );
    CLOG_WRITE_FORMAT( "RHttpDownloadMgr::ConnectL after process creation, err %d", error );

    if( !error )
        {
        TRequestStatus status;
        server.Rendezvous( status );
        if( status != KRequestPending )
            {
            CLOG_WRITE( "RHttpDownloadMgr::ConnectL pending status error." );
            server.Kill( 0 );
            }
        else
            {
            CLOG_WRITE( "RHttpDownloadMgr::ConnectL pending resume server." );
            server.Resume( );
            }
        User::WaitForRequest( status );
        error = ( server.ExitType() == EExitPanic ) ? KErrGeneral : status.Int();
        server.Close();
        }
    User::LeaveIfError( error );
    CLOG_WRITE( "Creating..." );
    User::LeaveIfError(  CreateSession( KDownloadMgrServerName, Version(), KDefaultMsgSlots ) );
    CLOG_WRITE( "Created" );

    CLOG_WRITE( "Starting initialization" );
    InitializeL( aAppUid, aObserver, aMaster );
    CLOG_WRITE( "Init OK" );
	}

// ---------------------------------------------------------
// RHttpDownloadMgr::InitializeL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::InitializeL( TUid aAppUid,
                                    MHttpDownloadMgrObserver& aObserver,
                                    TBool aMaster )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::InitializeL" )

    iAppUid = aAppUid;
    AddObserverL( aObserver );
    iExtension = CRHttpDownloadMgrExtension::NewL();
    CLOG_ATTACH( iExtension, this );
    iDownloadArray = new (ELeave) CArrayPtrFlat< RHttpDownload >( 1 );
    if( aMaster )
        {
        iManagerHandler = new (ELeave) CDownloadMgrHandler ( this );
        CLOG_ATTACH( iManagerHandler, this );
        iManagerHandler->StartL();
        }

    TPckg<TUid> uidPckg( iAppUid );
    TInt count( 0 );
    TPckg<TInt> pckgCount( count );
    TPckg<TInt> sessionId( iExtension->iSessionId );
    // 0st param - application UID
    // 1st param - the amount of downloads at server side belongs to the same UID
    // 2st param - master flag
    // 3rd param - session id

    User::LeaveIfError( SendReceive( EHttpDownloadMgrInitialize, 
                                     TIpcArgs( &uidPckg, &pckgCount, aMaster, 
                                     &sessionId ) ) );

    CLOG_NAME_2( _L("Session_%x_%x"), aAppUid.iUid, iExtension->iSessionId );

    CLOG_WRITE_FORMAT( "count: %d", count )
    // There are downloads at server side which needs to be attached
    if( count )
        {
        // Create a buffer which will contain the handles.
        TPckgBuf<TInt> arrayPckg;
        HBufC8* buf = HBufC8::NewLC( count*arrayPckg.Size() );
        // Get the handles from the server
        TPtr8 ptr = buf->Des();
        AttachL( ptr );
        // Create subsessions one by one.
        for( TInt i = 0; i < count; i++ )
            {
            RHttpDownload* download = new (ELeave) RHttpDownload ( this );
            CleanupStack::PushL( download );
            // Parse the handle from the buffer.
            arrayPckg.Copy( buf->Mid( i*arrayPckg.Size(), arrayPckg.Size() ) );
            // Attach subsession to the server by the handle.
            download->AttachL( arrayPckg() );
            TBool isCodDownload ( EFalse );
            download->GetBoolAttribute ( EDlAttrCodDownload , isCodDownload );
            if( isCodDownload )
            	{
            	//paused Download
            	download->InitPausedCodDownloadL( iAppUid );
            	
            	// Update CodData in Download Mgr Server
            	HBufC8* mediaInfo8 = NULL;
            	if(download->iCodDownload)
            	    {
            	    mediaInfo8 = download->iCodDownload->UpdatedDownloadDataL();
            	    }
    	    	if (mediaInfo8)
    	        	{
    	        	download->SetDownloadDataAttribute(*mediaInfo8);
    	        	delete mediaInfo8;
    	        	
    	        	// Buffer attributes in CRHttpDownloadExtension class
    	        	download->BufferAttributesL();
    	        	}
                User::LeaveIfError( download->GetProductDownloadedSize( ) );                	        	
            	}
            AddToArrayL( download );	
            CleanupStack::Pop( download ); //download
            }

        CleanupStack::PopAndDestroy( buf ); // buf
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::AttachL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::AttachL( TDes8& aBuf )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::AttachL" )
    // 0st param - buffer will contain handles.
    // The handles idetifies the download subsessions.

    User::LeaveIfError( SendReceive( EHttpDownloadMgrAttach, 
                                     TIpcArgs( &aBuf ) ) );
    }
    
// ---------------------------------------------------------
// RHttpDownloadMgr::CloseDownload
// ---------------------------------------------------------
//
void RHttpDownloadMgr::CloseDownload( RHttpDownload* aElement )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::CloseDownload" );

    // As this class owns the array of subsessions, this role is 
    // to close them.
    RemoveFromArray( aElement );
    aElement->Close();
    delete aElement;
    aElement = NULL;
    }
    
// ---------------------------------------------------------
// RHttpDownloadMgr::Version
// ---------------------------------------------------------
//
EXPORT_C TVersion RHttpDownloadMgr::Version( void ) const
	{
	return TVersion( KDownloadMgrMajorVersionNumber,
                     KDownloadMgrMinorVersionNumber,
                     KDownloadMgrBuildVersionNumber );
	}


// ---------------------------------------------------------
// RHttpDownloadMgr::Close
// ---------------------------------------------------------
//
EXPORT_C void RHttpDownloadMgr::Close()
	{
    
 	if( !Handle() )
 	    {
 	    return;
 	    }

    CLOG_WRITE( "RHttpDownloadMgr::Close" )
    if( iDownloadArray )
        {
        TInt count = iDownloadArray->Count();
        while( count-- )
            {
            CLOG_WRITE_FORMAT( "Close download count[%d]", count );
		    RHttpDownload* download = (*iDownloadArray)[count];
		    CloseDownload( download );
            }
        iDownloadArray->Reset();
        delete iDownloadArray;
        iDownloadArray = NULL;
        }

    if( iExtension )
        {
        delete iExtension;
        iExtension = NULL;
        }

    if( iObservers )
        {
        iObservers->Reset();
        delete iObservers;
        iObservers = NULL;
        }

    if( iDefaultAttribs )
        {
        iDefaultAttribs->ResetAndDestroy();
        delete iDefaultAttribs;
        iDefaultAttribs = NULL;
        }

    if( iManagerHandler )
        {
        iManagerHandler->Cancel();
        delete iManagerHandler;
        iManagerHandler = NULL;
        }

	RHandleBase::Close();
	
	CLOG_CLOSE;
	}

// ---------------------------------------------------------
// RHttpDownloadMgr::AddObserverL
// ---------------------------------------------------------
//
EXPORT_C void RHttpDownloadMgr::AddObserverL( MHttpDownloadMgrObserver& aObserver )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::AddObserverL" )

	if ( iObservers == NULL )
        {
		iObservers = new (ELeave) CDownloadMgrObserver( 
            KHttpDownloadMgrObserverArrayGranularity );
        }

    TInt index( 0 );
    if ( FindObserver( aObserver, index ) == KErrNone )
        {
        // Observer already added.
        }
    else
        {
	    iObservers->AppendL( &aObserver );
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::RemoveObserver
// ---------------------------------------------------------
//
EXPORT_C void RHttpDownloadMgr::RemoveObserver( MHttpDownloadMgrObserver& aObserver )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::RemoveObserver" )

    if ( iObservers )
        {
        TInt index( 0 );
        if ( FindObserver( aObserver, index ) != KErrNone )
            {
            // Observer not found. Do nothing.
            }
        else
            {
            // Observer found.
            iObservers->Delete( index );
            // Free up memory.
            if ( iObservers->Count() == 0 )
                {
                delete iObservers;
                iObservers = NULL;
                }
            }
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::FindObserver
// ---------------------------------------------------------
//
TInt RHttpDownloadMgr::FindObserver( MHttpDownloadMgrObserver& aObserver, TInt& aIndex ) const
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::FindObserver" )

    TInt ret( KErrNotFound );

    if ( iObservers == NULL )
        {
        ret = KErrNotFound;
        }
    else
        {
        MHttpDownloadMgrObserver* obs = &aObserver;
        TKeyArrayFix key( 0, ECmpTUint32 ); // Compare pointers
        ret = iObservers->Find( obs, key, aIndex );
        }

    return ret;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::CurrentDownloads
// ---------------------------------------------------------
//
EXPORT_C const CDownloadArray& RHttpDownloadMgr::CurrentDownloads() const
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_WRITE_FORMAT( "RHttpDownloadMgr::CurrentDownloads %d", iDownloadArray->Count() )
    return *iDownloadArray;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::CreateDownloadL
// ---------------------------------------------------------
//
EXPORT_C RHttpDownload& RHttpDownloadMgr::CreateDownloadL( const TDesC8& aUrl, 
                                                           TBool& aResult )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::CreateDownloadL" )
    RHttpDownload* download = DoFindDownloadL( aUrl, KNullDesC8 );
    
    if( !download )
        {
        // there is no ongoing download with this URL
        // create one and add to the array
        aResult = ETrue;
        return CreateDownloadL( aUrl );
        }
    else
        {
        // we already have a download, just return a reference to it.
        aResult = EFalse;
        return *download;
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::CreateDownloadL
// ---------------------------------------------------------
//
EXPORT_C RHttpDownload& RHttpDownloadMgr::CreateDownloadL( const TDesC8& aUrl )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::CreateDownloadL" )
    
    //Leave if the number of parallel downloads exceeds 16.
    if(!IsNewDownloadPossible()){
        User::LeaveIfError(KErrServerBusy);
        }
    
    RHttpDownload* download = new (ELeave) RHttpDownload ( this );
    CleanupStack::PushL( download );
    CleanupClosePushL( *download );
    HBufC8* buf = PackedDefaultAttributesLC();
    download->CreateL( aUrl, buf->Des() );
    RHttpDownload& item = AddToArrayL( download );
    CleanupStack::PopAndDestroy( buf ); // buf
    CleanupStack::Pop( 2 );  // download->Close, download
   
    return item;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::CreateCodDownloadL
// ---------------------------------------------------------
//
EXPORT_C RHttpDownload& RHttpDownloadMgr::CreateCodDownloadL( const TDesC8& aUrl,
                                                              const TDesC8& aBuf,
                                                              const TDesC8& aMimeType,
                                                              CEikonEnv* aEikEnv,
                                                              TBool& aResult )
	{
	__ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
	
	CLOG_ENTERFN( "RHttpDownloadMgr::CreateCodDownloadL" )
	
	RHttpDownload& download = CreateDownloadL( aUrl, aResult );
	download.InitCodDownloadL( aBuf, aMimeType, aEikEnv );
	download.SetBoolAttribute( EDlAttrCodDownload, ETrue );
	
	return download;
	}

// ---------------------------------------------------------
// RHttpDownloadMgr::CreateClientSideDownloadL
// ---------------------------------------------------------
//
EXPORT_C RHttpDownload& RHttpDownloadMgr::CreateClientSideDownloadL( 
    TInt aHttpTransaction,TBool& aResult )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    RHTTPTransaction* httpTransaction = 
        REINTERPRET_CAST( RHTTPTransaction* , aHttpTransaction );
    RHttpDownload& download = 
    		CreateDownloadL( httpTransaction->Request().URI().UriDes() );
    		
    download.SetBoolAttribute( EDlAttrContinue, ETrue );
    download.SetHttpTransactionL( aHttpTransaction );

    // Set the disconnect notification
    httpTransaction->PropertySet().SetPropertyL
        (
        httpTransaction->Session().StringPool().StringF( HTTP::ENotifyOnDisconnect, RHTTPSession::GetTable() ), 
        httpTransaction->Session().StringPool().StringF( HTTP::EEnableDisconnectNotification, RHTTPSession::GetTable() )
        ); 

    aResult = ETrue; // download is created
        
    return download;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::FindDownload
// ---------------------------------------------------------
//
EXPORT_C RHttpDownload* RHttpDownloadMgr::FindDownload( const TDesC8& aUrl, 
                                                        const TDesC8& aMsgBody )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::FindDownload" )
    RHttpDownload* retVal = NULL;
    
    TRAP_IGNORE( retVal = DoFindDownloadL( aUrl, aMsgBody) );

    return retVal;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DownloadFromHandleL
// ---------------------------------------------------------
//
RHttpDownload& RHttpDownloadMgr::DownloadFromHandleL( TUint aHandle )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::DownloadFromHandleL" )
    // Check the download's handle in the array
    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        if( (*iDownloadArray)[i]->IsDownload( aHandle ) )
            {
            return *(*iDownloadArray)[i];
            }
        }
    User::Leave( KErrNotFound );

    // Just let the compiler be satisfied
    return *(*iDownloadArray)[iDownloadArray->Count()];
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::AddToArrayL
// ---------------------------------------------------------
//
RHttpDownload& RHttpDownloadMgr::AddToArrayL( RHttpDownload* aElement )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::AddToArrayL" );

    TInt index( 0 );
    TInt err = FindInArray( aElement, index );
    if ( !err )
        {
        // Already added. Do nothing, just return a reference to the 
        // element in the array.
        }
    else
        {
        TInt count = iDownloadArray->Count();
        // 'count' will be the index of the new appended element:
        index = count;
        iDownloadArray->AppendL( aElement );
        }

    return  *(*iDownloadArray)[index];
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::RemoveFromArray
// ---------------------------------------------------------
//
void RHttpDownloadMgr::RemoveFromArray( RHttpDownload* aElement )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::RemoveFromArray" )

    TInt index( 0 );
    TInt err = FindInArray( aElement, index );
    if ( !err )
        {
        // Found. Remove from array:
        iDownloadArray->Delete( index );
        iDownloadArray->Compress();
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::FindInArray
// ---------------------------------------------------------
//
TInt RHttpDownloadMgr::FindInArray( RHttpDownload* aElement, TInt& aIndex ) const
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::FindInArray" );
    
    //__ASSERT_DEBUG( iDownloadArray, Panic...)
    TKeyArrayFix key( 0, ECmpTUint32 ); // Compare pointers
    TInt ret = iDownloadArray->Find( aElement, key, aIndex );

    return ret;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::PauseAll
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::PauseAll()
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::PauseAll" )

    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        (*iDownloadArray)[i]->Pause();
        }

    return KErrNone;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::StartAll
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::StartAll()
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::StartAllL" )

    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        (*iDownloadArray)[i]->Start();
        }

    return KErrNone;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::ResetAll
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::ResetAll()
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::ResetAll" )

    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        (*iDownloadArray)[i]->Reset();
        }

    return KErrNone;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DeleteAll
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::DeleteAll()
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::DeleteAll" )

    TInt err( KErrNone );

    TInt i = iDownloadArray->Count();
    while( i )
        {
        TInt temp = (*iDownloadArray)[0]->Delete();
        if( temp )
            {
            err = temp;
            }
        --i;
        }

    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::IsNewDownloadPossible()
// ---------------------------------------------------------
 TBool RHttpDownloadMgr::IsNewDownloadPossible()
{
    TInt32 value(0);    
    TPckg<TInt32> pckg( value );
    if(KErrNone ==  SendReceive( EHttpDownMgrNumOfSubSessions, 
                           TIpcArgs(&pckg ) )){
        if(value < KNumOfSubSessions){
            return ETrue;
        }
    }
    return EFalse;
}

// ---------------------------------------------------------
// RHttpDownloadMgr::Disconnect
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::Disconnect()
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::Disconnect" )

    // First pause all downloads.
    // It'd be difficult to pause client side downloads from
    // server side.
    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        (*iDownloadArray)[i]->Pause();
        }

    return SendReceive( EHttpDownloadMgrDisconnect, TIpcArgs() );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::GetIntAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::GetIntAttribute( const TUint aAttribute, 
                                                 TInt32& aValue )
    {
    switch ( aAttribute )
        {
        case EDlMgrHasActiveDownloads:
            {
            return CRHttpDownloadMgrExtension::GetRepositoryValue( KDownloadMgrHasActiveDownloads, (TInt&)aValue );
            }
        case EDlMgrAutoAcceptCod:
            {
            return CRHttpDownloadMgrExtension::GetRepositoryValue( KDownloadMgrAutoAcceptCod, (TInt&)aValue );
            }
        case EDlMgrNumOfClientSideDownload:
            {
            __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
            return NumberOfClientSideDownload( aValue );
            }
        default:
            {
            __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
            TPckg<TInt32> pckg( aValue );
            return SendReceive( EHttpDownloadMgrGetIntAttribute, 
                        TIpcArgs( aAttribute, &pckg ) );
            }
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::NumberOfClientSideDownload
// ---------------------------------------------------------
//
TInt RHttpDownloadMgr::NumberOfClientSideDownload( TInt32& aValue )
    {
    TInt err( KErrNone );

    aValue = 0;
    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        if( (*iDownloadArray)[i]->IsClientSideDownload() )
            {
            aValue++;
            }
        }
    
    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::GetBoolAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::GetBoolAttribute( const TUint aAttribute, 
                                                  TBool& aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::GetIntAttribute" )

    TPckg<TBool> pckg( aValue );

    return SendReceive( EHttpDownloadMgrGetBoolAttribute, 
                        TIpcArgs( aAttribute, &pckg ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::GetStringAttributeL
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::GetStringAttribute( const TUint aAttribute, 
                                                    TDes16& aValue  )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::GetIntAttribute" )

    return SendReceive( EHttpDownloadMgrGetStringAttribute, 
                        TIpcArgs( aAttribute, &aValue ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::GetStringAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::GetStringAttribute( const TUint aAttribute, 
                                                    TDes8& aValue  )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::GetIntAttribute" )

    return SendReceive( EHttpDownloadMgrGetString8Attribute, 
                        TIpcArgs( aAttribute, &aValue ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetIntAttributeL
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetIntAttribute( const TUint aAttribute, 
                                                 TInt32 aValue )
    {
    if( aAttribute == EDlMgrHasActiveDownloads )
        {
        return CRHttpDownloadMgrExtension::SetRepositoryValue(
                KDownloadMgrHasActiveDownloads, (TInt&)aValue );
        }
    else
        {
        __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
        return SendReceive( EHttpDownloadMgrSetIntAttribute, 
                            TIpcArgs( aAttribute, aValue ) );
        }
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetBoolAttributeL
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetBoolAttribute( const TUint aAttribute, 
                                                  TBool aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetBoolAttributeL" )

    return SendReceive( EHttpDownloadMgrSetBoolAttribute, 
                        TIpcArgs( aAttribute, aValue ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetStringAttributeL
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetStringAttribute( const TUint aAttribute, 
                                                    const TDesC16& aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetStringAttributeL" )

    return SendReceive( EHttpDownloadMgrSetStringAttribute, 
                        TIpcArgs( aAttribute, &aValue ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetStringAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetStringAttribute( const TUint aAttribute, 
                                                    const TDesC8& aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetStringAttributeL" )

    return SendReceive( EHttpDownloadMgrSetString8Attribute, 
                        TIpcArgs( aAttribute, &aValue ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetDefaultIntAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetDefaultIntAttribute( const TUint aAttribute, 
                                                        TInt32 aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultIntAttributeL" )

    TRAPD( err, DoSetDefaultAttributeL( aAttribute, aValue ) );

    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetDefaultBoolAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetDefaultBoolAttribute( const TUint aAttribute, 
                                                         TBool aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    TRAPD( err, DoSetDefaultAttributeL( aAttribute, aValue ) );

    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetDefaultStringAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetDefaultStringAttribute( const TUint aAttribute, 
                                                           const TDesC16& aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    TRAPD( err, DoSetDefaultAttributeL( aAttribute, aValue ) );

    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetDefaultStringAttribute
// ---------------------------------------------------------
//
EXPORT_C TInt RHttpDownloadMgr::SetDefaultStringAttribute( const TUint aAttribute, 
                                                           const TDesC8& aValue )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    TRAPD( err, DoSetDefaultAttributeL( aAttribute, aValue ) );

    return err;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SetNextUriObserver
// ---------------------------------------------------------
//
EXPORT_C void RHttpDownloadMgr::SetNextUriObserver( MHttpDownloadMgrNextUriObserver* aObserver )
    {
    __ASSERT_DEBUG( Handle(), DMPanic( KErrDisconnected ) );
    
    iExtension->SetNextUriObserver( aObserver );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::NextUriObserver
// ---------------------------------------------------------
//
MHttpDownloadMgrNextUriObserver* RHttpDownloadMgr::NextUriObserver() const
    {
    return iExtension->iNextUriObserver;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::SessionId
// ---------------------------------------------------------
//
TInt RHttpDownloadMgr::SessionId() const
    {
    return iExtension->iSessionId;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DoSetStringAttributeL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::DoSetDefaultAttributeL( const TUint aAttribute, 
                                               TBool aValue )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    if( iDefaultAttribs == NULL )
        {
		iDefaultAttribs = new (ELeave) CArrayPtrFlat< CDefaultAttrib >( 
            KHttpDownloadMgrDefalutAttribsGranularity );
        }
    CDefaultAttrib* attrib = CDefaultAttrib::NewL( (THttpDownloadAttrib)aAttribute,
                                                   aValue );
    iDefaultAttribs->AppendL( attrib );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DoSetStringAttributeL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::DoSetDefaultAttributeL( const TUint aAttribute, 
                                               TInt32 aValue )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    if( iDefaultAttribs == NULL )
        {
		iDefaultAttribs = new (ELeave) CArrayPtrFlat< CDefaultAttrib >( 
            KHttpDownloadMgrDefalutAttribsGranularity );
        }
    CDefaultAttrib* attrib = CDefaultAttrib::NewL( (THttpDownloadAttrib)aAttribute,
                                                   aValue );
    iDefaultAttribs->AppendL( attrib );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DoSetStringAttributeL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::DoSetDefaultAttributeL( const TUint aAttribute, 
                                               const TDesC8& aValue )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    if( iDefaultAttribs == NULL )
        {
		iDefaultAttribs = new (ELeave) CArrayPtrFlat< CDefaultAttrib >( 
            KHttpDownloadMgrDefalutAttribsGranularity );
        }
    CDefaultAttrib* attrib = CDefaultAttrib::NewL( (THttpDownloadAttrib)aAttribute,
                                                   aValue );
    iDefaultAttribs->AppendL( attrib );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DoSetStringAttributeL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::DoSetDefaultAttributeL( const TUint aAttribute, 
                                               const TDesC16& aValue )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::SetDefaultBoolAttribute" )

    if( iDefaultAttribs == NULL )
        {
		iDefaultAttribs = new (ELeave) CArrayPtrFlat< CDefaultAttrib >( 
            KHttpDownloadMgrDefalutAttribsGranularity );
        }
    CDefaultAttrib* attrib = CDefaultAttrib::NewL( (THttpDownloadAttrib)aAttribute,
                                                   aValue );
    iDefaultAttribs->AppendL( attrib );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::HandleDMgrEventL
// ---------------------------------------------------------
//

void RHttpDownloadMgr::HandleDMgrEventL( RHttpDownload& aDownload, 
                                         THttpDownloadEvent aEvent )
    {
    CLOG_ENTERFN( "RHttpDownloadMgr::HandleDMgrEventL" )
    iExtension->iEventBroadcastLevel++;
    CLOG_WRITE_FORMAT( "aDownload = %x", &aDownload );
    CLOG_WRITE_FORMAT( "Inc iEventBroadcastLevel = %d", iExtension->iEventBroadcastLevel );
    // In case of EHttpDlDeleted getting most of the attributes are forbidden,
    // because the engine is most likely is not ready to serve! Some of the
    // attributes are buffered in client side.
    aDownload.SetEventType( aEvent.iDownloadState );

    if( (( EHttpDlInprogress == aEvent.iDownloadState ) && ( EHttpProgCodDescriptorDownloaded == aEvent.iProgressState ))||
        (( EHttpDlInprogress == aEvent.iDownloadState ) && ( EHttpProgCodDownloadShouldResume == aEvent.iProgressState ))||
        (( EHttpDlPaused == aEvent.iDownloadState ) && ( EHttpProgCodDescriptorDownloaded == aEvent.iProgressState ))
      )
        {
        TBool isCod( ETrue );

        if(EHttpProgCodDownloadShouldResume == aEvent.iProgressState)
        	{
        	//resume only for apps with non-zero uid. otherwise the resume will happen from music player which sets the appuid as zero.
        	TInt32 clientAppUid(0); 
            GetIntAttribute(EDlMgrAppUid , clientAppUid);         
            if( !clientAppUid )
                {
                iExtension->iEventBroadcastLevel--;
                return;
                }
        	}
        	
        else
            {
            TRAPD( err, isCod = aDownload.CheckContentTypeAndCreateCodDownloadL() );
            if( isCod )
                {
                if( err )
                    {
                    // The error code is processed by the server
                    aDownload.SetOnError( err );
                    iExtension->iEventBroadcastLevel--;
                    return;                
                    }
                }                
                
            }
            TRAPD( err, aDownload.DoStartCodL() );
            if( err )
                {
                aDownload.SetOnError( err );
                iExtension->iEventBroadcastLevel--;
                return; 
                }              
  
        }
    else if( EHttpDlCancelTransaction == aEvent.iDownloadState )
        {
        aDownload.DeleteTransaction();
        }     
           
    else if( EHttpProgCodDownloadPause == aEvent.iProgressState )
        {
        if(aDownload.iCodDownload)
            {
            aDownload.iCodDownload->Pause();
            }
        }
    else if( EHttpDlProgProgressive == aEvent.iProgressState )
        {
        if(aDownload.iCodDownload)
            {
            aDownload.iCodDownload->SetCodDlAttached(ETrue);
            }
        }        
    else if( EHttpDlProgNonProgressive == aEvent.iProgressState )
        {
        if(aDownload.iCodDownload)
            {
            aDownload.iCodDownload->SetCodDlAttached(EFalse);
            }
        }        

    // TODO: make sure that all COD test cases works OK

    // ...and close the download.
    if( EHttpDlDeleted == aEvent.iDownloadState )
        {
        CloseDownload( &aDownload );
        }        
        
    iExtension->iEventBroadcastLevel--;

    // When a download completes, close the subsession to make a message slot free.
    // Also the required information will be cached before closing the subsession
    if( EHttpDlMultipleMOCompleted == aEvent.iDownloadState  && 
    		( 
    		EHttpProgContentFileMoved == aEvent.iProgressState ||
    		EHttpProgContentFileMovedAndDestFNChanged == aEvent.iProgressState 
    		)
    	)
    	{
    		//Store all the info clinet side in RHttpDownload's extension API
    		aDownload.SaveDownloadInfoL();
    		//Close the subsession to free up the message slot
    		aDownload.CloseSubSession();
    	}    
	TInt count = iObservers->Count();
    for( TInt i = 0; i < count; i++ )
        {
        CLOG_WRITE_FORMAT( "HandleDMgrEventL( aDownload = 0x%x)", this );
        TRAP_IGNORE( (*iObservers)[i]->HandleDMgrEventL( aDownload, aEvent ) );
        if(!iObservers)break;
        
        }
    
    //CLOG_WRITE_FORMAT( "Dec iEventBroadcastLevel = %d", iExtension->iEventBroadcastLevel );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::BroadcastEvent
// ---------------------------------------------------------
//
void RHttpDownloadMgr::BroadcastEvent( RHttpDownload& aDownload, 
                                       THttpDownloadEvent aEvent )
    {
    CLOG_WRITE_3( "BroadcastEvent: dl [%x], DownloadState [%d], ProgressState [%d]", this, aEvent.iDownloadState, aEvent.iProgressState );
    for( TInt i = 0; i < iObservers->Count(); i++ )
        {        
        TRAP_IGNORE( (*iObservers)[i]->HandleDMgrEventL( aDownload, aEvent ) );
        // The download shouldn't be deleted in nested loops!!!
        if( 1 == iExtension->iEventBroadcastLevel )
            {
            if( aDownload.IsToBeDeleted() )
                {
                // Decremented before delete because we check the
                // value in aDownload.Delete();
                iExtension->iEventBroadcastLevel--;
                CLOG_WRITE_FORMAT( "Dec iEventBroadcastLevel = %d", iExtension->iEventBroadcastLevel );
                aDownload.Delete();
                iExtension->iEventBroadcastLevel++;
                return;
                }
            }
        }    
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::HandleSessionEventL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::HandleSessionEventL( TInt aHandle, THttpDownloadEvent aEvent )
    {
    TRAP_IGNORE( DoHandleSessionEventL( aHandle, aEvent ) );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DoHandleSessionEventL
// ---------------------------------------------------------
//
void RHttpDownloadMgr::DoHandleSessionEventL( TInt aHandle, THttpDownloadEvent aEvent )
    {
    RHttpDownload* download = new (ELeave) RHttpDownload ( this );
    CleanupStack::PushL( download );
    CleanupClosePushL( *download );
    // Attach subsession to the server by the handle.
    download->AttachL( aHandle );
    AddToArrayL( download );
    CleanupStack::Pop( download ); //download
    // Forward the event to the client
    HandleDMgrEventL( *download, aEvent );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::StartSessionEventNotification
// ---------------------------------------------------------
//
void RHttpDownloadMgr::StartSessionEventNotification( const TDesC8& aDownloadState,
                                                      const TDesC8& aProgressState,
                                                      const TDesC8& aHandle,
                                                      TRequestStatus& aStatus )
    {
    CLOG_ENTERFN( "RHttpDownload::StartSessionEventNotification" )

    SendReceive( EHttpDownloadMgrSessionEventSubscription, 
                 TIpcArgs( &aDownloadState, &aProgressState, &aHandle ), 
                 aStatus );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::CancelSessionEventNotification
// ---------------------------------------------------------
//
void RHttpDownloadMgr::CancelSessionEventNotification()
    {
    CLOG_WRITE( "RHttpDownload::CancelSessionEventNotification" )

    SendReceive( EHttpDownloadMgrSessionEventCancel, TIpcArgs() );
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::PackedDefaultAttributesLC
// ---------------------------------------------------------
//
HBufC8* RHttpDownloadMgr::PackedDefaultAttributesLC()
    {
    HBufC8* buf = NULL;
    if( iDefaultAttribs )
        {
        
        buf = TDMgrUtils::PackedAttributesL( iDefaultAttribs );
        CleanupStack::PushL( buf );
        }
    else
        {
        buf = HBufC8::NewLC( 0 );
        }

    return buf;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::DoFindDownloadL
// ---------------------------------------------------------
//
RHttpDownload* RHttpDownloadMgr::DoFindDownloadL( const TDesC8& aUrl, const TDesC8& aMsgBody )
    {
    RHttpDownload* retVal = NULL;
    TInt pushCounter( 0 );

    HBufC8* escaped = EscapeUtils::EscapeDecodeL( aUrl );
    CleanupStack::PushL( escaped ); ++pushCounter;

    TUriParser8 compUri; 
    compUri.Parse( *escaped );

    TPtrC8 scheme( compUri.Extract( EUriScheme ) );

    CUri8* url = CUri8::NewLC(); ++pushCounter;

    if( scheme.Length() )
        {
        if( scheme != KHttpScheme &&
            scheme != KHttpsScheme )
            // this url has an unsupported scheme
            {
            User::Leave( KErrArgument );
            }
        else
            {
            url->SetComponentL( scheme, EUriScheme );
            }
        }
    else
        {
        url->SetComponentL( KHttpScheme, EUriScheme );
        }
   
    url->SetComponentL( compUri.Extract( EUriHost ), EUriHost );
    url->SetComponentL( compUri.Extract( EUriPath ), EUriPath );
    url->SetComponentL( compUri.Extract( EUriQuery ), EUriQuery );
    url->SetComponentL( compUri.Extract( EUriFragment ), EUriFragment );
    
    if( compUri.IsPresent( EUriPort ) )
        {
        url->SetComponentL( compUri.Extract( EUriPort ), EUriPort );
        }
    else
        {
        TBuf8<10> port;

        port.Format( _L8("%d"), KDefaultPort );

        url->SetComponentL( port, EUriPort );
        }
   
    TBuf8<KHashLength> hash_req;
    HashL( aMsgBody, hash_req );
    
    TUriParser8 parsed_req;
    
    parsed_req.Parse( url->Uri().UriDes() );

    for( TInt i = 0; i < iDownloadArray->Count(); i++ )
        {
        if( (*iDownloadArray)[i]->IsDownloadL( parsed_req, hash_req ) )
            {
            retVal = (*iDownloadArray)[i];
            break;
            }
        }    
        
    CleanupStack::PopAndDestroy( pushCounter );

    return retVal;
    }

// ---------------------------------------------------------
// RHttpDownloadMgr::IsEventBroadcasting
// ---------------------------------------------------------
//
TBool RHttpDownloadMgr::IsEventBroadcasting()
    {
    CLOG_WRITE( "RHttpDownload::IsEventBroadcasting" )
    return (0 < iExtension->iEventBroadcastLevel);
    }
    
// ---------------------------------------------------------
// RHttpDownloadMgr::IsEventBroadcasting
// ---------------------------------------------------------
//       
TInt RHttpDownloadMgr::EventPriorityFlag() const
    {
    return iExtension->iAdjustEventPriorityFlag;
    }
        
// ---------------------------------------------------------
// RHttpDownloadMgr::IncrementEventPriorityFlag
// ---------------------------------------------------------
//       
void RHttpDownloadMgr::IncrementEventPriorityFlag()
    {
    iExtension->iAdjustEventPriorityFlag++;
    }
        
// ---------------------------------------------------------
// RHttpDownloadMgr::IncrementEventPriorityFlag
// ---------------------------------------------------------
//       
void RHttpDownloadMgr::DecrementEventPriorityFlag()
    {
    iExtension->iAdjustEventPriorityFlag--;
    }