--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/cache/src/HttpCacheManager.cpp Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,806 @@
+/*
+* 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 CHttpCacheManager
+*
+*/
+
+// INCLUDE FILES
+#include "HttpCacheManager.h"
+#include "HttpCacheHandler.h"
+#include "HttpCacheUtil.h"
+#include <CenRepNotifyHandler.h>
+#include <HttpCacheManagerInternalCRKeys.h>
+#include <CoreApplicationUIsSDKCRKeys.h>
+#include <centralrepository.h>
+#include <FeatMgr.h>
+#include <http/RHTTPTransaction.h>
+#include <SysUtilDomainCRKeys.h>
+#include <eikenv.h>
+#include <f32file.h>
+#include <e32hashtab.h>
+#include <mmf/common/mmfcontrollerpluginresolver.h>
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// kbyte
+const TUint KDefaultCacheSize = 1048576; // 1MB = 1024*1024
+_LIT( KDefaultCacheDir, "c:\\cache\\");
+_LIT( KDefaultIndexFile, "index.dat" );
+_LIT( KDefaultOpIndexFile, "index_op.dat" );
+_LIT( KDefaultVSSIndexFile, "index_vss.dat" );
+_LIT( KIndexFileExtension, ".dat" );
+_LIT8( KVSSHeaderFileldName, "X-Vodafone-Content" );
+_LIT8( KVSSHeaderFileldValue, "Portal" );
+
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::CHttpCacheManager
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CHttpCacheManager::CHttpCacheManager():iCacheFolder( KDefaultCacheDir )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheManager::ConstructL()
+ {
+ CreateCacheHandlersL();
+
+ // read offline mode
+ if( FeatureManager::FeatureSupported( KFeatureIdOfflineMode ) )
+ {
+ // check if connection is not allowed and
+ // come up with a listerner on the offline setting
+ TInt connAllowed( 1 );
+
+ iOfflineRepository = CRepository::NewL( KCRUidCoreApplicationUIs );
+
+ iOfflineRepository->Get( KCoreAppUIsNetworkConnectionAllowed, connAllowed );
+
+ iOfflineMode = !connAllowed;
+
+ iOfflineNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iOfflineRepository,
+ CCenRepNotifyHandler::EIntKey, (TUint32)KCoreAppUIsNetworkConnectionAllowed );
+ iOfflineNotifyHandler->StartListeningL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CHttpCacheManager* CHttpCacheManager::NewL()
+ {
+ CHttpCacheManager* self = new( ELeave ) CHttpCacheManager();
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// Destructor
+CHttpCacheManager::~CHttpCacheManager()
+ {
+ delete iOfflineNotifyHandler;
+ delete iOfflineRepository;
+ delete iCache;
+ delete iOperatorCache;
+ delete iOpDomain;
+ delete iphoneSpecificCache;
+ delete iVSSWhiteList;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::VSSRequestCheck
+//
+// -----------------------------------------------------------------------------
+//
+TBool CHttpCacheManager::VSSRequestCheck( const RHTTPTransaction& aTrans,
+ const RHTTPHeaders& aHttpHeader,
+ const TDesC8& aUrl )
+ {
+ TBool VSSTransaction ( EFalse );
+ if( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) )
+ {
+ RStringPool strP = aTrans.Session().StringPool();
+
+#ifdef __CACHELOG__
+ RHTTPHeaders headers ( aHttpHeader );
+ HBufC8* responseHeaderStr8 = HttpCacheUtil::HeadersToBufferLC( headers, strP );
+ HBufC* responseHeaderStr;
+ if( responseHeaderStr8 )
+ {
+ responseHeaderStr = HBufC::NewL( responseHeaderStr8->Length() );
+ responseHeaderStr->Des().Copy( responseHeaderStr8->Des() );
+ CleanupStack::PopAndDestroy(); // responseHeaderStr8;
+ TPtrC headerStr( responseHeaderStr->Des() );
+ HttpCacheUtil::WriteLog( 0, _L("========== VSS Header Start =========\n") );
+ HttpCacheUtil::WriteLog( 0, responseHeaderStr->Des() );
+ HttpCacheUtil::WriteLog( 0, _L("========== VSS Header End =========\n") );
+ delete responseHeaderStr;
+ }
+#endif
+
+ TPtrC8 nameStr ( KVSSHeaderFileldName() );
+
+ RStringF VSSnameStr = strP.OpenFStringL( nameStr );
+ CleanupClosePushL<RStringF>( VSSnameStr);
+
+ THTTPHdrVal tempVal;
+ if( aHttpHeader.GetField( VSSnameStr, 0, tempVal ) == KErrNone )
+ {
+ TPtrC8 valueStr ( KVSSHeaderFileldValue() );
+ RStringF VSSValueStr = strP.OpenFStringL( valueStr );
+ CleanupClosePushL<RStringF>( VSSValueStr );
+
+ if( tempVal == VSSValueStr )
+ {
+ VSSTransaction = ETrue;
+ }
+ CleanupStack::PopAndDestroy(); // VSSValueStr
+ }
+ CleanupStack::PopAndDestroy(); // VSSnameStr
+ } //end if( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) )
+ return VSSTransaction;
+ }
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RequestL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpCacheManager::RequestL(
+ RHTTPTransaction& aTrans,
+ TBrCtlDefs::TBrCtlCacheMode aCacheMode,
+ THttpCacheEntry& aCacheEntry )
+ {
+ //
+ TInt status( KErrNotFound );
+ if( iCacheEnabled || iVSSCacheEnabled )
+ {
+ CHttpCacheHandler* cache = CacheHandler( aTrans.Request().URI().UriDes(), NULL ) ;
+ __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ // adjust cache mode in case of offline operation
+ if( iOfflineMode )
+ {
+ aCacheMode = TBrCtlDefs::ECacheModeOnlyCache;
+ }
+ //
+ if( cache )
+ {
+ status = cache->RequestL( aTrans, aCacheMode, aCacheEntry );
+ // save cache handler even if the entry is not in the cache
+ // so that when the response comes back, we do not need to
+ // check the url
+ if( status == KErrNotFound && iVSSCacheEnabled )
+ {
+ status = iphoneSpecificCache->RequestL( aTrans, aCacheMode, aCacheEntry );
+ if( (status == KErrNotReady) || (status == KErrNone ) )
+ {
+ aCacheEntry.iCacheHandler = iphoneSpecificCache;
+ }
+ else
+ {
+ // No entry found in any cache. Default to normal cache
+ aCacheEntry.iCacheHandler = cache;
+ }
+ }
+ else
+ {
+ aCacheEntry.iCacheHandler = cache;
+ }
+ } //end if( cache )
+
+ }//end if( iCacheEnabled || iVSSCacheEnabled )
+ return status;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RequestHeadersL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpCacheManager::RequestHeadersL(
+ RHTTPTransaction& aTrans,
+ THttpCacheEntry& aCacheEntry )
+ {
+ TInt status( KErrNotFound );
+ if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler )
+ {
+ status = aCacheEntry.iCacheHandler->RequestHeadersL( aTrans, aCacheEntry );
+ }
+ return status;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RequestNextChunkL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC8* CHttpCacheManager::RequestNextChunkL(
+ RHTTPTransaction& aTrans,
+ TBool& aLastChunk,
+ THttpCacheEntry& aCacheEntry )
+ {
+ HBufC8* bodyStr = NULL;
+
+ if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler )
+ {
+ bodyStr = aCacheEntry.iCacheHandler->RequestNextChunkL( aTrans, aLastChunk, aCacheEntry );
+ }
+ return bodyStr;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RequestClosed
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CHttpCacheManager::RequestClosed(
+ RHTTPTransaction* aTrans,
+ THttpCacheEntry& aCacheEntry )
+ {
+ if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler )
+ {
+ aCacheEntry.iCacheHandler->RequestClosed( aTrans, aCacheEntry );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::ReceivedResponseHeadersL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CHttpCacheManager::ReceivedResponseHeadersL(
+ RHTTPTransaction& aTrans,
+ THttpCacheEntry& aCacheEntry )
+ {
+ if( iCacheEnabled || iVSSCacheEnabled )
+ {
+ if( iVSSCacheEnabled && VSSRequestCheck( aTrans, aTrans.Response().GetHeaderCollection(),
+ aTrans.Request().URI().UriDes() ) )
+ {
+ //Modify the cache handler if VSS specific
+ aCacheEntry.iCacheHandler = iphoneSpecificCache;
+ }
+ if( aCacheEntry.iCacheHandler )
+ {
+ aCacheEntry.iCacheHandler->ReceivedResponseHeadersL( aTrans, aCacheEntry );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::ReceivedResponseBodyDataL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CHttpCacheManager::ReceivedResponseBodyDataL(
+ RHTTPTransaction& aTrans,
+ MHTTPDataSupplier& aBodyDataSupplier,
+ THttpCacheEntry& aCacheEntry )
+ {
+ if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler )
+ {
+ aCacheEntry.iCacheHandler->ReceivedResponseBodyDataL( aTrans, aBodyDataSupplier, aCacheEntry );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::ResponseComplete
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CHttpCacheManager::ResponseComplete(
+ RHTTPTransaction& aTrans,
+ THttpCacheEntry& aCacheEntry )
+ {
+ if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler )
+ {
+ aCacheEntry.iCacheHandler->ResponseComplete( aTrans, aCacheEntry );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RemoveAllL
+// Removes all files from HTTP cache. Also tries to remove orphaned files,
+// i.e files found on disk, but not registered in the cache's lookup table
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpCacheManager::RemoveAllL()
+ {
+ TInt numOfBytes( 0 );
+ // do not remove op cache
+ if( iCacheEnabled )
+ {
+ numOfBytes = iCache->RemoveAllL();
+ }
+
+ //failure here is not mission critical
+ TRAPD( error, RemoveOrphanedFilesL() );
+
+ return numOfBytes;
+ }
+
+
+// Hash function for Symbian file paths: discards case first
+static TUint32 FilepathHash(const TDesC& aDes)
+{
+ //since this function is intensively used by the HashMap,
+ //keeping (slow) heap allocation out of it.
+ TBuf<KMaxPath> normalized ( aDes );
+
+ normalized.LowerCase();
+ return DefaultHash::Des16( normalized );
+}
+
+// Comparator for Symbian file paths: Use case-insensitive compare
+static TBool FilepathIdent(const TDesC& aL, const TDesC& aR)
+{
+ return ( aL.CompareF(aR) == 0 );
+}
+
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RemoveOrphanedFilesL
+// Removes header/body files that exist on the file-system, but are not known to the in-memory Cache lookup table(s)
+// We do this because cache performance degrades substantially if there are too many files in a Symbian FAT32 directory.
+// Browser crash or out-of-battery situations may cause SaveLookuptable() to be not called, leading to such "orphaned files".
+// Due to high file-server interaction, don't call this method from performance critical code.
+// -----------------------------------------------------------------------------
+void CHttpCacheManager::RemoveOrphanedFilesL()
+ {
+
+ //Map that contains pointers to fully-qualified file paths as Keys, and "to be deleted flag" as Value.
+ RPtrHashMap<TDesC, TInt> onDiskFilesMap(&FilepathHash, &FilepathIdent);
+ CleanupClosePushL( onDiskFilesMap );
+
+ //Pointers to the following TInt are used as VALUES in the HashMap...
+ // so they must be in scope for the lifecycle of the HashMap.
+ const TInt needsDelete( 1 );
+ const TInt noDelete( 0 );
+
+ //collects objects that need to be deleted later on
+ RPointerArray<HBufC> cleanupList;
+ CleanupResetAndDestroyPushL( cleanupList );
+
+ RFs rfs = CCoeEnv::Static()->FsSession();
+ CDirScan* scanner = CDirScan::NewLC( rfs );
+
+ //Configure CDirScan to tell you all contents of a particular directory hierarchy
+ scanner->SetScanDataL( iCacheFolder, KEntryAttNormal, ESortNone );
+ CDir* matchingFiles( 0 );
+
+ //Step 1. Find out all files on disk: by walking the directory hierarchy, one directory at a time
+ for (;;)
+ {
+ //1a. Get list of files in current directory, NULL if no directory left in tree
+ scanner->NextL( matchingFiles );
+ if ( !matchingFiles )
+ break;
+
+ TPtrC dir( scanner->FullPath() );
+
+ //1b. Add any files found to the HashTable
+ const TInt nMatches = matchingFiles->Count();
+ for ( TInt i = 0; i < nMatches; i++ )
+ {
+ TEntry entry ( (*matchingFiles)[i] ) ;
+ if (entry.iName.Right( KIndexFileExtension().Length() ).
+ CompareF( KIndexFileExtension ) != 0) // ignore any .dat index files
+ {
+ HBufC* fullPath = HBufC::NewL( dir.Length() + entry.iName.Length() );
+ cleanupList.Append( fullPath ); //keep object safe for later destruction
+ fullPath->Des().Append( dir );
+ fullPath->Des().Append( entry.iName ); //a fully qualified file path
+ onDiskFilesMap.Insert( fullPath, &needsDelete ); //add to the hash
+ }
+ }
+
+
+ delete matchingFiles;
+ } // End of step 1: adding all known files on disk to Map
+
+ CleanupStack::PopAndDestroy( 1, scanner );
+
+#ifdef __CACHELOG__
+ {
+ RDebug::Print(_L("-----------START PRINTING MAP OF SIZE %d---------"), onDiskFilesMap.Count());
+ TPtrHashMapIter<TDesC, TInt> iter(onDiskFilesMap);
+ const TDesC* key;
+ while ((key = iter.NextKey()) != 0)
+ {
+ const TInt val = *(iter.CurrentValue());
+ RDebug::Print(_L("MAP WALK: %S, with value = %d "), key, val);
+ }
+ RDebug::Print(_L("-----------DONE PRINTING MAP-------------"));
+ }
+#endif
+
+ //Step 2. Get list of known (non-orphaned) files in each Cache's in-memory lookup table. Flag them as DO NOT DELETE
+ RPointerArray<TDesC> knownFiles;
+ CleanupClosePushL( knownFiles );
+ //Ask CacheHandlers to add their KNOWN files to this array. No ownership transfer occurs.
+ //Don't go ahead if any of the cache handlers choke to insure correct deletion of files.
+ if (iCache)
+ User::LeaveIfError( iCache->ListFiles( knownFiles ) );
+ if (iOperatorCache)
+ User::LeaveIfError( iOperatorCache->ListFiles( knownFiles ) );
+ if (iphoneSpecificCache)
+ User::LeaveIfError( iphoneSpecificCache->ListFiles( knownFiles ) );
+
+ //2a. HashTable lookup, and modification of flag
+ for (TInt i = 0; i < knownFiles.Count(); i++)
+ {
+ //lookup filename
+ TInt* ptr = onDiskFilesMap.Find( *(knownFiles[i]) );
+ if (ptr)
+ {
+ // Reinsert into Map, this time with NO DELETE
+ onDiskFilesMap.Insert( knownFiles[i], &noDelete );
+
+ // Add the header file to HashMap
+ HBufC* headerFile = HBufC::NewL( KHttpCacheHeaderExt().Length() + (*(knownFiles[i])).Length() );
+ cleanupList.Append( headerFile ); //keep for later destruction
+ TPtr ptr( headerFile->Des() );
+ HttpCacheUtil::GetHeaderFileName( *(knownFiles[i]), ptr );
+ onDiskFilesMap.Insert( headerFile, &noDelete ); // register Header files as NO DELETE
+ }
+ }
+
+ knownFiles.Close();
+ CleanupStack::Pop( 1, &knownFiles );
+
+ //Step 3. Delete all files on disk that don't belong to any of the Cache Handlers.
+ CFileMan* fileMan = CFileMan::NewL( rfs );
+ TPtrHashMapIter<TDesC, TInt> iter( onDiskFilesMap );
+ const TDesC* key;
+ while ((key = iter.NextKey()) != 0)
+ {
+ const TInt value ( *(iter.CurrentValue()) );
+ if ( value == 1 ) { // file needs deletion
+ fileMan->Delete( *key );
+ }
+ }
+ delete fileMan;
+
+ CleanupStack::Pop(1, &cleanupList);
+ cleanupList.ResetAndDestroy(); //should delete all HBufC objects
+
+ CleanupStack::Pop(1, &onDiskFilesMap);
+ onDiskFilesMap.Close(); // doesn't own any K,V object
+
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::RemoveL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpCacheManager::RemoveL(
+ const TDesC8& aUrl )
+ {
+ TInt status( KErrNotFound );
+ if( iCacheEnabled )
+ {
+ // do not remove op cache
+ status = iCache->RemoveL( aUrl );
+ }
+ return status;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::Find
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CHttpCacheManager::Find(
+ const TDesC8& aUrl )
+ {
+ TBool found( EFalse );
+ //
+ if( iCacheEnabled || iVSSCacheEnabled )
+ {
+ CHttpCacheHandler* cache = CacheHandler( aUrl, NULL );
+
+ __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ //
+ if( cache )
+ {
+ found = cache->Find( aUrl );
+ }
+
+ if( !found && iVSSCacheEnabled )
+ {
+ found = iphoneSpecificCache->Find( aUrl );
+ }
+ }
+ return found;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::VSSHeaderCheck
+//
+// -----------------------------------------------------------------------------
+//
+TBool CHttpCacheManager::VSSHeaderCheck( TDes8* aHttpHeaderString ) const
+ {
+ TBool found ( EFalse );
+ if( aHttpHeaderString->Size() > 0 )
+ {
+ TPtrC8 nameStr8( KVSSHeaderFileldName() );
+
+ TInt VSSnameLocation = aHttpHeaderString->FindC( nameStr8 ) ;
+
+ if ( VSSnameLocation != KErrNotFound )
+ {
+ TPtrC8 valueStr8( KVSSHeaderFileldValue() );
+ TInt VSSvalueLocation = aHttpHeaderString->FindC( KVSSHeaderFileldValue() );
+
+ if ( (VSSvalueLocation != KErrNotFound ) && ( VSSnameLocation < VSSvalueLocation ) )
+ {
+ found = ETrue;
+ }
+ } //end if ( VSSnameLocation != KErrNotFound )
+ } //end if( aHttpHeaderString.Size() > 0 )
+
+ return found;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::SaveL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CHttpCacheManager::SaveL(
+ const TDesC8& aUrl,
+ const TDesC8& aHeader,
+ const TDesC8& aContent,
+ const TDesC8& aHttpHeaderString)
+ {
+ TBool saved( EFalse );
+ //
+ if( iCacheEnabled || iVSSCacheEnabled )
+ {
+ HBufC8* headerStr = HBufC8::NewL( aHttpHeaderString.Length() );
+ headerStr->Des().Copy( aHttpHeaderString );
+ TPtr8 headerStrPtr8 ( headerStr->Des() ); //Any Type of TPtrc8
+ CHttpCacheHandler* cache = CacheHandler( aUrl, &headerStrPtr8 );
+ delete headerStr;
+ __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ //
+ if( cache )
+ {
+ saved = cache->SaveL( aUrl, aHeader, aContent );
+ }
+ }
+ return saved;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::AddHeaderL
+// Not supported for Vodafone specific storage.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CHttpCacheManager::AddHeaderL(
+ const TDesC8& aUrl,
+ const TDesC8& aName,
+ const TDesC8& aValue )
+ {
+ TBool status( KErrNotFound );
+ //
+ if( iCacheEnabled || iVSSCacheEnabled )
+ {
+ CHttpCacheHandler* cache = CacheHandler( aUrl, NULL );
+ __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ //
+ if( cache )
+ {
+ status = cache->AddHeaderL( aUrl, aName, aValue );
+ }
+ }
+ return status;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::CreateCacheHandlersL
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheManager::HandleNotifyString(
+ const TUint32 aKeyId,
+ const TDesC& aValue )
+ {
+ // check offline mode
+ if( aKeyId == KCoreAppUIsNetworkConnectionAllowed )
+ {
+ iOfflineMode = ( aValue == _L("1") ? EFalse : ETrue );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::CreateCacheHandlersL
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheManager::CreateCacheHandlersL()
+ {
+ // read cache settings
+ CRepository* repository = CRepository::NewLC( KCRUidCacheManager );
+ CRepository* repositoryDiskLevel = CRepository::NewLC( KCRUidDiskLevel );
+ TInt err;
+
+ // cache on/off
+ TInt cacheEnabled( 0 );
+ err = repository->Get( KCacheManagerHttpCacheEnabled, cacheEnabled );
+
+ iCacheEnabled = cacheEnabled;
+
+ // cache size
+ TInt cacheSize( KDefaultCacheSize );
+ repository->Get( KCacheManagerHttpCacheSize, cacheSize );
+
+ repository->Get( KCacheManagerHttpCacheFolder, iCacheFolder );
+ // fix folder by appending trailing \\ to the end -symbian thing
+ // unless it is already there
+ if( iCacheFolder.LocateReverse( '\\' ) != iCacheFolder.Length() - 1 )
+ {
+ iCacheFolder.Append( _L("\\") );
+ }
+
+ // get drive letter for sysutil
+ TParsePtrC pathParser( iCacheFolder );
+ TDriveUnit drive = pathParser.Drive();
+ // get critical level
+ // RAM drive can have different critical level
+ TVolumeInfo vinfo;
+ User::LeaveIfError( CCoeEnv::Static()->FsSession().Volume( vinfo, drive ) );
+ //
+ TInt criticalLevel;
+ User::LeaveIfError( repositoryDiskLevel->Get( ( vinfo.iDrive.iType == EMediaRam ? KRamDiskCriticalLevel : KDiskCriticalThreshold ),
+ criticalLevel ) );
+
+ if( (err == KErrNone) && iCacheEnabled )
+ {
+ // create cache handler
+ iCache = CHttpCacheHandler::NewL( cacheSize, iCacheFolder, KDefaultIndexFile(), criticalLevel );
+
+ // create operator cache. same settings
+ if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) )
+ {
+ TBuf<512> url;
+ // if domain is missing, then no need to read further
+ if( repository->Get( KOperatorDomainUrl, url ) == KErrNone )
+ {
+
+ HBufC8* opDomain8 = HBufC8::NewL( url.Length() );
+ CleanupStack::PushL(opDomain8);
+ opDomain8->Des().Append( url );
+
+ TInt slashPos = opDomain8->LocateReverse('/');
+ if(slashPos == -1)
+ {
+ slashPos = 0;
+ }
+ TPtrC8 temp = opDomain8->Left(slashPos);
+ iOpDomain = temp.AllocL();
+ CleanupStack::PopAndDestroy(opDomain8);
+
+ // op cache size
+ TInt opCacheSize( KDefaultCacheSize );
+ repository->Get( KOperatorCacheSize, opCacheSize );
+
+ // op cache folder
+ TFileName opCacheFolder( KDefaultCacheDir );
+ repository->Get( KOperatorCacheFolder, opCacheFolder );
+
+ if( opCacheFolder.LocateReverse( '\\' ) != opCacheFolder.Length() - 1 )
+ {
+ opCacheFolder.Append( _L("\\") );
+ }
+
+ // create op cache
+ iOperatorCache = CHttpCacheHandler::NewL( opCacheSize, opCacheFolder, KDefaultOpIndexFile(), criticalLevel );
+ }
+ } //end if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) )
+ } //end if( iCacheEnabled )
+
+ TInt VSScacheEnabled( 0 );
+ err = repository->Get( KPhoneSpecificCacheEnabled, VSScacheEnabled );
+
+ iVSSCacheEnabled = VSScacheEnabled;
+
+ if( (err == KErrNone) && iVSSCacheEnabled )
+ {
+ // cache size
+ TInt VSScacheSize( KDefaultCacheSize );
+ repository->Get( KPhoneSpecificCacheSize, VSScacheSize );
+
+ // cache folder
+ TFileName VSScacheFolder( KDefaultCacheDir );
+ // ignore cache folder. use c:\ to save memory. (same for operator cache. see below)
+ repository->Get( KPhoneSpecificCacheFolder, VSScacheFolder );
+ // fix folder by appending trailing \\ to the end -symbian thing
+ // unless it is already there
+ if( VSScacheFolder.LocateReverse( '\\' ) != VSScacheFolder.Length() - 1 )
+ {
+ VSScacheFolder.Append( _L("\\") );
+ }
+
+ //Get the white list
+ TBuf<2048> whiteList;
+
+ if( repository->Get( KPhoneSpecificCacheDomainUrl, whiteList ) == KErrNone )
+ {
+ iVSSWhiteList = HBufC8::NewL( whiteList.Length() );
+ iVSSWhiteList->Des().Append( whiteList );
+ }
+ else
+ {
+ iVSSWhiteList = NULL;
+ }
+
+ // create cache handler
+ iphoneSpecificCache = CHttpCacheHandler::NewL( VSScacheSize, VSScacheFolder, KDefaultVSSIndexFile(), criticalLevel );
+ }
+ CleanupStack::PopAndDestroy(2); // repository, , repositoryDiskLevel
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheManager::CacheHandler
+//
+// -----------------------------------------------------------------------------
+//
+CHttpCacheHandler* CHttpCacheManager::CacheHandler(
+ const TDesC8& aUrl,
+ TDes8* aHttpHeaderString ) const
+ {
+ CHttpCacheHandler* cache;
+ if( iVSSCacheEnabled && aHttpHeaderString && VSSHeaderCheck( aHttpHeaderString ) )
+ {
+ cache = iphoneSpecificCache;
+ }
+ else
+ {
+ cache = ( ( iOpDomain && HttpCacheUtil::OperatorCacheContent( iOpDomain->Des(), aUrl ) ) ? iOperatorCache : iCache );
+ }
+ return cache;
+ }
+// End of File
+