webengine/osswebengine/cache/src/HttpCacheHandler.cpp
changeset 1 7c90e6132015
parent 0 dd21522fd290
child 5 10e98eab6f85
--- a/webengine/osswebengine/cache/src/HttpCacheHandler.cpp	Mon Mar 30 12:54:55 2009 +0300
+++ b/webengine/osswebengine/cache/src/HttpCacheHandler.cpp	Fri May 08 08:25:06 2009 +0300
@@ -146,20 +146,20 @@
     return self;
     }
 
+// -----------------------------------------------------------------------------
 // Destructor
+// -----------------------------------------------------------------------------
+//
 CHttpCacheHandler::~CHttpCacheHandler()
     {
-   
-        TRAP_IGNORE( SaveLookupTableL() );
-   
+    TRAP_IGNORE( SaveLookupTableL() );
     //
     delete iHttpCacheObserver;
     //
-    if (iEvictionHandler)
+    if ( iEvictionHandler )
         {
         iEvictionHandler->RemoveAll();
         }
-
     //
     delete iLookupTable;
     //
@@ -184,8 +184,10 @@
     TBrCtlDefs::TBrCtlCacheMode aCacheMode,
     THttpCacheEntry& aCacheEntry )
     {
+#ifdef __CACHELOG__
     HttpCacheUtil::WriteUrlToLog( 0, _L( "request item" ), aTrans.Request().URI().UriDes() );
-    //
+#endif
+
     TInt status( KErrNotFound );
     CHttpCacheEntry* entry = NULL;
     // 0. check if we need to check cache at all (protected vs no cache mode)
@@ -193,9 +195,8 @@
     // 2. check if it is complete
     // 3. see if it is useable
 
-    // use protected item on reload???
-    // currently not
-    // and do not use cache for post
+    // use protected item on reload
+    // currently not and do not use cache for post
     if( aCacheMode != TBrCtlDefs::ECacheModeNoCache &&
         HttpCacheUtil::MethodFromStr( aTrans.Request().Method(), aTrans.Session().StringPool() ) != EMethodPost )
         {
@@ -242,7 +243,7 @@
             else
                 {
                 // cleanup on the corrupt entry
-                HandleCorruptEntry( *entry );
+                DeleteCacheEntry( *entry );
                 entry = NULL;
                 // item is not in cache
                 status = KErrNotFound;
@@ -346,39 +347,41 @@
     RHTTPTransaction* aTrans,
     THttpCacheEntry& aCacheEntry )
     {
-    if (aTrans)
-        HttpCacheUtil::WriteUrlToLog( 0, _L( "Request is closed" ), aTrans->Request().URI().UriDes() );
-    // fine
-    // make sure transaction is moved to the complete list
+#ifdef __CACHELOG__
+    if ( aTrans )
+        HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheHandler::RequestClosed on url =" ), aTrans->Request().URI().UriDes() );
+#endif
+
+    // Fine, make sure transaction is moved to the complete list
     CHttpCacheEntry* entry = aCacheEntry.iCacheEntry;
 
-    if( entry )
+    if ( entry )
         {
         // normal close on a request - when the content is loaded from the cache
-        if( entry->State() == CHttpCacheEntry::ECacheRequesting )
+        if ( entry->State() == CHttpCacheEntry::ECacheRequesting )
             {
             entry->SetState( CHttpCacheEntry::ECacheComplete );
             iStreamHandler->Detach( *entry );
             }
         // transaction is closed without being completed
-        else if( entry->State() == CHttpCacheEntry::ECacheResponding ||
-            entry->State() == CHttpCacheEntry::ECacheDestroyed )
+        else if ( entry->State() == CHttpCacheEntry::ECacheResponding ||
+                  entry->State() == CHttpCacheEntry::ECacheDestroyed )
             {
             // remove uncompleted/destroyed entry
             iStreamHandler->Detach( *entry );
-            HandleCorruptEntry( *entry );
+            DeleteCacheEntry( *entry );
             entry = NULL;
             aCacheEntry.iCacheEntry = NULL;
 #ifdef __CACHELOG__
-            HttpCacheUtil::WriteLog( 0, _L( "uncompleted entry" ) );
+            HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::RequestClosed - uncompleted entry" ) );
 #endif
             }
-        else if( entry->State() == CHttpCacheEntry::ECacheComplete )
+        else if ( entry->State() == CHttpCacheEntry::ECacheComplete )
             {
-            // normal close on the request - when the contet is saved to the cache
+            // normal close on the request - when the content is saved to the cache
             // ResponseComplete has already been called
             // check if the stream is released
-            __ASSERT_DEBUG( !iStreamHandler->Find( *entry ) , PanicCacheHandler( KErrCorrupt ) );
+            // __ASSERT_DEBUG( !entry->CacheFilesOpened() ) , PanicCacheHandler( KErrCorrupt ) );
             }
         else
             {
@@ -387,7 +390,6 @@
         }
     }
 
-
 // -----------------------------------------------------------------------------
 // CHttpCacheHandler::AdjustResponseTime
 //
@@ -453,9 +455,10 @@
     THttpCacheEntry& aCacheEntry )
     {
 #ifdef __CACHELOG__
-    HttpCacheUtil::WriteUrlToLog( 0, _L( "received http headers" ), aTrans.Request().URI().UriDes() );
+    HttpCacheUtil::WriteLog( 0, _L("---> CHttpCacheHandler::ReceivedResponseHeadersL"), 0);
+    HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheHandler::ReceivedResponseHeadersL - received http headers" ), aTrans.Request().URI().UriDes() );
 #endif
-    //
+
     TBool protectedEntry( EFalse );
     // check if the item is cacheable
     // no item should be bigger than the 1/3 of the cache size
@@ -466,16 +469,25 @@
         if( entry )
             {
 #ifdef __CACHELOG__
-            HttpCacheUtil::WriteUrlToLog( 0, _L( "item is already in the cache" ), entry->Url() );
-#endif            
-            //
+        	HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+                                       _L("CHttpCacheHandler::ReceivedResponseHeadersL"),
+                                       entry->Filename(),
+                                       entry->Url(),
+                                       entry->BodySize(), 
+                                       ELogEntrySize );
+#endif
+
             if( entry->State() != CHttpCacheEntry::ECacheComplete )
                 {
-                // multiple incoming entries? doh.
+                // multiple incoming entries doh.
 #ifdef __CACHELOG__
-                HttpCacheUtil::WriteLog( 0, _L( "MULTIPLE REQUEST!!!!!!!!!!!!!!!!!!!!!!!!!" ) );
-#endif                
-                // __ASSERT_DEBUG( EFalse, PanicCacheHandler( KErrCorrupt ) );
+        		HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+                                       _L("CHttpCacheHandler::ReceivedResponseHeadersL - ERROR MULTIPLE requests"),
+                                       entry->Filename(),
+                                       entry->Url(),
+                                       entry->BodySize(), 
+                                       ELogEntrySize );
+#endif
                 // ignore this one and the first will proceed.
                 entry = NULL;
                 }
@@ -483,7 +495,7 @@
         else
             {
 #ifdef __CACHELOG__
-            HttpCacheUtil::WriteLog( 0, _L( "create new cache item" ) );
+            HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::ReceivedResponseHeadersL - create new cache item" ) );
 #endif
             //Check adjustment of response time is required or not.
             AdjustResponseTime( aTrans );
@@ -495,9 +507,13 @@
                 if( protectedEntry )
                     {
 #ifdef __CACHELOG__
-                    HttpCacheUtil::WriteLog( 0, _L( "this item is protected" ) );
+        			HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+                                       _L("CHttpCacheHandler::ReceivedResponseHeadersL - this is protected item"),
+                                       entry->Filename(),
+                                       entry->Url(),
+                                       entry->BodySize(), 
+                                       ELogEntrySize );
 #endif
-                    //
                     entry->SetProtected();
                     RHTTPHeaders responseHeaders = aTrans.Response().GetHeaderCollection();
                     RStringPool strP = aTrans.Session().StringPool();
@@ -524,10 +540,10 @@
                 // 3. update the headers anyway in case of notmodified (304)
                 // 4. remove the old body in case of bodyupdate
                 TInt httpStatus( aTrans.Response().StatusCode() );
+
 #ifdef __CACHELOG__
-                HttpCacheUtil::WriteLog( 0, _L( "status code: " ), httpStatus );
+                HttpCacheUtil::WriteLog( 0,  _L("CHttpCacheHandler::ReceivedResponseHeadersL - status code ="), httpStatus );
 #endif
-                //
                 TBool ok( EFalse );
                 if( httpStatus == HTTPStatus::EOk )
                     {
@@ -537,7 +553,7 @@
                     {
                     ok = HandleResponseNotModifiedL( *entry, aTrans );
                     }
-                //
+
                 // entry could be corrupted at this point
                 if( ok )
                     {
@@ -549,13 +565,13 @@
                 else
                     {
                     iStreamHandler->Detach( *entry );
-                    HandleCorruptEntry( *entry );
+                    DeleteCacheEntry( *entry );
                     entry = NULL;
                     }
                 }
             else
                 {
-                HandleCorruptEntry( *entry );
+                DeleteCacheEntry( *entry );
                 entry = NULL;
                 }
             }
@@ -572,24 +588,36 @@
     MHTTPDataSupplier& aBodyDataSupplier,
     THttpCacheEntry& aCacheEntry )
     {
-    HttpCacheUtil::WriteUrlToLog( 0, _L( "received body" ), aTrans.Request().URI().UriDes() );
+#ifdef __CACHELOG__
+    HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheHandler::ReceivedResponseBodyDataL - received body from url =" ), aTrans.Request().URI().UriDes() );
+#endif
+
     // 1. check if we are caching this resource
     // 2. update the body data
     CHttpCacheEntry* entry = aCacheEntry.iCacheEntry;
 
-    if( entry && entry->State() == CHttpCacheEntry::ECacheResponding )
+    if ( entry && entry->State() == CHttpCacheEntry::ECacheResponding )
         {
+#ifdef __CACHELOG__
+        HttpCacheUtil::WriteLog( 0, _L("---> CHttpCacheHandler::ReceivedResponseBodyDataL"), entry->BodySize() );
+#endif
         HBufC8* bodyStr = HttpCacheUtil::BodyToBufferL( aBodyDataSupplier );
-        if( bodyStr )
+        if ( bodyStr )
             {
+            // Do we have old body data to remove first
+            if ( entry->BodyFileDeleteNeeded() ) {
+                iStreamHandler->RemoveBodyData( *entry );
+                entry->SetBodyFileDeleteNeeded( EFalse );
+            	}
+            
             // erase entry if we are unable to save it (low disk space)
             if( !SaveBuffer( *entry, bodyStr->Des(), ETrue ) )
                 {
                 // detach it from the stream and erase it
                 iStreamHandler->Detach( *entry );
-                HandleCorruptEntry( *entry );
+                DeleteCacheEntry( *entry );
 #ifdef __CACHELOG__                
-                HttpCacheUtil::WriteLog( 0, _L( "body cannot be saved" ) );
+                HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::ReceivedResponseBodyDataL - body cannot be saved" ) );
 #endif                
                 entry = NULL;
                 // remove entry
@@ -598,7 +626,7 @@
 #ifdef __CACHELOG__
             else
                 {
-                HttpCacheUtil::WriteLog( 0, _L( "body is saved" ) );
+                HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::ReceivedResponseBodyDataL - body is saved" ) );
                 }
 #endif // __CACHELOG__
             //
@@ -621,32 +649,48 @@
     // 2. mark the entry as complete
     CHttpCacheEntry* entry = aCacheEntry.iCacheEntry;
 
-    if( entry )
+    if ( entry )
         {
-        if( entry->State() == CHttpCacheEntry::ECacheResponding )
+#ifdef __CACHELOG__
+        HttpCacheUtil::WriteLog( 0, _L("---> CHttpCacheHandler::ResponseComplete"), entry->BodySize() );
+        HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+                                           _L("CHttpCacheHandler::ResponseComplete"),
+                                           entry->Filename(),
+                                           entry->Url(),
+                                           entry->BodySize(),
+                                           ELogEntrySize );
+#endif
+
+        if ( entry->State() == CHttpCacheEntry::ECacheResponding )
             {
-            // flush the entry
-            if( !iStreamHandler->Flush( *entry ) )
+            // Flush the entry
+            if ( !iStreamHandler->Flush( *entry ) )
                 {
+                // We failed saving (flush), cleanup
                 iStreamHandler->Detach( *entry );
-                HandleCorruptEntry( *entry );
-#ifdef __CACHELOG__
-                HttpCacheUtil::WriteLog( 0, _L( "body cannot be saved" ) );
-#endif
+
+                // Deleting the entry frees cache buffer
+                DeleteCacheEntry( *entry );
                 entry = NULL;
-                // remove entry
                 aCacheEntry.iCacheEntry = NULL;
                 }
             else
                 {
+                // We successfully saved (flush) body
                 entry->SetState( CHttpCacheEntry::ECacheComplete );
                 iStreamHandler->Detach( *entry );
+
+                // Clear the flushed cache buffer, we were using for incoming body
+                entry->SetCacheBufferL( KBufferSizeZero );
                 }
             }
         else if( entry->State() == CHttpCacheEntry::ECacheDestroyed )
             {
             iStreamHandler->Detach( *entry );
-            HandleCorruptEntry( *entry, EFalse );
+
+            // Deleting the entry frees cache buffer
+            DeleteCacheEntry( *entry, EFalse );
+            entry = NULL;
             aCacheEntry.iCacheEntry = NULL;
             }
         }
@@ -685,23 +729,22 @@
 //
 // -----------------------------------------------------------------------------
 //
-TInt CHttpCacheHandler::RemoveL(
-    const TDesC8& aUrl )
+TInt CHttpCacheHandler::RemoveL( const TDesC8& aUrl )
     {
     TInt status( KErrNotFound );
     HttpCacheUtil::WriteUrlToLog( 0, _L( "remove item:" ), aUrl );
     CHttpCacheEntry* entry = iLookupTable->Find( aUrl );
 
-    if( entry )
+    if ( entry )
         {
-        if( entry->State() == CHttpCacheEntry::ECacheComplete )
+        if ( entry->State() == CHttpCacheEntry::ECacheComplete )
             {
-            // delete
+            // Delete from lookup table
             status = iLookupTable->Remove( aUrl );
             }
         else
             {
-            // mark it as deleted and erase it when the
+            // Mark it as deleted and erase it when the
             // trans is complete
             entry->SetState( CHttpCacheEntry::ECacheDestroyed );
             status = KErrNone;
@@ -715,8 +758,7 @@
 //
 // -----------------------------------------------------------------------------
 //
-TBool CHttpCacheHandler::Find(
-    const TDesC8& aUrl )
+TBool CHttpCacheHandler::Find( const TDesC8& aUrl )
     {
     // find
     CHttpCacheEntry* entry = iLookupTable->Find( aUrl );
@@ -758,7 +800,7 @@
         // cleanup
         if( !saved && entry )
             {
-            HandleCorruptEntry( *entry );
+            DeleteCacheEntry( *entry );
             }
         }
     return saved;
@@ -806,7 +848,7 @@
                         {
                         // sorry, we made this entry corrupt. remove it
                         iStreamHandler->Detach( *entry );
-                        HandleCorruptEntry( *entry );
+                        DeleteCacheEntry( *entry );
                         entry = NULL;
                         }
                     }
@@ -886,7 +928,6 @@
                         HttpCacheUtil::WriteLog( 0, _L( "cache item is not fresh. needs revalidation" ) );
 #endif
                         // MKLE-7PRD27: Avoid removing cache entry here 
-                        
                         mustRevalidate = ETrue;
                         // add headers like EIfModifiedSince, EETag, EIfNoneMatch
                         HttpCacheUtil::AddValidationHeaders( responseHeaders, requestHeaders, strP );
@@ -915,7 +956,7 @@
         }
     else
         {
-        HandleCorruptEntry( aCacheEntry );
+        DeleteCacheEntry( aCacheEntry );
         // needs validation
         mustRevalidate = ETrue;
         }
@@ -927,8 +968,7 @@
 //
 // -----------------------------------------------------------------------------
 //
-TBool CHttpCacheHandler::CacheNeedsSpaceL(
-    TInt aSize )
+TBool CHttpCacheHandler::CacheNeedsSpaceL( TInt aSize )
     {
     TBool ok( ETrue );
 #ifdef __CACHELOG__
@@ -938,27 +978,30 @@
 #endif // __CACHELOG__
 
     // check if we need extra space
-    if( iStreamHandler->SavedContentSize() + aSize > iSize )
+    if ( iStreamHandler->SavedContentSize() + aSize > iSize )
         {
+
 #ifdef __CACHELOG__
         // items in the cache
         TInt size( 0 );
         HttpCacheUtil::WriteLog( 0, _L( "cached items" ) );
+
         const CArrayPtrFlat<CHttpCacheEntry>& entries = iLookupTable->Entries();
         for( TInt i = 0; i < entries.Count(); i++ )
             {
             CHttpCacheEntry* entry = entries.At( i );
             if( entry && entry != (CHttpCacheEntry*)0xffffffff )
                 {
-                HttpCacheUtil::WriteUrlToLog( 0, entry->Url(), entry->Size() );
-                size+=entry->Size();
-                size+=entry->HeaderSize();
+                HttpCacheUtil::WriteUrlToLog( 0, entry->Url(), entry->BodySize() );
+                size += entry->BodySize();
+                size += entry->HeaderSize();
                 }
             }
         HttpCacheUtil::WriteLog( 0, _L( "occupy with headers:" ), size );
 #endif // __CACHELOG__
+
         CArrayPtrFlat<CHttpCacheEntry>* evictedList = iEvictionHandler->EvictL( aSize );
-        if( evictedList && evictedList->Count() )
+        if ( evictedList && evictedList->Count() )
             {
             // destroy items
             CHttpCacheEntry* entry;
@@ -972,7 +1015,7 @@
                     iLookupTable->Remove( entry->Url() );
                     }
                 }
-            // __ASSERT_DEBUG( iStreamHandler->SavedContentSize() + aSize < iSize, PanicCacheHandler( KErrCorrupt ) );
+
             // ok = ETrue if there is enough space
             ok = ( iStreamHandler->SavedContentSize() + aSize < iSize );
             }
@@ -1004,49 +1047,56 @@
     RHTTPHeaders responseHeader = aTrans.Response().GetHeaderCollection();
     RStringPool strP = aTrans.Session().StringPool();
     HBufC8* responseHeaderStr = HttpCacheUtil::HeadersToBufferLC( responseHeader, strP );
-    //
+
     TBool update( ETrue );
     // get cached headers to compare
     HBufC8* cachedHeaderStr = iStreamHandler->HeadersL( aEntry );
-    // we've got some headers to update,
-    // check if we really need to update them
-    if( cachedHeaderStr )
+    
+    // we've got some headers to update, check if we really need to update them
+    if ( cachedHeaderStr )
         {
         CleanupStack::PushL( cachedHeaderStr );
-        //
+
         update = HttpCacheUtil::CacheNeedsUpdateL( responseHeader, cachedHeaderStr->Des(), strP );
 
         CleanupStack::PopAndDestroy(); // cachedHeaderStr
         }
-    //
-    if( update )
+
+    if ( update )
         {
 #ifdef __CACHELOG__
-        HttpCacheUtil::WriteLog( 0, _L( "udpate headers" ) );
+        HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+                                       _L("CHttpCacheHandler::HandleResponseOkL - cache UPDATE needed"),
+                                       aEntry.Filename(),
+                                       aEntry.Url(),
+                                       aEntry.BodySize(), 
+                                       ELogEntrySize );
 #endif
-        if( aEntry.HeaderSize() )
+        if ( aEntry.HeaderSize() )
             {
-            // remove it first
+            // remove headers from headerFile first
             iStreamHandler->RemoveHeaders( aEntry );
             }
-        // save
+
+        // save new headerFile
         saveOk = SaveBuffer( aEntry, responseHeaderStr->Des() );
-
-        if( aEntry.Size() )
+        
+        if ( aEntry.BodySize() )
             {
-#ifdef __CACHELOG__
-            HttpCacheUtil::WriteLog( 0, _L( "remove body" ) );
-#endif            
-            //
-            iStreamHandler->RemoveBodyData( aEntry );
+            // We will remove this body data, after we confirm that we get new
+            // body data
+            aEntry.SetBodyFileDeleteNeeded( ETrue );
             }
+
+        // Setup a cache buffer to hold the incoming body
+        aEntry.SetCacheBufferL( KBufferSize32k );
         }
     else
         {
         // if neither the header nor the body need to be updated, then
         // detach entry to protect from being updated
 #ifdef __CACHELOG__
-        HttpCacheUtil::WriteLog( 0, _L( "no udpate needed, ignore response" ) );
+        HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheHandler::HandleResponseOkL - no update needed, ignore response" ) );
 #endif        
         //
         aEntry.SetState( CHttpCacheEntry::ECacheComplete );
@@ -1054,8 +1104,10 @@
         // pretend that save was ok.
         saveOk = ETrue;
         }
+
+    CleanupStack::PopAndDestroy(); // responseHeaderStr
+
     // destroy corrupt entry by returning EFalse
-    CleanupStack::PopAndDestroy(); // responseHeaderStr
     return saveOk;
     }
 
@@ -1163,7 +1215,7 @@
             CleanupClosePushL( readStream );
             aLookupTable->InternalizeL( readStream, iDirectory->Des() );
             CleanupStack::PopAndDestroy(1); // readStream
-        }
+            }
     }
 
 // -----------------------------------------------------------------------------
@@ -1208,20 +1260,28 @@
     }
 
 // -----------------------------------------------------------------------------
