diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/cache/src/HttpCacheManager.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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( VSSnameStr); + + THTTPHdrVal tempVal; + if( aHttpHeader.GetField( VSSnameStr, 0, tempVal ) == KErrNone ) + { + TPtrC8 valueStr ( KVSSHeaderFileldValue() ); + RStringF VSSValueStr = strP.OpenFStringL( valueStr ); + CleanupClosePushL( 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 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 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 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 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 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 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 +