applayerprotocols/httpexamples/TestWebBrowser/src/browsertransaction.cpp
changeset 0 b16258d2340f
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "browsertransaction.h"
       
    17 #include "httpexampleutils.h"
       
    18 #include "htmlhandler.h"
       
    19 
       
    20 #include <escapeutils.h>
       
    21 
       
    22 _LIT8(KHtmlParserDataType, "text/html");
       
    23 _LIT8(KXmlParserDataType, "text/xml");
       
    24 
       
    25 
       
    26 _LIT8(KUserAgent, "Test web browser/1.0");
       
    27 
       
    28 CBrowserTransaction::CBrowserTransaction ( RHTTPSession& aSession, 
       
    29 										CHttpExampleUtils& aTestUtils,
       
    30 										MBrowserTransactionObserver* aObserver,
       
    31 										TBool aParseHtml /* = EFalse */ )
       
    32 : iSession ( aSession ),
       
    33 	iTransObserver ( aObserver ),
       
    34 	iTestUtils ( aTestUtils ),
       
    35 	iParseHtml ( aParseHtml ),
       
    36 	iSavingBody ( EFalse )
       
    37 	{
       
    38 	
       
    39 	}
       
    40 
       
    41 CBrowserTransaction::~CBrowserTransaction ()
       
    42 	{
       
    43 	iFileServer.Close();
       
    44 	delete iFilePath;
       
    45 	delete iHtmlHandler;
       
    46 	}
       
    47 
       
    48 CBrowserTransaction* CBrowserTransaction::NewLC (	RHTTPSession& aSession, 
       
    49 												CHttpExampleUtils& aTestUtils,
       
    50 												MBrowserTransactionObserver* aObserver,
       
    51 												const TDesC& aFilePath,
       
    52 												TBool aParseHtml /* = EFalse */ )
       
    53 	{
       
    54 	CBrowserTransaction* me = new( ELeave ) CBrowserTransaction ( aSession, aTestUtils, aObserver, aParseHtml );
       
    55 	CleanupStack::PushL ( me );
       
    56 	me->ConstructL ( aFilePath );
       
    57 	return me;
       
    58 	}
       
    59 
       
    60 void CBrowserTransaction::ConstructL ( const TDesC& aFilePath )
       
    61 	{
       
    62 	User::LeaveIfError ( iFileServer.Connect () );
       
    63 	iFilePath = aFilePath.AllocL ();
       
    64 	}
       
    65 
       
    66 CBrowserTransaction* CBrowserTransaction::NewL ( RHTTPSession& aSession, 
       
    67 											   CHttpExampleUtils& aTestUtils,
       
    68 											   MBrowserTransactionObserver* aObserver,
       
    69 											   const TDesC& aFilePath,
       
    70 											   TBool aParseHtml /* = EFalse */ )
       
    71 	{
       
    72 	CBrowserTransaction* me = CBrowserTransaction::NewLC ( aSession, aTestUtils, aObserver, aFilePath, aParseHtml );
       
    73 	CleanupStack::Pop ( me );
       
    74 	return me;
       
    75 	}
       
    76 
       
    77 /**
       
    78 	Open a new transaction and set the Date header field.
       
    79 	
       
    80 	@param aUri [in] Request URI.
       
    81  */	
       
    82 void CBrowserTransaction::CreateTransactionL ( const TDesC8& aUri )
       
    83 	{
       
    84 	
       
    85 	TUriParser8 uri; 
       
    86 	uri.Parse ( aUri );	
       
    87 	RStringF get = iSession.StringPool().StringF ( HTTP::EGET, RHTTPSession::GetTable() );	
       
    88 	// Open a new transaction.
       
    89 	iTransaction = iSession.OpenTransactionL ( uri, *this, get );	
       
    90 
       
    91 	// Add current date header
       
    92 	TTime time;
       
    93 	time.UniversalTime();
       
    94 	THTTPHdrVal hdrVal( time.DateTime() );
       
    95 	RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
       
    96 	hdr.SetFieldL( iSession.StringPool().StringF( HTTP::EDate, RHTTPSession::GetTable() ), hdrVal );	
       
    97 
       
    98 	RStringF valStr = iSession.StringPool().OpenFStringL(KUserAgent);
       
    99 	THTTPHdrVal val(valStr);
       
   100 	hdr.SetFieldL(iSession.StringPool().StringF( HTTP::EUserAgent, RHTTPSession::GetTable() ), val);
       
   101 	valStr.Close();
       
   102 
       
   103 	// Set the accept header.
       
   104 	SetAcceptHdrL ();
       
   105 	}
       
   106 
       
   107 /**
       
   108 	Submit the transaction.		
       
   109  */	
       
   110 void CBrowserTransaction::StartTransactionL ()
       
   111 	{
       
   112 	// Submit the transaction
       
   113 	iTransaction.SubmitL ();	
       
   114 	}
       
   115 
       
   116 /**
       
   117    Extract content type header from the HTTP response headers. 
       
   118  */
       
   119 void CBrowserTransaction::ExtractContentTypeL ( RHTTPResponse& aResponse, RStringF& aContentTypeValue )
       
   120 	{	
       
   121 	RHTTPHeaders hdr = aResponse.GetHeaderCollection();
       
   122 
       
   123 	RStringF contentType = iSession.StringPool ().StringF ( HTTP::EContentType, RHTTPSession::GetTable() );
       
   124 	
       
   125 	THTTPHdrVal fieldVal;
       
   126 	TInt ret = hdr.GetField ( contentType, 0, fieldVal );
       
   127 	if ( ret != KErrNone )
       
   128 		{
       
   129 		User::Leave ( KErrNotFound );
       
   130 		}
       
   131 		
       
   132 	aContentTypeValue = fieldVal.StrF ();	
       
   133 	}
       
   134 
       
   135 /**
       
   136    Load the parser plugin. text/html or text/xml type.
       
   137  */
       
   138 void CBrowserTransaction::LoadPluginL ( TMimeType aType )
       
   139 	{		
       
   140 	// Load the corresponding plugin based on the type. If it is of "xml" type 
       
   141 	// load xml plugin else load html plugin.		
       
   142 	iHtmlHandler = CHtmlHandler::NewL ( *iTransObserver, ( aType == eXml ) ? KXmlParserDataType() : KHtmlParserDataType() );			
       
   143 	}
       
   144 
       
   145 void CBrowserTransaction::SetAcceptHdrL ()
       
   146 	{	 
       
   147 	// Set the following HTTP Accept header.
       
   148 	// text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,*/*;q=0.5	
       
   149 	RHTTPHeaders hdr = iTransaction.Request ().GetHeaderCollection();
       
   150 	RStringPool stringPool = iSession.StringPool ();
       
   151 	
       
   152 	RStringF textXml = stringPool.OpenFStringL ( _L8 ( "text/xml" ) );
       
   153 	CleanupClosePushL ( textXml );
       
   154 	
       
   155 	RStringF appXml = stringPool.OpenFStringL ( _L8 ( "application/xml" ) );
       
   156 	CleanupClosePushL ( appXml );
       
   157 	
       
   158 	RStringF appXhtmlXml = stringPool.OpenFStringL ( _L8 ( "application/xhtml+xml" ) );
       
   159 	CleanupClosePushL ( appXhtmlXml );
       
   160 	
       
   161 	RStringF textHtml = stringPool.OpenFStringL ( _L8 ( "text/html" ) );
       
   162 	CleanupClosePushL ( textHtml );
       
   163 			
       
   164 	RStringF any = stringPool.OpenFStringL ( _L8 ( "*/*" ) );
       
   165 	CleanupClosePushL ( any );
       
   166 	
       
   167 	THTTPHdrVal hdrVal ( textXml );
       
   168 	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal );
       
   169 	
       
   170 	hdrVal.SetStrF ( appXml );
       
   171 	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal );
       
   172 	
       
   173 	hdrVal.SetStrF ( appXhtmlXml );
       
   174 	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal );
       
   175 	
       
   176 	hdrVal.SetStrF ( textHtml );
       
   177 	THTTPHdrVal q;
       
   178 	q.SetInt( THTTPHdrVal::TQConv( 0.9 ) );
       
   179 	
       
   180 	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal, 
       
   181 					stringPool.StringF ( HTTP::EQ, RHTTPSession::GetTable() ), q );
       
   182 
       
   183 	q.SetInt ( THTTPHdrVal::TQConv( 0.5 ) );
       
   184 	hdrVal.SetStrF ( any );
       
   185 	hdr.SetFieldL ( stringPool.StringF ( HTTP::EAccept, RHTTPSession::GetTable () ), hdrVal, 
       
   186 					stringPool.StringF ( HTTP::EQ, RHTTPSession::GetTable() ), q );
       
   187 	
       
   188 	CleanupStack::PopAndDestroy ( 5 );	// Destroy textXml, appXml, appXhtmlXml, textHtml & any.		
       
   189 	}
       
   190 
       
   191 			
       
   192 void CBrowserTransaction::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   193 	{
       
   194 	switch (aEvent.iStatus)
       
   195 		{
       
   196 		case THTTPEvent::EGotResponseHeaders:
       
   197 			{
       
   198 			// HTTP response headers have been received. 
       
   199 			RHTTPResponse resp = aTransaction.Response();
       
   200 			TInt status = resp.StatusCode();
       
   201 			if ( iParseHtml )
       
   202 				{
       
   203 				RStringF contentTypeValue;
       
   204 				ExtractContentTypeL ( resp, contentTypeValue );
       
   205 				TMimeType type = GetMimeType ( contentTypeValue );
       
   206 				if ( type != eUnknown )
       
   207 					{
       
   208 					TRAPD ( err, LoadPluginL ( type ) );
       
   209 					if ( err != KErrNone )
       
   210 						{
       
   211 						iTestUtils.Test().Printf(_L("\nUnable to load the parser plugin.\n"));
       
   212 						User::Leave ( KErrNotFound );					
       
   213 						}										
       
   214 					else
       
   215 						{
       
   216 						iTestUtils.Test().Printf(_L("\nPlugin loaded.\n"));							
       
   217 						}
       
   218 					}
       
   219 				else
       
   220 					{
       
   221 					iParseHtml = EFalse;						
       
   222 					}
       
   223 				}
       
   224 
       
   225 			if ( resp.HasBody() && ( status >= 200 ) && ( status < 300 ) && ( status != 204 ) )
       
   226 				{
       
   227 				iFileServer.MkDirAll( iFilePath->Des() );
       
   228 				User::LeaveIfError ( iRespBodyFile.Replace ( iFileServer, iFilePath->Des(), EFileWrite|EFileShareExclusive ) );
       
   229 				iSavingBody = ETrue;
       
   230 				}
       
   231 			} break;
       
   232 		case THTTPEvent::EGotResponseBodyData:
       
   233 			{
       
   234 			// Get the body data supplier
       
   235 			iRespBody = aTransaction.Response().Body();
       
   236 			// Append to the output file.
       
   237 			TPtrC8 bodyData;
       
   238 			TBool lastChunk = iRespBody->GetNextDataPart( bodyData );
       
   239 
       
   240 			if ( iParseHtml )
       
   241 				{
       
   242 				iHtmlHandler->ParseHtmlContentL( bodyData );				
       
   243 				}
       
   244 				
       
   245 			if ( iSavingBody )
       
   246 				{
       
   247 				iRespBodyFile.Write( bodyData );								
       
   248 				}
       
   249 
       
   250 						
       
   251 			if ( lastChunk )
       
   252 				{
       
   253 				if ( iParseHtml )
       
   254 					{
       
   255 					iHtmlHandler->ParseEndL ();							
       
   256 					}
       
   257 				if ( iSavingBody )
       
   258 					{
       
   259 					iRespBodyFile.Close();				
       
   260 					}
       
   261 				}
       
   262 
       
   263 			// Done with that bit of body data
       
   264 			iRespBody->ReleaseData();
       
   265 			
       
   266 			} break;
       
   267 		case THTTPEvent::EResponseComplete:
       
   268 			{
       
   269 			// The transaction's response is complete
       
   270 			iTestUtils.Test().Printf(_L("\nTransaction Complete\n"));
       
   271 			} break;
       
   272 		case THTTPEvent::ESucceeded:
       
   273 			{
       
   274 			iTestUtils.Test().Printf(_L("Transaction Successful\n"));
       
   275 			aTransaction.Close();
       
   276 			iTransObserver->OnTransactionClose ( this );
       
   277 			} break;
       
   278 		case THTTPEvent::EFailed:
       
   279 			{
       
   280 			iTestUtils.Test().Printf(_L("Transaction Failed\n"));
       
   281 			aTransaction.Close();
       
   282 			iTransObserver->OnTransactionClose ( this );
       
   283 			} break;
       
   284 		case THTTPEvent::ERedirectedPermanently:
       
   285 			{
       
   286 			iTestUtils.Test().Printf(_L("Permanent Redirection\n"));
       
   287 			} break;
       
   288 		case THTTPEvent::ERedirectedTemporarily:
       
   289 			{
       
   290 			iTestUtils.Test().Printf(_L("Temporary Redirection\n"));
       
   291 			} break;
       
   292 		case THTTPEvent::ERedirectRequiresConfirmation:
       
   293  			{
       
   294 			// 301(Moved Permanently), 302(Found) or 307(Temporary Redirect) status is received 
       
   295 			// from a transaction and hence ERedirectRequiresConfirmation is sent by filter
       
   296 			// client has opted to close the transaction
       
   297 			iTestUtils.Test().Printf(_L("Redirect requires confirmation\n"));
       
   298  			aTransaction.Close();
       
   299 			iTransObserver->OnTransactionClose ( this );
       
   300  			} break;
       
   301 		default:
       
   302 			{
       
   303 			iTestUtils.Test().Printf(_L("<unrecognised event: %d>\n"), aEvent.iStatus);
       
   304 			// close off the transaction if it's an error
       
   305 			if (aEvent.iStatus < 0)
       
   306 				{
       
   307 				aTransaction.Close();
       
   308 				iTransObserver->OnTransactionClose ( this );
       
   309 				}
       
   310 			} break;
       
   311 		}
       
   312 	}
       
   313 
       
   314 TInt CBrowserTransaction::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   315 	{
       
   316 	iTestUtils.Test().Printf(_L("MHFRunError fired with error code %d\n"), aError);
       
   317 	iTestUtils.PressAnyKey ();
       
   318 
       
   319 	return KErrNone;
       
   320 	}
       
   321 
       
   322 
       
   323 CBrowserTransaction::TMimeType CBrowserTransaction::GetMimeType ( const RStringF& aType )
       
   324 	{
       
   325 	// Find the type has "xml" or "html". HTTP header will be set to 
       
   326 	// text/xml,application/xml,application/xhtml+xml,text/html	
       
   327 	TMimeType type ( eUnknown );
       
   328 	TPtrC8 ptrType ( aType.DesC() );
       
   329 	
       
   330 	if ( ptrType.FindF ( _L8 ("xml") ) != KErrNotFound )
       
   331 		{
       
   332 		type = eXml;
       
   333 		}
       
   334 
       
   335 	if ( ptrType.FindF ( _L8 ("html") ) != KErrNotFound )
       
   336 		{
       
   337 		type = eHtml;
       
   338 		}	
       
   339 	return type;
       
   340 	}