applayerprotocols/httpexamples/TestWebBrowser/src/testwebbrowser.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 <e32base.h>
       
    17 #include <http.h>
       
    18 #include <escapeutils.h>
       
    19 
       
    20 #include "testwebbrowser.h"
       
    21 #include "httpexampleutils.h"
       
    22 
       
    23 
       
    24 const TInt KMaxURISize = 256;
       
    25 const TInt KMaxFilePathLength = 512;
       
    26 const TInt KHttpSchemeLength = 7;
       
    27 
       
    28 _LIT ( KDirPath, "c:\\TestWebBrowser\\");
       
    29 _LIT ( KDefaultFilePath, "index.html" );
       
    30 _LIT ( KQuit, "quit" );
       
    31 _LIT ( KSelectOption, " Select an option \n\n" );
       
    32 _LIT ( KPossibleSelectionsText, " 1 Download URL \n 2 Set Proxy\n 3 Quit \n" );
       
    33 _LIT ( KPossibleSelections,"123" );
       
    34 _LIT ( KEnterUrl, "Enter URL: " );
       
    35 _LIT ( KEnterProxy, "Enter Proxy Address: " );	
       
    36 		
       
    37 // Invalid characters that can appear in a URL. These values must be replaced
       
    38 // with a valid character to generate the full file path.
       
    39 _LIT ( KInvalidChars, "<>:\"|*?");
       
    40 
       
    41 const TUint KReplaceChar = '_';
       
    42 
       
    43 void ChangePathSeparator( TDes& aDesPtr, TUint aPathSeperatorFrom, TUint aPathSeperatorTo )
       
    44 	{
       
    45 	for( TInt offset = aDesPtr.Length() - 1; offset >= 0; offset-- )
       
    46 		{
       
    47 		if ( aDesPtr[offset] == aPathSeperatorFrom )
       
    48 			{	
       
    49 				aDesPtr[offset] = TUint16( aPathSeperatorTo );
       
    50 			}
       
    51 		}
       
    52 	}
       
    53 
       
    54 CTestWebBrowser::CTestWebBrowser ( CHttpExampleUtils& aUtils )
       
    55 : CActive ( EPriorityStandard ),
       
    56 iTestUtils ( aUtils ),
       
    57 iCurrentState ( EMainMenu )
       
    58 	{
       
    59 	//Add this active object to the active schedeler
       
    60 	CActiveScheduler::Add(this);
       
    61 	__ASSERT_DEBUG( !IsActive(),User::Panic(_L("Reader"), KErrCorrupt) );
       
    62 	
       
    63 	// Wait for request to be handled.
       
    64 	IssueAndCompleteRequest();		
       
    65 	}
       
    66 
       
    67 
       
    68 CTestWebBrowser::~CTestWebBrowser ()
       
    69 	{
       
    70 	// Close the HTTP session.
       
    71 	iHttpSession.Close();
       
    72 	
       
    73 	iTransArray.ResetAndDestroy ();
       
    74 	iTransArray.Close ();
       
    75 	
       
    76 	delete iBaseUri;
       
    77 	}
       
    78 	
       
    79 CTestWebBrowser* CTestWebBrowser::NewLC ( CHttpExampleUtils& aUtils )	
       
    80 	{
       
    81 	CTestWebBrowser* me = new (ELeave) CTestWebBrowser ( aUtils );
       
    82 	CleanupStack::PushL ( me );
       
    83 	me->ConstructL ();
       
    84 	return me;
       
    85 	}
       
    86 
       
    87 void CTestWebBrowser::ConstructL ()
       
    88 	{
       
    89 	// Open a HTTP session.
       
    90 	iHttpSession.OpenL ();
       
    91 	
       
    92 	// Install the callback into the session.
       
    93 	InstallAuthenticationL ( iHttpSession );
       
    94 	
       
    95 	iBaseUri = HBufC8::NewL ( KMaxURISize );
       
    96 	}
       
    97 
       
    98 CTestWebBrowser* CTestWebBrowser::NewL ( CHttpExampleUtils& aUtils )	
       
    99 	{
       
   100 	CTestWebBrowser* me = CTestWebBrowser::NewLC ( aUtils );
       
   101 	CleanupStack::Pop ( me );
       
   102 	return me;
       
   103 	}
       
   104 
       
   105 /**
       
   106 	Set HTTP proxy information for the session.
       
   107 	
       
   108 	@param aProxyAddr [in] Proxy address to set for the session
       
   109  */	
       
   110 void CTestWebBrowser::SetProxyL ( const TDesC8& aProxyAddr )
       
   111 	{
       
   112 	
       
   113 	RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo();
       
   114 	
       
   115 	// Set the proxy usage property.
       
   116 	THTTPHdrVal proxyUsage( iHttpSession.StringPool().StringF( HTTP::EUseProxy, RHTTPSession::GetTable() ) );
       
   117 	connInfo.SetPropertyL( iHttpSession.StringPool().StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ), proxyUsage );
       
   118 	
       
   119 	RStringF proxyAddr = iHttpSession.StringPool ().OpenFStringL ( aProxyAddr );
       
   120 	CleanupClosePushL ( proxyAddr );
       
   121 	
       
   122 	// Set the proxy address property.
       
   123 	THTTPHdrVal proxyAddrHdr( proxyAddr );
       
   124     connInfo.SetPropertyL( iHttpSession.StringPool().StringF( HTTP::EProxyAddress, RHTTPSession::GetTable() ), proxyAddrHdr );
       
   125     
       
   126     CleanupStack::PopAndDestroy (); // Pop and destroy proxyAddr
       
   127 	return;		
       
   128 	}
       
   129 
       
   130 /**
       
   131 	Get the credentials from the user.
       
   132 	
       
   133 	@param aURI [in] The URI being requested
       
   134 	@param aRealm [out] The realm being requested
       
   135 	@param aAuthenticationType [out] The type of authentication.
       
   136 	@param aUsername [out] User name
       
   137 	@param aPassword [out] Pass word
       
   138 	
       
   139 	@return TBool ETrue if credentials being returned else EFalse
       
   140  */		
       
   141 TBool CTestWebBrowser::GetCredentialsL( const TUriC8& aURI, 
       
   142 										RString aRealm, 
       
   143 									   	RStringF aAuthenticationType,
       
   144 									   	RString& aUsername, 
       
   145 									   	RString& aPassword )
       
   146 	{
       
   147 	// Convert to 16 bit to display
       
   148 	HBufC* uriDesBuf = HBufC::NewLC( aURI.UriDes().Length() );
       
   149 	TPtr uriDesPtr( uriDesBuf->Des() );
       
   150 	uriDesPtr.Copy( aURI.UriDes() );
       
   151 
       
   152 	HBufC* uriRealmBuf = HBufC::NewLC( aRealm.DesC().Length() );
       
   153 	TPtr uriRealmPtr( uriRealmBuf->Des() );
       
   154 	uriRealmPtr.Copy( aRealm.DesC() );
       
   155 	
       
   156 	HBufC* uriAuthenticationType = HBufC::NewLC ( aAuthenticationType.DesC().Length() );
       
   157 	TPtr uriAuthenticationPtr( uriAuthenticationType->Des() );
       
   158 	uriAuthenticationPtr.Copy ( aAuthenticationType.DesC() );
       
   159 	
       
   160 	
       
   161 	// Prompt user for input
       
   162 	iTestUtils.Test().Printf ( _L( "Enter credentials for URL %S, realm %S\n"), &uriDesPtr, &uriRealmPtr );
       
   163 	iTestUtils.Test().Printf ( _L("Using %S authentication\n"), &uriAuthenticationPtr );
       
   164 	CleanupStack::PopAndDestroy ( 3 ); // Pop and destroy uriDesBuf, uriRealmBuf and uriAuthenticationType
       
   165 	
       
   166 	HBufC* userDetails16 = HBufC::NewLC ( KMaxUserEntrySize );
       
   167 	HBufC8* userDetails8 = HBufC8::NewLC ( KMaxUserEntrySize );
       
   168 	TPtr userDetailsPtr16( userDetails16->Des() );
       
   169 	TPtr8 userDetailsPtr8( userDetails8->Des() );
       
   170 	
       
   171 	iTestUtils.GetAnEntry ( _L( "Username (or QUIT to give up): " ), userDetailsPtr16 );
       
   172 	TBool set = EFalse;
       
   173 	if ( userDetailsPtr16.CompareF ( KQuit ) )
       
   174 		{
       
   175 		userDetailsPtr8.Copy ( userDetailsPtr16 );
       
   176 		aUsername = aRealm.Pool().OpenStringL ( userDetailsPtr8 );
       
   177 		iTestUtils.GetAnEntry( _L( "Password: " ), userDetailsPtr16 );
       
   178 		userDetailsPtr8.Copy ( userDetailsPtr16 );
       
   179 		aPassword = aRealm.Pool().OpenStringL ( userDetailsPtr8 );
       
   180 		set = ETrue;		
       
   181 		}
       
   182 	CleanupStack::PopAndDestroy ( 2 ); // Pop and destroy userDetails16 & userDetails8
       
   183 	return set;	
       
   184 	}
       
   185 
       
   186 /**
       
   187 	Create a new transaction. Generate the full uri from a partial uri.
       
   188 	Also, generates the file path where the contents to be saved. Adds the transaction
       
   189 	object into array.
       
   190 	
       
   191 	@param aUri [in] URI to download.
       
   192 	@param aParseHtml [in] Parse the downloaded HTML content. Default value: EFalse. ETrue value to parse 
       
   193 	the HTML content. Typically the value will be set to ETrue only for the main page.
       
   194  */
       
   195 void CTestWebBrowser::CreateTransactionL ( const TDesC8& aUri, TBool aParseHtml /* = EFalse */ )
       
   196 	{	
       
   197 	TUriParser8 baseUri;	
       
   198 	baseUri.Parse ( iBaseUri->Des() );
       
   199 	
       
   200 	TUriParser8 refUri;
       
   201 	refUri.Parse ( aUri );
       
   202 
       
   203 	// Resolve uri
       
   204 	CUri8* uriPtr = CUri8::ResolveL( baseUri, refUri );	
       
   205 	CleanupStack::PushL ( uriPtr );
       
   206 	
       
   207 	// Generate the file path from the full http uri.	
       
   208 	HBufC* filePath = GenerateFilePathL ( uriPtr->Uri() );
       
   209 	CleanupStack::PushL ( filePath );
       
   210 	
       
   211 	// Create a new HTTP transaction object.
       
   212 	CBrowserTransaction* newTrans = CBrowserTransaction::NewL ( iHttpSession, iTestUtils, this, *filePath, aParseHtml );
       
   213 	CleanupStack::PopAndDestroy ( filePath );
       
   214 	CleanupStack::PushL ( newTrans );
       
   215 	iTransArray.AppendL ( newTrans );
       
   216 	
       
   217 	// Open and submit the transaction.
       
   218 	newTrans->CreateTransactionL ( uriPtr->Uri().UriDes() );
       
   219 	newTrans->StartTransactionL ();
       
   220 	
       
   221 	CleanupStack::Pop ( newTrans ); 
       
   222 	CleanupStack::PopAndDestroy ( uriPtr );
       
   223 	return;		
       
   224 	}
       
   225 
       
   226 /**
       
   227 	To create a new transaction. This function is a calllback called from 
       
   228 	the CHTMLHandler when it finds a new URI to be downloaded.
       
   229 	
       
   230 	@param aUri [in] URI to download.
       
   231  */	
       
   232 void CTestWebBrowser::OnTransactionCreateL ( const TDesC8& aUri, TBool aParseHtml )
       
   233 	{
       
   234 	CreateTransactionL ( aUri, aParseHtml );
       
   235 	return;		
       
   236 	}
       
   237 
       
   238 /**
       
   239 	Delete the transaction. Removes the transaction object from the transaction array
       
   240 	
       
   241 	@param aTrans [out] Transaction object to close.
       
   242  */	
       
   243 void CTestWebBrowser::OnTransactionClose ( CBrowserTransaction* aTrans ) 
       
   244 	{	
       
   245 	// Find the transaction object to be deleted and remove it from the 
       
   246 	// transaction	array.
       
   247 	TInt numTrans = iTransArray.Count ();
       
   248 	for ( TInt i = 0; i < numTrans; ++i )
       
   249 		{
       
   250 		if ( iTransArray[ i ] == aTrans )			
       
   251 			{
       
   252 			delete aTrans;
       
   253 			iTransArray.Remove ( i );
       
   254 			break;
       
   255 			}
       
   256 		}	
       
   257 	
       
   258 	if ( iTransArray.Count () == 0 )
       
   259 		{
       
   260 		// All transactions are completed. 
       
   261 		iCurrentState = ETransactionCompleted;
       
   262 		IssueAndCompleteRequest ();
       
   263 		}
       
   264 	return;		
       
   265 	}
       
   266 
       
   267 /**
       
   268 	Issues a new request if the active object has no outstanding request.
       
   269 	
       
   270  */	
       
   271 void CTestWebBrowser::IssueAndCompleteRequest()
       
   272 	{
       
   273 	if ( !IsActive() )		
       
   274 		{
       
   275 		TRequestStatus* status = &iStatus;
       
   276 		User::RequestComplete( status, KErrNone );
       
   277 		SetActive();
       
   278 		}
       
   279 	}
       
   280 	
       
   281 void CTestWebBrowser::RunL ()
       
   282 	{
       
   283 	
       
   284 	switch ( iCurrentState )
       
   285 		{
       
   286 		case EMainMenu:
       
   287 			iTestUtils.Test().Printf ( _L ( "Main menu") );
       
   288 			ExecuteMainMenuL();
       
   289 			break;
       
   290 		
       
   291 		case EEnterUrl:
       
   292 			AcceptUrlL ();
       
   293 			break;
       
   294 		
       
   295 		case ESelectProxy:
       
   296 			AcceptProxyL ();
       
   297 			break;
       
   298 		
       
   299 		case EStop:		
       
   300 			CActiveScheduler::Stop();
       
   301 			break;
       
   302 		
       
   303 		case EStartTransaction:
       
   304 			{		
       
   305 			CreateTransactionL ( iBaseUri->Des(), ETrue );	
       
   306 			}
       
   307 			break;
       
   308 		
       
   309 		case ETransactionStarted:
       
   310 			{
       
   311 			iTestUtils.Test().Printf ( _L ( "Transaction started. Please wait...") );			
       
   312 			}
       
   313 			break;
       
   314 		
       
   315 		case ETransactionCompleted:
       
   316 			{
       
   317 			OnTransactionCompleted();
       
   318 			}
       
   319 			break;				
       
   320 			
       
   321 		default:
       
   322 			break;
       
   323 		}
       
   324 	}
       
   325 
       
   326 void CTestWebBrowser::DoCancel ()
       
   327 	{
       
   328 	// Do nothing...		
       
   329 	}
       
   330 
       
   331 /**
       
   332 	Checks whether a uri is valid or not. Will check whether the uri contains
       
   333 	scheme, host and path.
       
   334 	
       
   335 	@param aUri [in] URI to validate. Only scheme and host presence is validated.
       
   336 	
       
   337 	@return TBool ETrue if the URI is successfully validated else EFalse.
       
   338  */	
       
   339 TBool CTestWebBrowser::ValidateUri ( const TDesC8& aUri )
       
   340 	{
       
   341 	TUriParser8 uriParser;
       
   342 	if ( uriParser.Parse ( aUri ) != KErrNone )
       
   343 		{
       
   344 		return EFalse;			
       
   345 		}
       
   346 	
       
   347 	// check for scheme
       
   348 	if ( !uriParser.IsPresent ( EUriScheme ) )
       
   349 		{
       
   350 		return EFalse;				
       
   351 		}
       
   352 	
       
   353 	// check for host
       
   354 	if ( !uriParser.IsPresent ( EUriHost) )
       
   355 		{
       
   356 		return EFalse;			
       
   357 		}
       
   358 	return ETrue;				
       
   359 	}
       
   360 
       
   361 /**
       
   362 	Generate the full file path based on the aUri.
       
   363 	
       
   364 	@param aUri [in] Full URI to generate the full file path.
       
   365 	
       
   366 	@return HBufC* Holds the full file path.
       
   367  */	
       
   368 HBufC* CTestWebBrowser::GenerateFilePathL ( const TUriC8& aUri )
       
   369 	{
       
   370 	
       
   371 	HBufC* filePath = HBufC::NewLC ( KMaxFilePathLength );	
       
   372 	TPtr filePtr ( filePath->Des() );	
       
   373 	
       
   374 	// Append the base path
       
   375 	filePtr.Append ( KDirPath ); 
       
   376 	
       
   377 	// Get the full uri.
       
   378 	HBufC* completeUri = aUri.DisplayFormL();
       
   379 	CleanupStack::PushL ( completeUri );
       
   380 	
       
   381 	TPtr ptr = completeUri->Des();
       
   382 	// Chop off the scheme. ( http:// )
       
   383 	ptr.Delete ( 0, KHttpSchemeLength );
       
   384 	
       
   385 	// Reverse the slashes.
       
   386 	ChangePathSeparator ( ptr, '/', '\\' );
       
   387 	
       
   388 	// Replace invalid characters with '_'. Invalid characters: <>:"|* 	
       
   389 	TPtrC ptrInvalidChars ( KInvalidChars );
       
   390 	for ( TInt i = 0; i < KInvalidChars().Length(); ++i )
       
   391 		{
       
   392 		ChangePathSeparator ( ptr, ptrInvalidChars[i], KReplaceChar );					
       
   393 		}
       
   394 	
       
   395 	// Append the URI file path.	
       
   396 	filePtr.Append ( ptr );		
       
   397 	CleanupStack::PopAndDestroy ( completeUri );
       
   398 	
       
   399 	HBufC* uriTail = aUri.GetFileNameL ( EUriFileNameTail );
       
   400 	CleanupStack::PushL ( uriTail );	
       
   401 	
       
   402 	TBool fileExtPresent = uriTail->Des().Length() != 0;
       
   403 	
       
   404 	CleanupStack::PopAndDestroy ( uriTail );
       
   405 			
       
   406 	// Append a '\\' at the end of the completeUri if not present.
       
   407 	TInt len = filePtr.Length();
       
   408 	
       
   409 	if ( ( !fileExtPresent ) && ( len != 0 ) && ( filePtr[ len-1 ] != '\\') )
       
   410 		{
       
   411 		filePtr.Append ( '\\' );		
       
   412 		}
       
   413 
       
   414 	if ( !fileExtPresent )
       
   415 		{
       
   416 		// No file name present in the uri. Set the file name as index.html.		
       
   417 		filePtr.Append ( KDefaultFilePath() );
       
   418 		}	
       
   419 
       
   420 	CleanupStack::Pop ( filePath );
       
   421 	iTestUtils.LogIt ( _L("File Path: %S"), &filePtr );
       
   422 	return filePath;
       
   423 	}
       
   424 		
       
   425 void CTestWebBrowser::ExecuteMainMenuL ()
       
   426 	{
       
   427 	iTestUtils.Test().Console()->ClearScreen ();
       
   428 
       
   429 	iTestUtils.Test().Printf(KSelectOption);		
       
   430 	
       
   431 	
       
   432 	TInt selection = iTestUtils.GetSelection ( KPossibleSelectionsText, KPossibleSelections );	
       
   433 	
       
   434 	switch ( selection )
       
   435 		{
       
   436 		case EDownloadURL:
       
   437 		iCurrentState = EEnterUrl;
       
   438 		break;
       
   439 		
       
   440 		case ESetProxy:
       
   441 		iCurrentState = ESelectProxy;
       
   442 		break;
       
   443 		
       
   444 		case EQuit:
       
   445 		iCurrentState = EStop;
       
   446 		break;
       
   447 		
       
   448 		default:
       
   449 		break;
       
   450 		}
       
   451 		
       
   452 	IssueAndCompleteRequest ();
       
   453 	}
       
   454 
       
   455 /**
       
   456 	Accept the url from the user and validate.
       
   457  */	
       
   458 void CTestWebBrowser::AcceptUrlL ()
       
   459 	{
       
   460 
       
   461 	HBufC* uri = HBufC::NewLC ( KMaxURISize );
       
   462 	TPtr ptr( uri->Des() );
       
   463 	iTestUtils.GetAnEntry ( KEnterUrl, ptr );
       
   464 	if ( iBaseUri->Des().MaxLength() < ptr.Length() )
       
   465 		{
       
   466 		iBaseUri = 	iBaseUri->ReAllocL ( ptr.Length() );
       
   467 		}
       
   468 		
       
   469 	iBaseUri->Des().Copy ( ptr );
       
   470 	
       
   471 	if ( ValidateUri( iBaseUri->Des() ) )
       
   472 		{
       
   473 		iCurrentState = EStartTransaction;
       
   474 		}
       
   475 	else
       
   476 		{
       
   477 		iTestUtils.Test().Printf ( _L("Invalid entry.") );
       
   478 		iTestUtils.PressAnyKey ();			
       
   479 		iCurrentState = EMainMenu;
       
   480 		}	
       
   481 	CleanupStack::PopAndDestroy ( uri );
       
   482 	
       
   483 	IssueAndCompleteRequest ();		
       
   484 	}
       
   485 
       
   486 /**
       
   487 	Accept proxy information from the user.
       
   488  */	
       
   489 void CTestWebBrowser::AcceptProxyL ()
       
   490 	{	
       
   491 	HBufC* proxy16 = HBufC::NewLC ( 128 )		;
       
   492 	TPtr ptr( proxy16->Des() );
       
   493 	iTestUtils.GetAnEntry ( KEnterProxy, ptr );
       
   494 	
       
   495 	HBufC8* proxy8 = HBufC8::NewLC ( ptr.Length() );
       
   496 	proxy8->Des().Copy ( ptr );
       
   497 	
       
   498 	TRAPD ( err, SetProxyL ( proxy8->Des() ) );	
       
   499 	
       
   500 	if ( err != KErrNone )
       
   501 		{
       
   502 		iTestUtils.Test().Printf ( _L ( "Setting of proxy address failed." ) );
       
   503 		}
       
   504 	
       
   505 	iCurrentState = EMainMenu;
       
   506 	IssueAndCompleteRequest ();
       
   507 	}
       
   508 
       
   509 /**
       
   510 	Set the state to EMainMenu and issues a request to be processed by the RunL.	
       
   511  */	
       
   512 void CTestWebBrowser::OnTransactionCompleted ()
       
   513 	{
       
   514 	iTestUtils.Test().Printf ( _L ("Transaction completed.") );
       
   515 	iTestUtils.PressAnyKey();
       
   516 	iCurrentState = EMainMenu;			
       
   517 	IssueAndCompleteRequest ();
       
   518 	}
       
   519 
       
   520