|         |      1 /* | 
|         |      2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). | 
|         |      3 * All rights reserved. | 
|         |      4 * This component and the accompanying materials are made available | 
|         |      5 * under the terms of the License "Eclipse Public License v1.0" | 
|         |      6 * which accompanies this distribution, and is available | 
|         |      7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      8 * | 
|         |      9 * Initial Contributors: | 
|         |     10 * Nokia Corporation - initial contribution. | 
|         |     11 * | 
|         |     12 * Contributors: | 
|         |     13 * | 
|         |     14 * Description:  Implementation of CHttpCacheManager | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18 // INCLUDE FILES | 
|         |     19 #include "HttpCacheManager.h" | 
|         |     20 #include "HttpCacheHandler.h" | 
|         |     21 #include "HttpCacheUtil.h" | 
|         |     22 #include <CenRepNotifyHandler.h> | 
|         |     23 #include <HttpCacheManagerInternalCRKeys.h> | 
|         |     24 #include <CoreApplicationUIsSDKCRKeys.h> | 
|         |     25 #include <centralrepository.h> | 
|         |     26 #include <FeatMgr.h> | 
|         |     27 #include <http/RHTTPTransaction.h> | 
|         |     28 #include <SysUtilDomainCRKeys.h> | 
|         |     29 #include <eikenv.h> | 
|         |     30 #include <f32file.h> | 
|         |     31 #include <e32hashtab.h> | 
|         |     32 #include <mmf/common/mmfcontrollerpluginresolver.h> | 
|         |     33  | 
|         |     34 // EXTERNAL DATA STRUCTURES | 
|         |     35  | 
|         |     36 // EXTERNAL FUNCTION PROTOTYPES | 
|         |     37  | 
|         |     38 // CONSTANTS | 
|         |     39  | 
|         |     40 // kbyte | 
|         |     41 const TUint KDefaultCacheSize = 1048576; // 1MB = 1024*1024 | 
|         |     42 _LIT( KDefaultCacheDir, "c:\\cache\\"); | 
|         |     43 _LIT( KDefaultIndexFile, "index.dat" ); | 
|         |     44 _LIT( KDefaultOpIndexFile, "index_op.dat" ); | 
|         |     45 _LIT( KDefaultVSSIndexFile, "index_vss.dat" ); | 
|         |     46 _LIT( KIndexFileExtension, ".dat" ); | 
|         |     47 _LIT8( KVSSHeaderFileldName, "X-Vodafone-Content" ); | 
|         |     48 _LIT8( KVSSHeaderFileldValue, "Portal" ); | 
|         |     49  | 
|         |     50  | 
|         |     51 // MACROS | 
|         |     52  | 
|         |     53 // LOCAL CONSTANTS AND MACROS | 
|         |     54  | 
|         |     55 // MODULE DATA STRUCTURES | 
|         |     56  | 
|         |     57 // LOCAL FUNCTION PROTOTYPES | 
|         |     58  | 
|         |     59 // FORWARD DECLARATIONS | 
|         |     60  | 
|         |     61  | 
|         |     62 // ============================ MEMBER FUNCTIONS =============================== | 
|         |     63  | 
|         |     64 // ----------------------------------------------------------------------------- | 
|         |     65 // CHttpCacheManager::CHttpCacheManager | 
|         |     66 // C++ default constructor can NOT contain any code, that | 
|         |     67 // might leave. | 
|         |     68 // ----------------------------------------------------------------------------- | 
|         |     69 // | 
|         |     70 CHttpCacheManager::CHttpCacheManager():iCacheFolder( KDefaultCacheDir ) | 
|         |     71     { | 
|         |     72     } | 
|         |     73  | 
|         |     74 // ----------------------------------------------------------------------------- | 
|         |     75 // CHttpCacheManager::ConstructL | 
|         |     76 // Symbian 2nd phase constructor can leave. | 
|         |     77 // ----------------------------------------------------------------------------- | 
|         |     78 // | 
|         |     79 void CHttpCacheManager::ConstructL() | 
|         |     80     { | 
|         |     81     CreateCacheHandlersL(); | 
|         |     82  | 
|         |     83     // read offline mode | 
|         |     84     if( FeatureManager::FeatureSupported( KFeatureIdOfflineMode ) ) | 
|         |     85         { | 
|         |     86         // check if connection is not allowed and | 
|         |     87         // come up with a listerner on the offline setting | 
|         |     88         TInt connAllowed( 1 ); | 
|         |     89  | 
|         |     90         iOfflineRepository = CRepository::NewL( KCRUidCoreApplicationUIs ); | 
|         |     91  | 
|         |     92         iOfflineRepository->Get( KCoreAppUIsNetworkConnectionAllowed, connAllowed ); | 
|         |     93  | 
|         |     94         iOfflineMode = !connAllowed; | 
|         |     95  | 
|         |     96         iOfflineNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iOfflineRepository, | 
|         |     97             CCenRepNotifyHandler::EIntKey, (TUint32)KCoreAppUIsNetworkConnectionAllowed ); | 
|         |     98         iOfflineNotifyHandler->StartListeningL(); | 
|         |     99         } | 
|         |    100     } | 
|         |    101  | 
|         |    102 // ----------------------------------------------------------------------------- | 
|         |    103 // CHttpCacheManager::NewL | 
|         |    104 // Two-phased constructor. | 
|         |    105 // ----------------------------------------------------------------------------- | 
|         |    106 // | 
|         |    107 EXPORT_C CHttpCacheManager* CHttpCacheManager::NewL() | 
|         |    108     { | 
|         |    109     CHttpCacheManager* self = new( ELeave ) CHttpCacheManager(); | 
|         |    110  | 
|         |    111     CleanupStack::PushL( self ); | 
|         |    112     self->ConstructL(); | 
|         |    113     CleanupStack::Pop(); | 
|         |    114  | 
|         |    115     return self; | 
|         |    116     } | 
|         |    117  | 
|         |    118 // Destructor | 
|         |    119 CHttpCacheManager::~CHttpCacheManager() | 
|         |    120     { | 
|         |    121     delete iOfflineNotifyHandler; | 
|         |    122     delete iOfflineRepository; | 
|         |    123     delete iCache; | 
|         |    124     delete iOperatorCache; | 
|         |    125     delete iOpDomain; | 
|         |    126     delete iphoneSpecificCache; | 
|         |    127     delete iVSSWhiteList; | 
|         |    128     } | 
|         |    129  | 
|         |    130 // ----------------------------------------------------------------------------- | 
|         |    131 // CHttpCacheManager::VSSRequestCheck | 
|         |    132 // | 
|         |    133 // ----------------------------------------------------------------------------- | 
|         |    134 // | 
|         |    135 TBool CHttpCacheManager::VSSRequestCheck( const RHTTPTransaction& aTrans, | 
|         |    136                                           const RHTTPHeaders& aHttpHeader, | 
|         |    137                                           const TDesC8& aUrl ) | 
|         |    138     { | 
|         |    139     TBool VSSTransaction ( EFalse ); | 
|         |    140     if( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) ) | 
|         |    141         { | 
|         |    142         RStringPool strP = aTrans.Session().StringPool(); | 
|         |    143  | 
|         |    144 #ifdef __CACHELOG__ | 
|         |    145         RHTTPHeaders headers ( aHttpHeader ); | 
|         |    146         HBufC8* responseHeaderStr8 = HttpCacheUtil::HeadersToBufferLC( headers, strP ); | 
|         |    147         HBufC* responseHeaderStr; | 
|         |    148         if( responseHeaderStr8 ) | 
|         |    149             { | 
|         |    150             responseHeaderStr = HBufC::NewL( responseHeaderStr8->Length() ); | 
|         |    151             responseHeaderStr->Des().Copy( responseHeaderStr8->Des() ); | 
|         |    152             CleanupStack::PopAndDestroy(); //  responseHeaderStr8; | 
|         |    153             TPtrC headerStr( responseHeaderStr->Des() ); | 
|         |    154             HttpCacheUtil::WriteLog( 0, _L("========== VSS Header Start =========\n") ); | 
|         |    155             HttpCacheUtil::WriteLog( 0, responseHeaderStr->Des() ); | 
|         |    156             HttpCacheUtil::WriteLog( 0, _L("========== VSS Header End =========\n") ); | 
|         |    157             delete responseHeaderStr; | 
|         |    158             } | 
|         |    159 #endif | 
|         |    160  | 
|         |    161         TPtrC8 nameStr ( KVSSHeaderFileldName() ); | 
|         |    162  | 
|         |    163         RStringF VSSnameStr = strP.OpenFStringL( nameStr ); | 
|         |    164         CleanupClosePushL<RStringF>( VSSnameStr); | 
|         |    165  | 
|         |    166         THTTPHdrVal tempVal; | 
|         |    167         if( aHttpHeader.GetField( VSSnameStr, 0, tempVal ) == KErrNone ) | 
|         |    168             { | 
|         |    169             TPtrC8 valueStr ( KVSSHeaderFileldValue() ); | 
|         |    170             RStringF VSSValueStr = strP.OpenFStringL( valueStr ); | 
|         |    171             CleanupClosePushL<RStringF>( VSSValueStr ); | 
|         |    172  | 
|         |    173             if( tempVal == VSSValueStr ) | 
|         |    174                 { | 
|         |    175                 VSSTransaction      = ETrue; | 
|         |    176                 } | 
|         |    177             CleanupStack::PopAndDestroy(); // VSSValueStr | 
|         |    178             } | 
|         |    179         CleanupStack::PopAndDestroy(); // VSSnameStr | 
|         |    180         } //end if( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) ) | 
|         |    181     return VSSTransaction; | 
|         |    182     } | 
|         |    183 // ----------------------------------------------------------------------------- | 
|         |    184 // CHttpCacheManager::RequestL | 
|         |    185 // | 
|         |    186 // ----------------------------------------------------------------------------- | 
|         |    187 // | 
|         |    188 EXPORT_C TInt CHttpCacheManager::RequestL( | 
|         |    189     RHTTPTransaction& aTrans, | 
|         |    190     TBrCtlDefs::TBrCtlCacheMode aCacheMode, | 
|         |    191     THttpCacheEntry& aCacheEntry ) | 
|         |    192     { | 
|         |    193     // | 
|         |    194     TInt status( KErrNotFound ); | 
|         |    195     if( iCacheEnabled || iVSSCacheEnabled ) | 
|         |    196         { | 
|         |    197         CHttpCacheHandler* cache = CacheHandler( aTrans.Request().URI().UriDes(), NULL ) ; | 
|         |    198         __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) ); | 
|         |    199         // adjust cache mode in case of offline operation | 
|         |    200         if( iOfflineMode ) | 
|         |    201             { | 
|         |    202             aCacheMode = TBrCtlDefs::ECacheModeOnlyCache; | 
|         |    203             } | 
|         |    204         // | 
|         |    205         if( cache ) | 
|         |    206             { | 
|         |    207             status = cache->RequestL( aTrans, aCacheMode, aCacheEntry ); | 
|         |    208             // save cache handler even if the entry is not in the cache | 
|         |    209             // so that when the response comes back, we do not need to | 
|         |    210             // check the url | 
|         |    211              if( status == KErrNotFound && iVSSCacheEnabled ) | 
|         |    212                 { | 
|         |    213                  status = iphoneSpecificCache->RequestL( aTrans, aCacheMode, aCacheEntry ); | 
|         |    214                  if( (status  == KErrNotReady) || (status == KErrNone ) ) | 
|         |    215                  { | 
|         |    216                  aCacheEntry.iCacheHandler = iphoneSpecificCache;  | 
|         |    217                  } | 
|         |    218                  else | 
|         |    219                  { | 
|         |    220                  // No entry found in any cache. Default to normal cache | 
|         |    221                  aCacheEntry.iCacheHandler = cache;    | 
|         |    222                  } | 
|         |    223                 }  | 
|         |    224             else | 
|         |    225             { | 
|         |    226             aCacheEntry.iCacheHandler = cache;   | 
|         |    227             }                 | 
|         |    228            } //end if( cache ) | 
|         |    229  | 
|         |    230         }//end  if( iCacheEnabled || iVSSCacheEnabled ) | 
|         |    231     return status; | 
|         |    232     } | 
|         |    233  | 
|         |    234 // ----------------------------------------------------------------------------- | 
|         |    235 // CHttpCacheManager::RequestHeadersL | 
|         |    236 // | 
|         |    237 // ----------------------------------------------------------------------------- | 
|         |    238 // | 
|         |    239 EXPORT_C TInt CHttpCacheManager::RequestHeadersL( | 
|         |    240     RHTTPTransaction& aTrans, | 
|         |    241     THttpCacheEntry& aCacheEntry ) | 
|         |    242     { | 
|         |    243     TInt status( KErrNotFound ); | 
|         |    244     if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) | 
|         |    245         { | 
|         |    246         status = aCacheEntry.iCacheHandler->RequestHeadersL( aTrans, aCacheEntry ); | 
|         |    247         } | 
|         |    248     return status; | 
|         |    249     } | 
|         |    250  | 
|         |    251 // ----------------------------------------------------------------------------- | 
|         |    252 // CHttpCacheManager::RequestNextChunkL | 
|         |    253 // | 
|         |    254 // ----------------------------------------------------------------------------- | 
|         |    255 // | 
|         |    256 EXPORT_C HBufC8* CHttpCacheManager::RequestNextChunkL( | 
|         |    257     RHTTPTransaction& aTrans, | 
|         |    258     TBool& aLastChunk, | 
|         |    259     THttpCacheEntry& aCacheEntry ) | 
|         |    260     { | 
|         |    261     HBufC8* bodyStr = NULL; | 
|         |    262  | 
|         |    263     if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) | 
|         |    264         { | 
|         |    265         bodyStr = aCacheEntry.iCacheHandler->RequestNextChunkL( aTrans, aLastChunk, aCacheEntry ); | 
|         |    266         } | 
|         |    267     return bodyStr; | 
|         |    268     } | 
|         |    269  | 
|         |    270 // ----------------------------------------------------------------------------- | 
|         |    271 // CHttpCacheManager::RequestClosed | 
|         |    272 // | 
|         |    273 // ----------------------------------------------------------------------------- | 
|         |    274 // | 
|         |    275 EXPORT_C void CHttpCacheManager::RequestClosed( | 
|         |    276     RHTTPTransaction* aTrans, | 
|         |    277     THttpCacheEntry& aCacheEntry ) | 
|         |    278     { | 
|         |    279     if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) | 
|         |    280         { | 
|         |    281         aCacheEntry.iCacheHandler->RequestClosed( aTrans, aCacheEntry ); | 
|         |    282         } | 
|         |    283     } | 
|         |    284  | 
|         |    285 // ----------------------------------------------------------------------------- | 
|         |    286 // CHttpCacheManager::ReceivedResponseHeadersL | 
|         |    287 // | 
|         |    288 // ----------------------------------------------------------------------------- | 
|         |    289 // | 
|         |    290 EXPORT_C void CHttpCacheManager::ReceivedResponseHeadersL( | 
|         |    291   RHTTPTransaction& aTrans, | 
|         |    292     THttpCacheEntry& aCacheEntry ) | 
|         |    293     { | 
|         |    294     if( iCacheEnabled || iVSSCacheEnabled ) | 
|         |    295         { | 
|         |    296         if( iVSSCacheEnabled && VSSRequestCheck( aTrans, aTrans.Response().GetHeaderCollection(), | 
|         |    297             aTrans.Request().URI().UriDes() ) ) | 
|         |    298             { | 
|         |    299             //Modify the cache handler if VSS specific | 
|         |    300             aCacheEntry.iCacheHandler = iphoneSpecificCache; | 
|         |    301             } | 
|         |    302         if( aCacheEntry.iCacheHandler ) | 
|         |    303             { | 
|         |    304             aCacheEntry.iCacheHandler->ReceivedResponseHeadersL( aTrans, aCacheEntry ); | 
|         |    305             } | 
|         |    306         } | 
|         |    307     } | 
|         |    308  | 
|         |    309 // ----------------------------------------------------------------------------- | 
|         |    310 // CHttpCacheManager::ReceivedResponseBodyDataL | 
|         |    311 // | 
|         |    312 // ----------------------------------------------------------------------------- | 
|         |    313 // | 
|         |    314 EXPORT_C void CHttpCacheManager::ReceivedResponseBodyDataL( | 
|         |    315   RHTTPTransaction& aTrans, | 
|         |    316     MHTTPDataSupplier& aBodyDataSupplier, | 
|         |    317     THttpCacheEntry& aCacheEntry ) | 
|         |    318     { | 
|         |    319     if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) | 
|         |    320         { | 
|         |    321         aCacheEntry.iCacheHandler->ReceivedResponseBodyDataL( aTrans, aBodyDataSupplier, aCacheEntry ); | 
|         |    322         } | 
|         |    323     } | 
|         |    324  | 
|         |    325 // ----------------------------------------------------------------------------- | 
|         |    326 // CHttpCacheManager::ResponseComplete | 
|         |    327 // | 
|         |    328 // ----------------------------------------------------------------------------- | 
|         |    329 // | 
|         |    330 EXPORT_C void CHttpCacheManager::ResponseComplete( | 
|         |    331     RHTTPTransaction& aTrans, | 
|         |    332     THttpCacheEntry& aCacheEntry ) | 
|         |    333     { | 
|         |    334     if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) | 
|         |    335         { | 
|         |    336         aCacheEntry.iCacheHandler->ResponseComplete( aTrans, aCacheEntry ); | 
|         |    337         } | 
|         |    338     } | 
|         |    339  | 
|         |    340 // ----------------------------------------------------------------------------- | 
|         |    341 // CHttpCacheManager::RemoveAllL | 
|         |    342 // Removes all files from HTTP cache. Also tries to remove orphaned files,  | 
|         |    343 // i.e files found on disk, but not registered in the cache's lookup table | 
|         |    344 // ----------------------------------------------------------------------------- | 
|         |    345 // | 
|         |    346 EXPORT_C TInt CHttpCacheManager::RemoveAllL() | 
|         |    347     { | 
|         |    348     TInt numOfBytes( 0 ); | 
|         |    349     // do not remove op cache | 
|         |    350     if( iCacheEnabled ) | 
|         |    351         { | 
|         |    352         numOfBytes = iCache->RemoveAllL(); | 
|         |    353         } | 
|         |    354          | 
|         |    355     //failure here is not mission critical | 
|         |    356     TRAPD( error, RemoveOrphanedFilesL() );  | 
|         |    357      | 
|         |    358     return numOfBytes; | 
|         |    359     } | 
|         |    360  | 
|         |    361  | 
|         |    362 // Hash function for Symbian file paths: discards case first | 
|         |    363 static TUint32 FilepathHash(const TDesC& aDes) | 
|         |    364 { | 
|         |    365     //since this function is intensively used by the HashMap,  | 
|         |    366     //keeping (slow) heap allocation out of it.  | 
|         |    367     TBuf<KMaxPath> normalized ( aDes );  | 
|         |    368       | 
|         |    369     normalized.LowerCase(); | 
|         |    370     return DefaultHash::Des16( normalized ); | 
|         |    371 } | 
|         |    372  | 
|         |    373 // Comparator for Symbian file paths: Use case-insensitive compare   | 
|         |    374 static TBool FilepathIdent(const TDesC& aL, const TDesC& aR) | 
|         |    375 { | 
|         |    376     return ( aL.CompareF(aR) == 0 );   | 
|         |    377 } | 
|         |    378  | 
|         |    379  | 
|         |    380 // ----------------------------------------------------------------------------- | 
|         |    381 // CHttpCacheManager::RemoveOrphanedFilesL  | 
|         |    382 // Removes header/body files that exist on the file-system, but are not known to the in-memory Cache lookup table(s) | 
|         |    383 // We do this because cache performance degrades substantially if there are too many files in a Symbian FAT32 directory.  | 
|         |    384 // Browser crash or out-of-battery situations may cause SaveLookuptable() to be not called, leading to such "orphaned files".  | 
|         |    385 // Due to high file-server interaction, don't call this method from performance critical code.  | 
|         |    386 // ----------------------------------------------------------------------------- | 
|         |    387 void CHttpCacheManager::RemoveOrphanedFilesL() | 
|         |    388     { | 
|         |    389  | 
|         |    390     //Map that contains pointers to fully-qualified file paths as Keys, and "to be deleted flag" as Value.  | 
|         |    391     RPtrHashMap<TDesC, TInt> onDiskFilesMap(&FilepathHash, &FilepathIdent); | 
|         |    392     CleanupClosePushL( onDiskFilesMap ); | 
|         |    393  | 
|         |    394     //Pointers to the following TInt are used as VALUES in the HashMap... | 
|         |    395     // so they must be in scope for the lifecycle of the HashMap. | 
|         |    396     const TInt needsDelete( 1 ); | 
|         |    397     const TInt noDelete( 0 ); | 
|         |    398  | 
|         |    399     //collects objects that need to be deleted later on  | 
|         |    400     RPointerArray<HBufC> cleanupList; | 
|         |    401     CleanupResetAndDestroyPushL( cleanupList ); | 
|         |    402  | 
|         |    403     RFs rfs = CCoeEnv::Static()->FsSession(); | 
|         |    404     CDirScan* scanner = CDirScan::NewLC( rfs ); | 
|         |    405  | 
|         |    406     //Configure CDirScan to tell you all contents of a particular directory hierarchy | 
|         |    407     scanner->SetScanDataL( iCacheFolder, KEntryAttNormal, ESortNone ); | 
|         |    408     CDir* matchingFiles( 0 ); | 
|         |    409  | 
|         |    410     //Step 1. Find out all files on disk: by walking the directory hierarchy, one directory at a time | 
|         |    411     for (;;) | 
|         |    412         { | 
|         |    413         //1a. Get list of files in current directory, NULL if no directory left in tree  | 
|         |    414         scanner->NextL( matchingFiles ); | 
|         |    415         if ( !matchingFiles ) | 
|         |    416             break; | 
|         |    417  | 
|         |    418         TPtrC dir( scanner->FullPath() );        | 
|         |    419          | 
|         |    420         //1b. Add any files found to the HashTable | 
|         |    421         const TInt nMatches = matchingFiles->Count(); | 
|         |    422         for ( TInt i = 0; i < nMatches; i++ ) | 
|         |    423             { | 
|         |    424             TEntry entry ( (*matchingFiles)[i] ) ;  | 
|         |    425             if (entry.iName.Right( KIndexFileExtension().Length() ). | 
|         |    426                     CompareF( KIndexFileExtension ) != 0) // ignore any .dat index files | 
|         |    427                 { | 
|         |    428                 HBufC* fullPath = HBufC::NewL( dir.Length() +  entry.iName.Length() ); | 
|         |    429                 cleanupList.Append( fullPath ); //keep object safe for later destruction | 
|         |    430                 fullPath->Des().Append( dir ); | 
|         |    431                 fullPath->Des().Append( entry.iName ); //a fully qualified file path | 
|         |    432                 onDiskFilesMap.Insert( fullPath, &needsDelete ); //add to the hash | 
|         |    433                 } | 
|         |    434             } | 
|         |    435              | 
|         |    436  | 
|         |    437         delete matchingFiles; | 
|         |    438         } // End of step 1: adding all known files on disk to Map | 
|         |    439  | 
|         |    440     CleanupStack::PopAndDestroy( 1, scanner ); | 
|         |    441  | 
|         |    442 #ifdef __CACHELOG__ | 
|         |    443     { | 
|         |    444     RDebug::Print(_L("-----------START PRINTING MAP OF SIZE %d---------"), onDiskFilesMap.Count()); | 
|         |    445     TPtrHashMapIter<TDesC, TInt> iter(onDiskFilesMap); | 
|         |    446     const TDesC* key; | 
|         |    447     while ((key = iter.NextKey()) != 0) | 
|         |    448         { | 
|         |    449         const TInt val = *(iter.CurrentValue()); | 
|         |    450         RDebug::Print(_L("MAP WALK: %S, with value = %d "), key, val); | 
|         |    451         } | 
|         |    452     RDebug::Print(_L("-----------DONE PRINTING MAP-------------")); | 
|         |    453     } | 
|         |    454 #endif | 
|         |    455      | 
|         |    456     //Step 2. Get list of known (non-orphaned) files in each Cache's in-memory lookup table. Flag them as DO NOT DELETE | 
|         |    457     RPointerArray<TDesC> knownFiles;  | 
|         |    458     CleanupClosePushL( knownFiles ); | 
|         |    459     //Ask CacheHandlers to add their KNOWN files to this array. No ownership transfer occurs.  | 
|         |    460     //Don't go ahead if any of the cache handlers choke to insure correct deletion of files. | 
|         |    461     if (iCache) | 
|         |    462         User::LeaveIfError( iCache->ListFiles( knownFiles ) );  | 
|         |    463     if (iOperatorCache) | 
|         |    464         User::LeaveIfError( iOperatorCache->ListFiles( knownFiles ) ); | 
|         |    465     if (iphoneSpecificCache) | 
|         |    466         User::LeaveIfError( iphoneSpecificCache->ListFiles( knownFiles ) );  | 
|         |    467  | 
|         |    468     //2a. HashTable lookup, and modification of flag | 
|         |    469     for (TInt i = 0; i < knownFiles.Count(); i++) | 
|         |    470         { | 
|         |    471         //lookup filename | 
|         |    472         TInt* ptr = onDiskFilesMap.Find( *(knownFiles[i]) ); | 
|         |    473         if (ptr) | 
|         |    474             { | 
|         |    475             // Reinsert into Map, this time with NO DELETE | 
|         |    476             onDiskFilesMap.Insert( knownFiles[i], &noDelete );  | 
|         |    477              | 
|         |    478             // Add the header file to HashMap | 
|         |    479             HBufC* headerFile = HBufC::NewL( KHttpCacheHeaderExt().Length() +  (*(knownFiles[i])).Length() );  | 
|         |    480             cleanupList.Append( headerFile ); //keep for later destruction | 
|         |    481             TPtr ptr( headerFile->Des() );  | 
|         |    482             HttpCacheUtil::GetHeaderFileName( *(knownFiles[i]), ptr ); | 
|         |    483             onDiskFilesMap.Insert( headerFile, &noDelete ); // register Header files as NO DELETE | 
|         |    484             } | 
|         |    485         } | 
|         |    486  | 
|         |    487     knownFiles.Close();  | 
|         |    488     CleanupStack::Pop( 1, &knownFiles ); | 
|         |    489  | 
|         |    490     //Step 3. Delete all files on disk that don't belong to any of the Cache Handlers. | 
|         |    491     CFileMan* fileMan = CFileMan::NewL( rfs ); | 
|         |    492     TPtrHashMapIter<TDesC, TInt> iter( onDiskFilesMap ); | 
|         |    493     const TDesC* key; | 
|         |    494     while ((key = iter.NextKey()) != 0) | 
|         |    495         { | 
|         |    496         const TInt value ( *(iter.CurrentValue()) ); | 
|         |    497         if ( value == 1 ) { // file needs deletion | 
|         |    498             fileMan->Delete( *key ); | 
|         |    499         } | 
|         |    500         } | 
|         |    501     delete fileMan; | 
|         |    502  | 
|         |    503     CleanupStack::Pop(1, &cleanupList);  | 
|         |    504     cleanupList.ResetAndDestroy(); //should delete all HBufC objects | 
|         |    505      | 
|         |    506     CleanupStack::Pop(1, &onDiskFilesMap); | 
|         |    507     onDiskFilesMap.Close(); // doesn't own any K,V object | 
|         |    508      | 
|         |    509     } | 
|         |    510  | 
|         |    511 // ----------------------------------------------------------------------------- | 
|         |    512 // CHttpCacheManager::RemoveL | 
|         |    513 // | 
|         |    514 // ----------------------------------------------------------------------------- | 
|         |    515 // | 
|         |    516 EXPORT_C TInt CHttpCacheManager::RemoveL( | 
|         |    517     const TDesC8& aUrl ) | 
|         |    518     { | 
|         |    519     TInt status( KErrNotFound ); | 
|         |    520     if( iCacheEnabled ) | 
|         |    521         { | 
|         |    522         // do not remove op cache | 
|         |    523         status = iCache->RemoveL( aUrl ); | 
|         |    524         } | 
|         |    525     return status; | 
|         |    526     } | 
|         |    527  | 
|         |    528 // ----------------------------------------------------------------------------- | 
|         |    529 // CHttpCacheManager::Find | 
|         |    530 // | 
|         |    531 // ----------------------------------------------------------------------------- | 
|         |    532 // | 
|         |    533 EXPORT_C TBool CHttpCacheManager::Find( | 
|         |    534     const TDesC8& aUrl ) | 
|         |    535     { | 
|         |    536     TBool found( EFalse ); | 
|         |    537     // | 
|         |    538     if( iCacheEnabled || iVSSCacheEnabled ) | 
|         |    539         { | 
|         |    540         CHttpCacheHandler* cache = CacheHandler( aUrl, NULL ); | 
|         |    541  | 
|         |    542         __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) ); | 
|         |    543         // | 
|         |    544         if( cache ) | 
|         |    545             { | 
|         |    546             found = cache->Find( aUrl ); | 
|         |    547             } | 
|         |    548  | 
|         |    549         if( !found && iVSSCacheEnabled ) | 
|         |    550             { | 
|         |    551             found = iphoneSpecificCache->Find( aUrl ); | 
|         |    552             } | 
|         |    553         } | 
|         |    554     return found; | 
|         |    555     } | 
|         |    556  | 
|         |    557 // ----------------------------------------------------------------------------- | 
|         |    558 // CHttpCacheManager::VSSHeaderCheck | 
|         |    559 // | 
|         |    560 // ----------------------------------------------------------------------------- | 
|         |    561 // | 
|         |    562 TBool CHttpCacheManager::VSSHeaderCheck( TDes8*  aHttpHeaderString ) const | 
|         |    563     { | 
|         |    564     TBool found ( EFalse ); | 
|         |    565     if( aHttpHeaderString->Size() > 0 ) | 
|         |    566         { | 
|         |    567         TPtrC8 nameStr8( KVSSHeaderFileldName() ); | 
|         |    568  | 
|         |    569         TInt VSSnameLocation = aHttpHeaderString->FindC( nameStr8 ) ; | 
|         |    570  | 
|         |    571         if ( VSSnameLocation != KErrNotFound ) | 
|         |    572             { | 
|         |    573             TPtrC8 valueStr8( KVSSHeaderFileldValue() ); | 
|         |    574             TInt VSSvalueLocation = aHttpHeaderString->FindC( KVSSHeaderFileldValue() ); | 
|         |    575  | 
|         |    576             if ( (VSSvalueLocation != KErrNotFound ) && ( VSSnameLocation < VSSvalueLocation ) ) | 
|         |    577                 { | 
|         |    578                 found = ETrue; | 
|         |    579                 } | 
|         |    580             } //end if ( VSSnameLocation != KErrNotFound ) | 
|         |    581         } //end  if( aHttpHeaderString.Size() > 0 ) | 
|         |    582  | 
|         |    583     return found; | 
|         |    584     } | 
|         |    585  | 
|         |    586 // ----------------------------------------------------------------------------- | 
|         |    587 // CHttpCacheManager::SaveL | 
|         |    588 // | 
|         |    589 // ----------------------------------------------------------------------------- | 
|         |    590 // | 
|         |    591 EXPORT_C TBool CHttpCacheManager::SaveL( | 
|         |    592     const TDesC8& aUrl, | 
|         |    593     const TDesC8& aHeader, | 
|         |    594     const TDesC8& aContent, | 
|         |    595     const TDesC8&  aHttpHeaderString) | 
|         |    596     { | 
|         |    597     TBool saved( EFalse ); | 
|         |    598     // | 
|         |    599     if( iCacheEnabled || iVSSCacheEnabled ) | 
|         |    600         { | 
|         |    601         HBufC8* headerStr = HBufC8::NewL( aHttpHeaderString.Length() ); | 
|         |    602         headerStr->Des().Copy( aHttpHeaderString ); | 
|         |    603         TPtr8 headerStrPtr8 ( headerStr->Des() ); //Any Type of TPtrc8 | 
|         |    604         CHttpCacheHandler* cache = CacheHandler( aUrl, &headerStrPtr8 ); | 
|         |    605         delete headerStr; | 
|         |    606         __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) ); | 
|         |    607         // | 
|         |    608         if( cache ) | 
|         |    609             { | 
|         |    610             saved = cache->SaveL( aUrl, aHeader, aContent ); | 
|         |    611             } | 
|         |    612         } | 
|         |    613     return saved; | 
|         |    614     } | 
|         |    615  | 
|         |    616 // ----------------------------------------------------------------------------- | 
|         |    617 // CHttpCacheManager::AddHeaderL | 
|         |    618 // Not supported for Vodafone specific storage. | 
|         |    619 // ----------------------------------------------------------------------------- | 
|         |    620 // | 
|         |    621 EXPORT_C TInt CHttpCacheManager::AddHeaderL( | 
|         |    622     const TDesC8& aUrl, | 
|         |    623     const TDesC8& aName, | 
|         |    624     const TDesC8& aValue ) | 
|         |    625     { | 
|         |    626     TBool status( KErrNotFound ); | 
|         |    627     // | 
|         |    628     if( iCacheEnabled || iVSSCacheEnabled ) | 
|         |    629         { | 
|         |    630         CHttpCacheHandler* cache = CacheHandler( aUrl, NULL ); | 
|         |    631         __ASSERT_DEBUG( cache, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) ); | 
|         |    632         // | 
|         |    633         if( cache ) | 
|         |    634             { | 
|         |    635             status = cache->AddHeaderL( aUrl, aName, aValue ); | 
|         |    636             } | 
|         |    637         } | 
|         |    638     return status; | 
|         |    639     } | 
|         |    640  | 
|         |    641 // ----------------------------------------------------------------------------- | 
|         |    642 // CHttpCacheManager::CreateCacheHandlersL | 
|         |    643 // | 
|         |    644 // ----------------------------------------------------------------------------- | 
|         |    645 // | 
|         |    646 void CHttpCacheManager::HandleNotifyString( | 
|         |    647     const TUint32 aKeyId, | 
|         |    648     const TDesC& aValue ) | 
|         |    649     { | 
|         |    650     // check offline mode | 
|         |    651     if( aKeyId == KCoreAppUIsNetworkConnectionAllowed ) | 
|         |    652         { | 
|         |    653         iOfflineMode = ( aValue == _L("1") ? EFalse : ETrue ); | 
|         |    654         } | 
|         |    655     } | 
|         |    656  | 
|         |    657 // ----------------------------------------------------------------------------- | 
|         |    658 // CHttpCacheManager::CreateCacheHandlersL | 
|         |    659 // | 
|         |    660 // ----------------------------------------------------------------------------- | 
|         |    661 // | 
|         |    662 void CHttpCacheManager::CreateCacheHandlersL() | 
|         |    663     { | 
|         |    664     // read cache settings | 
|         |    665     CRepository* repository = CRepository::NewLC( KCRUidCacheManager ); | 
|         |    666     CRepository* repositoryDiskLevel = CRepository::NewLC( KCRUidDiskLevel ); | 
|         |    667     TInt err; | 
|         |    668  | 
|         |    669     // cache on/off | 
|         |    670     TInt cacheEnabled( 0 ); | 
|         |    671     err = repository->Get( KCacheManagerHttpCacheEnabled, cacheEnabled ); | 
|         |    672  | 
|         |    673     iCacheEnabled = cacheEnabled; | 
|         |    674  | 
|         |    675         // cache size | 
|         |    676         TInt cacheSize( KDefaultCacheSize ); | 
|         |    677         repository->Get( KCacheManagerHttpCacheSize, cacheSize ); | 
|         |    678  | 
|         |    679          repository->Get( KCacheManagerHttpCacheFolder, iCacheFolder ); | 
|         |    680         // fix folder by appending trailing \\ to the end -symbian thing | 
|         |    681         // unless it is already there | 
|         |    682         if( iCacheFolder.LocateReverse( '\\' ) != iCacheFolder.Length() - 1  ) | 
|         |    683             { | 
|         |    684             iCacheFolder.Append( _L("\\") ); | 
|         |    685             } | 
|         |    686          | 
|         |    687 	// get drive letter for sysutil | 
|         |    688 	TParsePtrC pathParser( iCacheFolder ); | 
|         |    689 	TDriveUnit drive = pathParser.Drive(); | 
|         |    690 	// get critical level | 
|         |    691 	// RAM drive can have different critical level | 
|         |    692 	TVolumeInfo vinfo; | 
|         |    693 	User::LeaveIfError( CCoeEnv::Static()->FsSession().Volume( vinfo, drive ) ); | 
|         |    694 	// | 
|         |    695 	TInt criticalLevel; | 
|         |    696 	User::LeaveIfError( repositoryDiskLevel->Get( ( vinfo.iDrive.iType == EMediaRam ? KRamDiskCriticalLevel : KDiskCriticalThreshold ), | 
|         |    697 		criticalLevel ) ); | 
|         |    698  | 
|         |    699     if( (err == KErrNone) && iCacheEnabled ) | 
|         |    700         { | 
|         |    701         // create cache handler | 
|         |    702         iCache = CHttpCacheHandler::NewL( cacheSize, iCacheFolder, KDefaultIndexFile(), criticalLevel ); | 
|         |    703  | 
|         |    704         // create operator cache. same settings | 
|         |    705         if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) | 
|         |    706             { | 
|         |    707             TBuf<512> url; | 
|         |    708             // if domain is missing, then no need to read further | 
|         |    709             if( repository->Get( KOperatorDomainUrl, url ) == KErrNone ) | 
|         |    710                 { | 
|         |    711  | 
|         |    712                 HBufC8* opDomain8 = HBufC8::NewL( url.Length() ); | 
|         |    713             CleanupStack::PushL(opDomain8); | 
|         |    714             opDomain8->Des().Append( url ); | 
|         |    715  | 
|         |    716             TInt slashPos = opDomain8->LocateReverse('/'); | 
|         |    717             if(slashPos == -1) | 
|         |    718             { | 
|         |    719                 slashPos = 0; | 
|         |    720             } | 
|         |    721             TPtrC8 temp = opDomain8->Left(slashPos); | 
|         |    722             iOpDomain = temp.AllocL(); | 
|         |    723             CleanupStack::PopAndDestroy(opDomain8); | 
|         |    724  | 
|         |    725                 // op cache size | 
|         |    726                 TInt opCacheSize( KDefaultCacheSize ); | 
|         |    727                 repository->Get( KOperatorCacheSize, opCacheSize ); | 
|         |    728  | 
|         |    729                 // op cache folder | 
|         |    730                 TFileName opCacheFolder( KDefaultCacheDir ); | 
|         |    731                 repository->Get( KOperatorCacheFolder, opCacheFolder ); | 
|         |    732  | 
|         |    733                 if( opCacheFolder.LocateReverse( '\\' ) != opCacheFolder.Length() - 1  ) | 
|         |    734                     { | 
|         |    735                     opCacheFolder.Append( _L("\\") ); | 
|         |    736                     } | 
|         |    737  | 
|         |    738                 // create op cache | 
|         |    739                 iOperatorCache = CHttpCacheHandler::NewL( opCacheSize, opCacheFolder, KDefaultOpIndexFile(), criticalLevel ); | 
|         |    740         } | 
|         |    741             } //end if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) | 
|         |    742         } //end if( iCacheEnabled ) | 
|         |    743  | 
|         |    744     TInt VSScacheEnabled( 0 ); | 
|         |    745     err = repository->Get( KPhoneSpecificCacheEnabled, VSScacheEnabled ); | 
|         |    746  | 
|         |    747     iVSSCacheEnabled = VSScacheEnabled; | 
|         |    748   | 
|         |    749     if( (err == KErrNone) && iVSSCacheEnabled ) | 
|         |    750         { | 
|         |    751         // cache size | 
|         |    752         TInt VSScacheSize( KDefaultCacheSize ); | 
|         |    753         repository->Get( KPhoneSpecificCacheSize, VSScacheSize ); | 
|         |    754  | 
|         |    755         // cache folder | 
|         |    756         TFileName VSScacheFolder( KDefaultCacheDir ); | 
|         |    757         // ignore cache folder. use c:\ to save memory. (same for operator cache. see below) | 
|         |    758         repository->Get( KPhoneSpecificCacheFolder, VSScacheFolder ); | 
|         |    759         // fix folder by appending trailing \\ to the end -symbian thing | 
|         |    760         // unless it is already there | 
|         |    761         if( VSScacheFolder.LocateReverse( '\\' ) != VSScacheFolder.Length() - 1  ) | 
|         |    762             { | 
|         |    763             VSScacheFolder.Append( _L("\\") ); | 
|         |    764             } | 
|         |    765  | 
|         |    766         //Get the white list | 
|         |    767         TBuf<2048> whiteList; | 
|         |    768  | 
|         |    769         if( repository->Get( KPhoneSpecificCacheDomainUrl, whiteList ) == KErrNone ) | 
|         |    770             { | 
|         |    771             iVSSWhiteList = HBufC8::NewL( whiteList.Length() ); | 
|         |    772             iVSSWhiteList->Des().Append( whiteList ); | 
|         |    773             } | 
|         |    774         else | 
|         |    775             { | 
|         |    776             iVSSWhiteList = NULL; | 
|         |    777             } | 
|         |    778  | 
|         |    779         // create cache handler | 
|         |    780         iphoneSpecificCache = CHttpCacheHandler::NewL( VSScacheSize, VSScacheFolder, KDefaultVSSIndexFile(), criticalLevel ); | 
|         |    781         } | 
|         |    782     CleanupStack::PopAndDestroy(2); // repository, , repositoryDiskLevel | 
|         |    783     } | 
|         |    784  | 
|         |    785 // ----------------------------------------------------------------------------- | 
|         |    786 // CHttpCacheManager::CacheHandler | 
|         |    787 // | 
|         |    788 // ----------------------------------------------------------------------------- | 
|         |    789 // | 
|         |    790 CHttpCacheHandler* CHttpCacheManager::CacheHandler( | 
|         |    791     const TDesC8& aUrl, | 
|         |    792     TDes8* aHttpHeaderString ) const | 
|         |    793     { | 
|         |    794     CHttpCacheHandler* cache; | 
|         |    795     if( iVSSCacheEnabled && aHttpHeaderString && VSSHeaderCheck( aHttpHeaderString ) ) | 
|         |    796         { | 
|         |    797         cache = iphoneSpecificCache; | 
|         |    798         } | 
|         |    799     else | 
|         |    800         { | 
|         |    801         cache = ( ( iOpDomain && HttpCacheUtil::OperatorCacheContent( iOpDomain->Des(), aUrl ) ) ? iOperatorCache : iCache ); | 
|         |    802         } | 
|         |    803     return cache; | 
|         |    804     } | 
|         |    805 //  End of File | 
|         |    806  |