--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebCore/platform/network/symbian/HttpCacheSupply.cpp Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,339 @@
+/*
+* 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 CHttpCacheSupply
+*
+*/
+
+
+// INCLUDE FILES
+#include "HttpCacheSupply.h"
+#include "HttpCacheManager.h"
+#include "HttpCacheDataSupplier.h"
+#include "HttpConnection.h"
+#include "ResourceLoaderDelegate.h"
+#include "StaticObjectsContainer.h"
+
+#include <http/RHTTPTransaction.h>
+#include <http/mhttpdatasupplier.h>
+#include <http/rhttpsession.h>
+#include <httperr.h>
+
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+const TInt KResponseTimeout = 0;
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::CHttpCacheSupply
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CHttpCacheSupply::CHttpCacheSupply(HttpConnection* aHttpTransaction)
+ : m_httpTransaction( aHttpTransaction ),
+ m_reponseState( THTTPEvent::EClosed )
+{
+ m_cacheEntry.iCacheHandler = NULL;
+ m_cacheEntry.iCacheEntry = NULL;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::ConstructL()
+{
+ m_cacheManager = WebCore::StaticObjectsContainer::instance()->resourceLoaderDelegate()->httpSessionManager()->cacheManager();
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CHttpCacheSupply* CHttpCacheSupply::NewL(HttpConnection* aHttpTransaction)
+{
+ CHttpCacheSupply* self = new( ELeave ) CHttpCacheSupply( aHttpTransaction );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+}
+
+// Destructor
+CHttpCacheSupply::~CHttpCacheSupply()
+{
+ delete m_dataSupplier;
+ CloseRequest();
+ delete m_responseTimer;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::StartRequestL
+//
+//
+// -----------------------------------------------------------------------------
+//
+TInt CHttpCacheSupply::StartRequestL(TBrCtlDefs::TBrCtlCacheMode aCacheMode)
+{
+ TInt status;
+ status = m_cacheManager->RequestL( *(m_httpTransaction->HttpTransaction()), aCacheMode, m_cacheEntry );
+ // start a timer that feeds the content to the transaction
+ if( status == KErrNone ) {
+ m_closed = EFalse;
+ // set response state. start with the http headers.
+ m_reponseState = THTTPEvent::EGotResponseHeaders;
+ m_responseTimer = CPeriodic::NewL( CActive::EPriorityHigh );
+ m_responseTimer->Start( KResponseTimeout, KResponseTimeout, TCallBack( &ResponseCallbackL, this ) );
+ }
+ return status;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::CloseRequest
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::CloseRequest()
+{
+ if( !m_closed) {
+ m_cacheManager->RequestClosed( (m_httpTransaction->HttpTransaction()), m_cacheEntry );
+ m_closed = ETrue;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::HeadersReceived
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::HeadersReceivedL()
+{
+ // do not cache content we just sent off
+ if( m_reponseState == THTTPEvent::EClosed ) {
+ RHTTPTransaction* trans = m_httpTransaction->HttpTransaction();
+ m_cacheManager->ReceivedResponseHeadersL( *(m_httpTransaction->HttpTransaction()), m_cacheEntry );
+ //
+ m_notModified = trans->Response().StatusCode() == HTTPStatus::ENotModified;
+ if( m_notModified ) {
+ // change from 304 to 200 -otherwise trans exits with EFailed
+ trans->Response().SetStatusCode( HTTPStatus::EOk );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::BodyReceivedL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::BodyReceivedL()
+{
+ // do not cache content we just sent off
+ if( m_reponseState == THTTPEvent::EClosed ) {
+ RHTTPTransaction* trans = m_httpTransaction->HttpTransaction();
+ MHTTPDataSupplier* supplier = trans->Response().Body();
+ //
+ m_cacheManager->ReceivedResponseBodyDataL( *trans, *supplier, m_cacheEntry );
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::ResponseComplete
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::ResponseCompleteL()
+{
+ if( m_reponseState == THTTPEvent::EClosed ) {
+ RHTTPTransaction* trans = m_httpTransaction->HttpTransaction();
+ // not modified needs body before response complete
+ if( m_notModified ) {
+ // use cache
+ // close response first
+ m_cacheManager->ResponseComplete( *trans, m_cacheEntry );
+ // request the item from cache
+ if( m_cacheManager->RequestL( *trans, TBrCtlDefs::ECacheModeOnlyCache, m_cacheEntry ) == KErrNone ) {
+ // ser
+ m_reponseState = THTTPEvent::EGotResponseBodyData;
+ //
+ SendBodyL();
+ CloseRequest();
+ }
+ }
+ else {
+ // normal response complete
+ m_cacheManager->ResponseComplete( *trans, m_cacheEntry );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::ResponseCallbackL
+//
+//
+// -----------------------------------------------------------------------------
+//
+TInt CHttpCacheSupply::ResponseCallbackL(TAny* aAny)
+{
+ //
+ CHttpCacheSupply* thisObj = (CHttpCacheSupply*)aAny;
+ thisObj->SupplyResponseL();
+ return KErrNone;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::SupplyResponseL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::SupplyResponseL()
+{
+ RHTTPTransaction* trans = m_httpTransaction->HttpTransaction();
+ //
+ switch( m_reponseState )
+ {
+ case THTTPEvent::EGotResponseHeaders:
+ {
+ m_failed = EFalse;
+ if( m_cacheManager->RequestHeadersL( *trans, m_cacheEntry ) == KErrNone ) {
+ //
+ trans->Response().SetStatusCode( HTTPStatus::EOk );
+ //
+ m_httpTransaction->MHFRunL( THTTPEvent::EGotResponseHeaders );
+ // move to the next state
+ m_reponseState = THTTPEvent::EGotResponseBodyData;
+ }
+ else {
+ // move to the next state
+ m_failed = ETrue;
+ // move to the next state
+ m_reponseState = THTTPEvent::EResponseComplete;
+ }
+ break;
+ }
+ case THTTPEvent::EGotResponseBodyData:
+ {
+ SendBodyL();
+ // move to the next state
+ m_reponseState = THTTPEvent::EResponseComplete;
+ break;
+ }
+ case THTTPEvent::EResponseComplete:
+ {
+ m_httpTransaction->MHFRunL(THTTPEvent::EResponseComplete );
+ // move to the next state
+ m_reponseState = !m_failed ? THTTPEvent::ESucceeded : THTTPEvent::EFailed;
+ break;
+ }
+ case THTTPEvent::ESucceeded:
+ {
+ // move to the next state
+ m_reponseState = THTTPEvent::EClosed;
+ // cancel timer
+ m_responseTimer->Cancel();
+ //
+ m_httpTransaction->MHFRunL(THTTPEvent::ESucceeded );
+ // this obj is destroyed at this point
+ break;
+ }
+ case THTTPEvent::EFailed:
+ {
+ // move to the next state
+ m_reponseState = THTTPEvent::EClosed;
+ // cancel timer
+ m_responseTimer->Cancel();
+ m_httpTransaction->MHFRunL(THTTPEvent::EFailed );
+ // this obj is destroyed at this point
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::SendBodyL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheSupply::SendBodyL()
+{
+ RHTTPTransaction* trans = m_httpTransaction->HttpTransaction();
+ //
+ TBool lastChunk;
+ // currently it is always the last chunk
+ HBufC8* body = m_cacheManager->RequestNextChunkL( *trans, lastChunk, m_cacheEntry );
+ if( body ) {
+ CleanupStack::PushL( body );
+ // create datasupplier and attach it to the transaction
+ if( !m_dataSupplier )
+ m_dataSupplier = CHttpCacheDataSupplier::NewL( body );
+ trans->Response().SetBody( *m_dataSupplier );
+ CleanupStack::Pop(); // body
+ //
+ m_httpTransaction->MHFRunL(THTTPEvent::EGotResponseBodyData );
+ }
+ else {
+ // move to the next state
+ m_failed = ETrue;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::PauseSupply
+// -----------------------------------------------------------------------------
+void CHttpCacheSupply::PauseSupply()
+{
+ if( m_responseTimer && m_responseTimer->IsActive() )
+ m_responseTimer->Cancel();
+}
+
+// -----------------------------------------------------------------------------
+// CHttpCacheSupply::ResumeSupply
+// -----------------------------------------------------------------------------
+void CHttpCacheSupply::ResumeSupply()
+{
+ if( m_responseTimer && !m_responseTimer->IsActive() )
+ m_responseTimer->Start( KResponseTimeout, KResponseTimeout, TCallBack( &ResponseCallbackL, this ) );
+}
+
+// End of File