diff -r 000000000000 -r 84ad3b177aa3 pushmtm/Plugins/PushContentHandler/PushMtmCacheSupply.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pushmtm/Plugins/PushContentHandler/PushMtmCacheSupply.cpp Mon Mar 30 12:49:49 2009 +0300 @@ -0,0 +1,363 @@ +/* +* Copyright (c) 2006 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: Implementation of CPushMtmCacheSupply +* +*/ + + +// INCLUDE FILES +#include "PushMtmCacheSupply.h" +#include "HttpCacheManager.h" +#include "PushMtmCacheDataSupplier.h" + +#include +#include +#include +#include + + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +const TInt KResponseTimeout = 0; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::CPushMtmCacheSupply +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPushMtmCacheSupply::CPushMtmCacheSupply(MCacheSupplyCallbacks* aCacheSupplyCallbacks ): + // closed by default + iReponseState( THTTPEvent::EClosed ) + { + iCacheEntry.iCacheHandler = NULL; + iCacheEntry.iCacheEntry = NULL; + iCacheSupplyCallbacks = aCacheSupplyCallbacks; + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::ConstructL(CHttpCacheManager* aCacheMgr) + { + iCacheManager = aCacheMgr; + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPushMtmCacheSupply* CPushMtmCacheSupply::NewL(CHttpCacheManager* aCacheMgr, MCacheSupplyCallbacks* aCacheSupplyCallbacks ) + { + CPushMtmCacheSupply* self = new( ELeave ) CPushMtmCacheSupply( aCacheSupplyCallbacks); + + CleanupStack::PushL( self ); + self->ConstructL(aCacheMgr); + CleanupStack::Pop(); + + return self; + } + +// Destructor +CPushMtmCacheSupply::~CPushMtmCacheSupply() + { + delete iDataSupplier; + CloseRequest(); + if (iResponseTimer) + { + iResponseTimer->Cancel(); + } + delete iResponseTimer; + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::StartRequestL +// +// +// ----------------------------------------------------------------------------- +// +TInt CPushMtmCacheSupply::StartRequestL( ) + { + TInt status; + + status = iCacheManager->RequestL( *(iCacheSupplyCallbacks->Transaction()), + TBrCtlDefs::ECacheModeNormal , iCacheEntry ); + // start a timer that feeds the content to the transaction + if( status == KErrNone ) + { + iClosed = EFalse; + // set response state. start with the http headers. + iReponseState = THTTPEvent::EGotResponseHeaders; + // + iResponseTimer = CPeriodic::NewL( CActive::EPriorityHigh ); + iResponseTimer->Start( KResponseTimeout, KResponseTimeout, TCallBack( &ResponseCallbackL, this ) ); + } + return status; + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::CloseRequest +// +// +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::CloseRequest() + { + if( !iClosed ) + { + iCacheManager->RequestClosed( (iCacheSupplyCallbacks->Transaction()), iCacheEntry ); + iClosed = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::HeadersReceived +// +// +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::HeadersReceivedL() + { + // do not cache content we just sent off + if( iReponseState == THTTPEvent::EClosed ) + { + RHTTPTransaction* trans = iCacheSupplyCallbacks->Transaction(); + iCacheManager->ReceivedResponseHeadersL( *(iCacheSupplyCallbacks->Transaction()), iCacheEntry ); + // + iNotModified = trans->Response().StatusCode() == HTTPStatus::ENotModified; + if( iNotModified ) + { + // change from 304 to 200 -otherwise trans exits with EFailed + trans->Response().SetStatusCode( HTTPStatus::EOk ); + } + } + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::BodyReceivedL +// +// +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::BodyReceivedL() + { + // do not cache content we just sent off + if( iReponseState == THTTPEvent::EClosed ) + { + RHTTPTransaction* trans = iCacheSupplyCallbacks->Transaction(); + MHTTPDataSupplier* supplier = trans->Response().Body(); + // + iCacheManager->ReceivedResponseBodyDataL( *trans, *supplier, iCacheEntry ); + } + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::ResponseComplete +// +// +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::ResponseCompleteL() + { + if( iReponseState == THTTPEvent::EClosed ) + { + RHTTPTransaction* trans = iCacheSupplyCallbacks->Transaction(); + // not modified needs body before response complete + if( iNotModified ) + { + // use cache + // close response first + iCacheManager->ResponseComplete( *trans, iCacheEntry ); + // request the item from cache + if( iCacheManager->RequestL( *trans, TBrCtlDefs::ECacheModeOnlyCache, iCacheEntry ) == KErrNone ) + { + // ser + iReponseState = THTTPEvent::EGotResponseBodyData; + // + SendBodyL(); + CloseRequest(); + } + } + else + { + // normal response complete + iCacheManager->ResponseComplete( *trans, iCacheEntry ); + } + } + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::ResponseCallbackL +// +// +// ----------------------------------------------------------------------------- +// +TInt CPushMtmCacheSupply::ResponseCallbackL( + TAny* aAny ) + { + // + CPushMtmCacheSupply* thisObj = (CPushMtmCacheSupply*)aAny; + thisObj->SupplyResponseL(); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::SupplyResponseL +// +// +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::SupplyResponseL() + { + RHTTPTransaction* trans = iCacheSupplyCallbacks->Transaction(); + // + switch( iReponseState ) + { + case THTTPEvent::EGotResponseHeaders: + { + // + iFailed = EFalse; + if( iCacheManager->RequestHeadersL( *trans, iCacheEntry ) == KErrNone ) + { + // + trans->Response().SetStatusCode( HTTPStatus::EOk ); + // + iCacheSupplyCallbacks->HandleEventL( THTTPEvent::EGotResponseHeaders ); + // move to the next state + iReponseState = THTTPEvent::EGotResponseBodyData; + } + else + { + // move to the next state + iFailed = ETrue; + // move to the next state + iReponseState = THTTPEvent::EResponseComplete; + } + break; + } + case THTTPEvent::EGotResponseBodyData: + { + // + SendBodyL(); + // move to the next state + iReponseState = THTTPEvent::EResponseComplete; + break; + } + case THTTPEvent::EResponseComplete: + { + iCacheSupplyCallbacks->HandleEventL( THTTPEvent::EResponseComplete ); + // move to the next state + iReponseState = !iFailed ? THTTPEvent::ESucceeded : THTTPEvent::EFailed; + break; + } + case THTTPEvent::ESucceeded: + { + // move to the next state + iReponseState = THTTPEvent::EClosed; + // cancel timer + iResponseTimer->Cancel(); + // + iCacheSupplyCallbacks->HandleEventL( THTTPEvent::ESucceeded ); + // this obj is destroyed at this point + break; + } + case THTTPEvent::EFailed: + { + // move to the next state + iReponseState = THTTPEvent::EClosed; + // cancel timer + iResponseTimer->Cancel(); + // + iCacheSupplyCallbacks->HandleEventL( THTTPEvent::EFailed ); + // this obj is destroyed at this point + break; + } + default: + { + // + } + } + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::SendBodyL +// +// +// ----------------------------------------------------------------------------- +// +void CPushMtmCacheSupply::SendBodyL() + { + RHTTPTransaction* trans = iCacheSupplyCallbacks->Transaction(); + // + TBool lastChunk; + // currently it is always the last chunk + HBufC8* body = iCacheManager->RequestNextChunkL( *trans, lastChunk, iCacheEntry ); + if( body ) + { + CleanupStack::PushL( body ); + // create datasupplier and attach it to the transaction + if( !iDataSupplier ) + iDataSupplier = CPushMtmCacheDataSupplier::NewL( body ); + trans->Response().SetBody( *iDataSupplier ); + CleanupStack::Pop(); // body + // + iCacheSupplyCallbacks->HandleEventL( THTTPEvent::EGotResponseBodyData ); + } + else + { + // move to the next state + iFailed = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::PauseSupply +// ----------------------------------------------------------------------------- +void CPushMtmCacheSupply::PauseSupply() + { + if( iResponseTimer && iResponseTimer->IsActive() ) + iResponseTimer->Cancel(); + } + +// ----------------------------------------------------------------------------- +// CPushMtmCacheSupply::ResumeSupply +// ----------------------------------------------------------------------------- +void CPushMtmCacheSupply::ResumeSupply() + { + if( iResponseTimer && !iResponseTimer->IsActive() ) + iResponseTimer->Start( KResponseTimeout, KResponseTimeout, TCallBack( &ResponseCallbackL, this ) ); + } + +// End of File