-// CHttpCacheHandler::HandleCorruptEntry
+// CHttpCacheHandler::DeleteCacheEntry
 //
 // -----------------------------------------------------------------------------
 //
-void CHttpCacheHandler::HandleCorruptEntry(
-    CHttpCacheEntry& aStrayEntry,
+void CHttpCacheHandler::DeleteCacheEntry(
+    CHttpCacheEntry& aEntry,
     TBool aUpdate )
     {
-    (void)aUpdate;//suppress compiler and PC-lint warnings
+    // suppress compiler and PC-lint warnings
+    (void)aUpdate;
+
 #ifdef __CACHELOG__
-    HttpCacheUtil::WriteLog( 0, _L( "delete this stray entry" ) );
+        HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+                                       _L("CHttpCacheHandler::DeleteCacheEntry"),
+                                       aEntry.Filename(),
+                                       aEntry.Url(),
+                                       aEntry.BodySize(), 
+                                       ELogEntrySize );
 #endif
-    // remove from the lookuptable
-    iLookupTable->EraseCorruptEntry( aStrayEntry.Url() );
+
+    // Remove from the lookuptable
+    iLookupTable->EraseCacheEntry( aEntry.Url() );
     }
 
 // -----------------------------------------------------------------------------
@@ -1241,10 +1301,11 @@
     TBool aBody )
     {
     TBool ok( EFalse );
+    
     TRAPD( err, ok = CacheNeedsSpaceL( aBuffer.Length() ) );
-    if( err == KErrNone && ok )
+    if ( err == KErrNone && ok )
         {
-        // safe save
+        // Did we have a safe save of the body or header
         ok = aBody ? iStreamHandler->SaveBodyData( aEntry, aBuffer ) : iStreamHandler->SaveHeaders( aEntry, aBuffer );
         }
 #ifdef __CACHELOG__