applayerprotocols/httpexamples/TestWebBrowser/src/browsertransaction.cpp
changeset 0 b16258d2340f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httpexamples/TestWebBrowser/src/browsertransaction.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,340 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+//
+
+#include "browsertransaction.h"
+#include "httpexampleutils.h"
+#include "htmlhandler.h"
+
+#include <escapeutils.h>
+
+_LIT8(KHtmlParserDataType, "text/html");
+_LIT8(KXmlParserDataType, "text/xml");
+
+
+_LIT8(KUserAgent, "Test web browser/1.0");
+
+CBrowserTransaction::CBrowserTransaction ( RHTTPSession& aSession, 
+										CHttpExampleUtils& aTestUtils,
+										MBrowserTransactionObserver* aObserver,
+										TBool aParseHtml /* = EFalse */ )
+: iSession ( aSession ),
+	iTransObserver ( aObserver ),
+	iTestUtils ( aTestUtils ),
+	iParseHtml ( aParseHtml ),
+	iSavingBody ( EFalse )
+	{
+	
+	}
+
+CBrowserTransaction::~CBrowserTransaction ()
+	{
+	iFileServer.Close();
+	delete iFilePath;
+	delete iHtmlHandler;
+	}
+
+CBrowserTransaction* CBrowserTransaction::NewLC (	RHTTPSession& aSession, 
+												CHttpExampleUtils& aTestUtils,
+												MBrowserTransactionObserver* aObserver,
+												const TDesC& aFilePath,
+												TBool aParseHtml /* = EFalse */ )
+	{
+	CBrowserTransaction* me = new( ELeave ) CBrowserTransaction ( aSession, aTestUtils, aObserver, aParseHtml );
+	CleanupStack::PushL ( me );
+	me->ConstructL ( aFilePath );
+	return me;
+	}
+
+void CBrowserTransaction::ConstructL ( const TDesC& aFilePath )
+	{
+	User::LeaveIfError ( iFileServer.Connect () );
+	iFilePath = aFilePath.AllocL ();
+	}
+
+CBrowserTransaction* CBrowserTransaction::NewL ( RHTTPSession& aSession, 
+											   CHttpExampleUtils& aTestUtils,
+											   MBrowserTransactionObserver* aObserver,
+											   const TDesC& aFilePath,
+											   TBool aParseHtml /* = EFalse */ )
+	{
+	CBrowserTransaction* me = CBrowserTransaction::NewLC ( aSession, aTestUtils, aObserver, aFilePath, aParseHtml );
+	CleanupStack::Pop ( me );
+	return me;
+	}
+
+/**
+	Open a new transaction and set the Date header field.
+	
+	@param aUri [in] Request URI.
+ */	
+void CBrowserTransaction::CreateTransactionL ( const TDesC8& aUri )
+	{
+	
+	TUriParser8 uri; 
+	uri.Parse ( aUri );	
+	RStringF get = iSession.StringPool().StringF ( HTTP::EGET, RHTTPSession::GetTable() );	
+	// Open a new transaction.
+	iTransaction = iSession.OpenTransactionL ( uri, *this, get );	
+
+	// Add current date header
+	TTime time;
+	time.UniversalTime();
+	THTTPHdrVal hdrVal( time.DateTime() );
+	RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
+	hdr.SetFieldL( iSession.StringPool().StringF( HTTP::EDate, RHTTPSession::GetTable() ), hdrVal );	
+
+	RStringF valStr = iSession.StringPool().OpenFStringL(KUserAgent);
+	THTTPHdrVal val(valStr);
+	hdr.SetFieldL(iSession.StringPool().StringF( HTTP::EUserAgent, RHTTPSession::GetTable() ), val);
+	valStr.Close();
+
+	// Set the accept header.
+	SetAcceptHdrL ();
+	}
+
+/**
+	Submit the transaction.		
+ */	
+void CBrowserTransaction::StartTransactionL ()
+	{
+	// Submit the transaction
+	iTransaction.SubmitL ();	
+	}
+
+/**
+   Extract content type header from the HTTP response headers. 
+ */
+void CBrowserTransaction::ExtractContentTypeL ( RHTTPResponse& aResponse, RStringF& aContentTypeValue )
+	{	
+	RHTTPHeaders hdr = aResponse.GetHeaderCollection();
+
+	RStringF contentType = iSession.StringPool ().StringF ( HTTP::EContentType, RHTTPSession::GetTable() );
+	
+	THTTPHdrVal fieldVal;
+	TInt ret = hdr.GetField ( contentType, 0, fieldVal );
+	if ( ret != KErrNone )
+		{
+		User::Leave ( KErrNotFound );
+		}
+		
+	aContentTypeValue = fieldVal.StrF ();	
+	}
+
+/**
+   Load the parser plugin. text/html or text/xml type.
+ */
+void CBrowserTransaction::LoadPluginL ( TMimeType aType )
+	{		
+	// Load the corresponding plugin based on the type. If it is of "xml" type 
+	// load xml plugin else load html plugin.		
+	iHtmlHandler = CHtmlHandler::NewL ( *iTransObserver, ( aType == eXml ) ? KXmlParserDataType() : KHtmlParserDataType() );			
+	}
+
+void CBrowserTransaction::SetAcceptHdrL ()
+	{	 
+	// Set the following HTTP Accept header.
+	// text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,*/*;q=0.5	
+	RHTTPHeaders hdr = iTransaction.Request ().GetHeaderCollection();
+	RStringPool stringPool = iSession.StringPool ();
+	
+	RStringF textXml = stringPool.OpenFStringL ( _L8 ( "text/xml" ) );
+	CleanupClosePushL ( textXml );
+	
+	RStringF appXml = stringPool.OpenFStringL ( _L8 ( "application/xml" ) );
+	CleanupClosePushL ( appXml );
+	
+	RStringF appXhtmlXml = stringPool.OpenFStringL ( _L8 ( "application/xhtml+xml" ) );
+	CleanupClosePushL ( appXhtmlXml );
+	
+	RStringF textHtml = stringPool.OpenFStringL ( _L8 ( "text/html" ) );
+	CleanupClosePushL ( textHtml );
+			
+	RStringF any = stringPool.OpenFStringL ( _L8 ( "*/*" ) );
+	CleanupClosePushL ( any );
+	
+	THTTPHdrVal hdrVal ( textXml );
+	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal );
+	
+	hdrVal.SetStrF ( appXml );
+	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal );
+	
+	hdrVal.SetStrF ( appXhtmlXml );
+	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal );
+	
+	hdrVal.SetStrF ( textHtml );
+	THTTPHdrVal q;
+	q.SetInt( THTTPHdrVal::TQConv( 0.9 ) );
+	
+	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal, 
+					stringPool.StringF ( HTTP::EQ, RHTTPSession::GetTable() ), q );
+
+	q.SetInt ( THTTPHdrVal::TQConv( 0.5 ) );
+	hdrVal.SetStrF ( any );
+	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal, 
+					stringPool.StringF ( HTTP::EQ, RHTTPSession::GetTable() ), q );
+	
+	CleanupStack::PopAndDestroy ( 5 );	// Destroy textXml, appXml, appXhtmlXml, textHtml & any.		
+	}
+
+			
+void CBrowserTransaction::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
+	{
+	switch (aEvent.iStatus)
+		{
+		case THTTPEvent::EGotResponseHeaders:
+			{
+			// HTTP response headers have been received. 
+			RHTTPResponse resp = aTransaction.Response();
+			TInt status = resp.StatusCode();
+			if ( iParseHtml )
+				{
+				RStringF contentTypeValue;
+				ExtractContentTypeL ( resp, contentTypeValue );
+				TMimeType type = GetMimeType ( contentTypeValue );
+				if ( type != eUnknown )
+					{
+					TRAPD ( err, LoadPluginL ( type ) );
+					if ( err != KErrNone )
+						{
+						iTestUtils.Test().Printf(_L("\nUnable to load the parser plugin.\n"));
+						User::Leave ( KErrNotFound );					
+						}										
+					else
+						{
+						iTestUtils.Test().Printf(_L("\nPlugin loaded.\n"));							
+						}
+					}
+				else
+					{
+					iParseHtml = EFalse;						
+					}
+				}
+
+			if ( resp.HasBody() && ( status >= 200 ) && ( status < 300 ) && ( status != 204 ) )
+				{
+				iFileServer.MkDirAll( iFilePath->Des() );
+				User::LeaveIfError ( iRespBodyFile.Replace ( iFileServer, iFilePath->Des(), EFileWrite|EFileShareExclusive ) );
+				iSavingBody = ETrue;
+				}
+			} break;
+		case THTTPEvent::EGotResponseBodyData:
+			{
+			// Get the body data supplier
+			iRespBody = aTransaction.Response().Body();
+			// Append to the output file.
+			TPtrC8 bodyData;
+			TBool lastChunk = iRespBody->GetNextDataPart( bodyData );
+
+			if ( iParseHtml )
+				{
+				iHtmlHandler->ParseHtmlContentL( bodyData );				
+				}
+				
+			if ( iSavingBody )
+				{
+				iRespBodyFile.Write( bodyData );								
+				}
+
+						
+			if ( lastChunk )
+				{
+				if ( iParseHtml )
+					{
+					iHtmlHandler->ParseEndL ();							
+					}
+				if ( iSavingBody )
+					{
+					iRespBodyFile.Close();				
+					}
+				}
+
+			// Done with that bit of body data
+			iRespBody->ReleaseData();
+			
+			} break;
+		case THTTPEvent::EResponseComplete:
+			{
+			// The transaction's response is complete
+			iTestUtils.Test().Printf(_L("\nTransaction Complete\n"));
+			} break;
+		case THTTPEvent::ESucceeded:
+			{
+			iTestUtils.Test().Printf(_L("Transaction Successful\n"));
+			aTransaction.Close();
+			iTransObserver->OnTransactionClose ( this );
+			} break;
+		case THTTPEvent::EFailed:
+			{
+			iTestUtils.Test().Printf(_L("Transaction Failed\n"));
+			aTransaction.Close();
+			iTransObserver->OnTransactionClose ( this );
+			} break;
+		case THTTPEvent::ERedirectedPermanently:
+			{
+			iTestUtils.Test().Printf(_L("Permanent Redirection\n"));
+			} break;
+		case THTTPEvent::ERedirectedTemporarily:
+			{
+			iTestUtils.Test().Printf(_L("Temporary Redirection\n"));
+			} break;
+		case THTTPEvent::ERedirectRequiresConfirmation:
+ 			{
+			// 301(Moved Permanently), 302(Found) or 307(Temporary Redirect) status is received 
+			// from a transaction and hence ERedirectRequiresConfirmation is sent by filter
+			// client has opted to close the transaction
+			iTestUtils.Test().Printf(_L("Redirect requires confirmation\n"));
+ 			aTransaction.Close();
+			iTransObserver->OnTransactionClose ( this );
+ 			} break;
+		default:
+			{
+			iTestUtils.Test().Printf(_L("<unrecognised event: %d>\n"), aEvent.iStatus);
+			// close off the transaction if it's an error
+			if (aEvent.iStatus < 0)
+				{
+				aTransaction.Close();
+				iTransObserver->OnTransactionClose ( this );
+				}
+			} break;
+		}
+	}
+
+TInt CBrowserTransaction::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
+	{
+	iTestUtils.Test().Printf(_L("MHFRunError fired with error code %d\n"), aError);
+	iTestUtils.PressAnyKey ();
+
+	return KErrNone;
+	}
+
+
+CBrowserTransaction::TMimeType CBrowserTransaction::GetMimeType ( const RStringF& aType )
+	{
+	// Find the type has "xml" or "html". HTTP header will be set to 
+	// text/xml,application/xml,application/xhtml+xml,text/html	
+	TMimeType type ( eUnknown );
+	TPtrC8 ptrType ( aType.DesC() );
+	
+	if ( ptrType.FindF ( _L8 ("xml") ) != KErrNotFound )
+		{
+		type = eXml;
+		}
+
+	if ( ptrType.FindF ( _L8 ("html") ) != KErrNotFound )
+		{
+		type = eHtml;
+		}	
+	return type;
+	}