--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httpexamples/TestWebBrowser/src/testwebbrowser.cpp Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,520 @@
+// 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 <e32base.h>
+#include <http.h>
+#include <escapeutils.h>
+
+#include "testwebbrowser.h"
+#include "httpexampleutils.h"
+
+
+const TInt KMaxURISize = 256;
+const TInt KMaxFilePathLength = 512;
+const TInt KHttpSchemeLength = 7;
+
+_LIT ( KDirPath, "c:\\TestWebBrowser\\");
+_LIT ( KDefaultFilePath, "index.html" );
+_LIT ( KQuit, "quit" );
+_LIT ( KSelectOption, " Select an option \n\n" );
+_LIT ( KPossibleSelectionsText, " 1 Download URL \n 2 Set Proxy\n 3 Quit \n" );
+_LIT ( KPossibleSelections,"123" );
+_LIT ( KEnterUrl, "Enter URL: " );
+_LIT ( KEnterProxy, "Enter Proxy Address: " );
+
+// Invalid characters that can appear in a URL. These values must be replaced
+// with a valid character to generate the full file path.
+_LIT ( KInvalidChars, "<>:\"|*?");
+
+const TUint KReplaceChar = '_';
+
+void ChangePathSeparator( TDes& aDesPtr, TUint aPathSeperatorFrom, TUint aPathSeperatorTo )
+ {
+ for( TInt offset = aDesPtr.Length() - 1; offset >= 0; offset-- )
+ {
+ if ( aDesPtr[offset] == aPathSeperatorFrom )
+ {
+ aDesPtr[offset] = TUint16( aPathSeperatorTo );
+ }
+ }
+ }
+
+CTestWebBrowser::CTestWebBrowser ( CHttpExampleUtils& aUtils )
+: CActive ( EPriorityStandard ),
+iTestUtils ( aUtils ),
+iCurrentState ( EMainMenu )
+ {
+ //Add this active object to the active schedeler
+ CActiveScheduler::Add(this);
+ __ASSERT_DEBUG( !IsActive(),User::Panic(_L("Reader"), KErrCorrupt) );
+
+ // Wait for request to be handled.
+ IssueAndCompleteRequest();
+ }
+
+
+CTestWebBrowser::~CTestWebBrowser ()
+ {
+ // Close the HTTP session.
+ iHttpSession.Close();
+
+ iTransArray.ResetAndDestroy ();
+ iTransArray.Close ();
+
+ delete iBaseUri;
+ }
+
+CTestWebBrowser* CTestWebBrowser::NewLC ( CHttpExampleUtils& aUtils )
+ {
+ CTestWebBrowser* me = new (ELeave) CTestWebBrowser ( aUtils );
+ CleanupStack::PushL ( me );
+ me->ConstructL ();
+ return me;
+ }
+
+void CTestWebBrowser::ConstructL ()
+ {
+ // Open a HTTP session.
+ iHttpSession.OpenL ();
+
+ // Install the callback into the session.
+ InstallAuthenticationL ( iHttpSession );
+
+ iBaseUri = HBufC8::NewL ( KMaxURISize );
+ }
+
+CTestWebBrowser* CTestWebBrowser::NewL ( CHttpExampleUtils& aUtils )
+ {
+ CTestWebBrowser* me = CTestWebBrowser::NewLC ( aUtils );
+ CleanupStack::Pop ( me );
+ return me;
+ }
+
+/**
+ Set HTTP proxy information for the session.
+
+ @param aProxyAddr [in] Proxy address to set for the session
+ */
+void CTestWebBrowser::SetProxyL ( const TDesC8& aProxyAddr )
+ {
+
+ RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo();
+
+ // Set the proxy usage property.
+ THTTPHdrVal proxyUsage( iHttpSession.StringPool().StringF( HTTP::EUseProxy, RHTTPSession::GetTable() ) );
+ connInfo.SetPropertyL( iHttpSession.StringPool().StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ), proxyUsage );
+
+ RStringF proxyAddr = iHttpSession.StringPool ().OpenFStringL ( aProxyAddr );
+ CleanupClosePushL ( proxyAddr );
+
+ // Set the proxy address property.
+ THTTPHdrVal proxyAddrHdr( proxyAddr );
+ connInfo.SetPropertyL( iHttpSession.StringPool().StringF( HTTP::EProxyAddress, RHTTPSession::GetTable() ), proxyAddrHdr );
+
+ CleanupStack::PopAndDestroy (); // Pop and destroy proxyAddr
+ return;
+ }
+
+/**
+ Get the credentials from the user.
+
+ @param aURI [in] The URI being requested
+ @param aRealm [out] The realm being requested
+ @param aAuthenticationType [out] The type of authentication.
+ @param aUsername [out] User name
+ @param aPassword [out] Pass word
+
+ @return TBool ETrue if credentials being returned else EFalse
+ */
+TBool CTestWebBrowser::GetCredentialsL( const TUriC8& aURI,
+ RString aRealm,
+ RStringF aAuthenticationType,
+ RString& aUsername,
+ RString& aPassword )
+ {
+ // Convert to 16 bit to display
+ HBufC* uriDesBuf = HBufC::NewLC( aURI.UriDes().Length() );
+ TPtr uriDesPtr( uriDesBuf->Des() );
+ uriDesPtr.Copy( aURI.UriDes() );
+
+ HBufC* uriRealmBuf = HBufC::NewLC( aRealm.DesC().Length() );
+ TPtr uriRealmPtr( uriRealmBuf->Des() );
+ uriRealmPtr.Copy( aRealm.DesC() );
+
+ HBufC* uriAuthenticationType = HBufC::NewLC ( aAuthenticationType.DesC().Length() );
+ TPtr uriAuthenticationPtr( uriAuthenticationType->Des() );
+ uriAuthenticationPtr.Copy ( aAuthenticationType.DesC() );
+
+
+ // Prompt user for input
+ iTestUtils.Test().Printf ( _L( "Enter credentials for URL %S, realm %S\n"), &uriDesPtr, &uriRealmPtr );
+ iTestUtils.Test().Printf ( _L("Using %S authentication\n"), &uriAuthenticationPtr );
+ CleanupStack::PopAndDestroy ( 3 ); // Pop and destroy uriDesBuf, uriRealmBuf and uriAuthenticationType
+
+ HBufC* userDetails16 = HBufC::NewLC ( KMaxUserEntrySize );
+ HBufC8* userDetails8 = HBufC8::NewLC ( KMaxUserEntrySize );
+ TPtr userDetailsPtr16( userDetails16->Des() );
+ TPtr8 userDetailsPtr8( userDetails8->Des() );
+
+ iTestUtils.GetAnEntry ( _L( "Username (or QUIT to give up): " ), userDetailsPtr16 );
+ TBool set = EFalse;
+ if ( userDetailsPtr16.CompareF ( KQuit ) )
+ {
+ userDetailsPtr8.Copy ( userDetailsPtr16 );
+ aUsername = aRealm.Pool().OpenStringL ( userDetailsPtr8 );
+ iTestUtils.GetAnEntry( _L( "Password: " ), userDetailsPtr16 );
+ userDetailsPtr8.Copy ( userDetailsPtr16 );
+ aPassword = aRealm.Pool().OpenStringL ( userDetailsPtr8 );
+ set = ETrue;
+ }
+ CleanupStack::PopAndDestroy ( 2 ); // Pop and destroy userDetails16 & userDetails8
+ return set;
+ }
+
+/**
+ Create a new transaction. Generate the full uri from a partial uri.
+ Also, generates the file path where the contents to be saved. Adds the transaction
+ object into array.
+
+ @param aUri [in] URI to download.
+ @param aParseHtml [in] Parse the downloaded HTML content. Default value: EFalse. ETrue value to parse
+ the HTML content. Typically the value will be set to ETrue only for the main page.
+ */
+void CTestWebBrowser::CreateTransactionL ( const TDesC8& aUri, TBool aParseHtml /* = EFalse */ )
+ {
+ TUriParser8 baseUri;
+ baseUri.Parse ( iBaseUri->Des() );
+
+ TUriParser8 refUri;
+ refUri.Parse ( aUri );
+
+ // Resolve uri
+ CUri8* uriPtr = CUri8::ResolveL( baseUri, refUri );
+ CleanupStack::PushL ( uriPtr );
+
+ // Generate the file path from the full http uri.
+ HBufC* filePath = GenerateFilePathL ( uriPtr->Uri() );
+ CleanupStack::PushL ( filePath );
+
+ // Create a new HTTP transaction object.
+ CBrowserTransaction* newTrans = CBrowserTransaction::NewL ( iHttpSession, iTestUtils, this, *filePath, aParseHtml );
+ CleanupStack::PopAndDestroy ( filePath );
+ CleanupStack::PushL ( newTrans );
+ iTransArray.AppendL ( newTrans );
+
+ // Open and submit the transaction.
+ newTrans->CreateTransactionL ( uriPtr->Uri().UriDes() );
+ newTrans->StartTransactionL ();
+
+ CleanupStack::Pop ( newTrans );
+ CleanupStack::PopAndDestroy ( uriPtr );
+ return;
+ }
+
+/**
+ To create a new transaction. This function is a calllback called from
+ the CHTMLHandler when it finds a new URI to be downloaded.
+
+ @param aUri [in] URI to download.
+ */
+void CTestWebBrowser::OnTransactionCreateL ( const TDesC8& aUri, TBool aParseHtml )
+ {
+ CreateTransactionL ( aUri, aParseHtml );
+ return;
+ }
+
+/**
+ Delete the transaction. Removes the transaction object from the transaction array
+
+ @param aTrans [out] Transaction object to close.
+ */
+void CTestWebBrowser::OnTransactionClose ( CBrowserTransaction* aTrans )
+ {
+ // Find the transaction object to be deleted and remove it from the
+ // transaction array.
+ TInt numTrans = iTransArray.Count ();
+ for ( TInt i = 0; i < numTrans; ++i )
+ {
+ if ( iTransArray[ i ] == aTrans )
+ {
+ delete aTrans;
+ iTransArray.Remove ( i );
+ break;
+ }
+ }
+
+ if ( iTransArray.Count () == 0 )
+ {
+ // All transactions are completed.
+ iCurrentState = ETransactionCompleted;
+ IssueAndCompleteRequest ();
+ }
+ return;
+ }
+
+/**
+ Issues a new request if the active object has no outstanding request.
+
+ */
+void CTestWebBrowser::IssueAndCompleteRequest()
+ {
+ if ( !IsActive() )
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+ }
+
+void CTestWebBrowser::RunL ()
+ {
+
+ switch ( iCurrentState )
+ {
+ case EMainMenu:
+ iTestUtils.Test().Printf ( _L ( "Main menu") );
+ ExecuteMainMenuL();
+ break;
+
+ case EEnterUrl:
+ AcceptUrlL ();
+ break;
+
+ case ESelectProxy:
+ AcceptProxyL ();
+ break;
+
+ case EStop:
+ CActiveScheduler::Stop();
+ break;
+
+ case EStartTransaction:
+ {
+ CreateTransactionL ( iBaseUri->Des(), ETrue );
+ }
+ break;
+
+ case ETransactionStarted:
+ {
+ iTestUtils.Test().Printf ( _L ( "Transaction started. Please wait...") );
+ }
+ break;
+
+ case ETransactionCompleted:
+ {
+ OnTransactionCompleted();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void CTestWebBrowser::DoCancel ()
+ {
+ // Do nothing...
+ }
+
+/**
+ Checks whether a uri is valid or not. Will check whether the uri contains
+ scheme, host and path.
+
+ @param aUri [in] URI to validate. Only scheme and host presence is validated.
+
+ @return TBool ETrue if the URI is successfully validated else EFalse.
+ */
+TBool CTestWebBrowser::ValidateUri ( const TDesC8& aUri )
+ {
+ TUriParser8 uriParser;
+ if ( uriParser.Parse ( aUri ) != KErrNone )
+ {
+ return EFalse;
+ }
+
+ // check for scheme
+ if ( !uriParser.IsPresent ( EUriScheme ) )
+ {
+ return EFalse;
+ }
+
+ // check for host
+ if ( !uriParser.IsPresent ( EUriHost) )
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+/**
+ Generate the full file path based on the aUri.
+
+ @param aUri [in] Full URI to generate the full file path.
+
+ @return HBufC* Holds the full file path.
+ */
+HBufC* CTestWebBrowser::GenerateFilePathL ( const TUriC8& aUri )
+ {
+
+ HBufC* filePath = HBufC::NewLC ( KMaxFilePathLength );
+ TPtr filePtr ( filePath->Des() );
+
+ // Append the base path
+ filePtr.Append ( KDirPath );
+
+ // Get the full uri.
+ HBufC* completeUri = aUri.DisplayFormL();
+ CleanupStack::PushL ( completeUri );
+
+ TPtr ptr = completeUri->Des();
+ // Chop off the scheme. ( http:// )
+ ptr.Delete ( 0, KHttpSchemeLength );
+
+ // Reverse the slashes.
+ ChangePathSeparator ( ptr, '/', '\\' );
+
+ // Replace invalid characters with '_'. Invalid characters: <>:"|*
+ TPtrC ptrInvalidChars ( KInvalidChars );
+ for ( TInt i = 0; i < KInvalidChars().Length(); ++i )
+ {
+ ChangePathSeparator ( ptr, ptrInvalidChars[i], KReplaceChar );
+ }
+
+ // Append the URI file path.
+ filePtr.Append ( ptr );
+ CleanupStack::PopAndDestroy ( completeUri );
+
+ HBufC* uriTail = aUri.GetFileNameL ( EUriFileNameTail );
+ CleanupStack::PushL ( uriTail );
+
+ TBool fileExtPresent = uriTail->Des().Length() != 0;
+
+ CleanupStack::PopAndDestroy ( uriTail );
+
+ // Append a '\\' at the end of the completeUri if not present.
+ TInt len = filePtr.Length();
+
+ if ( ( !fileExtPresent ) && ( len != 0 ) && ( filePtr[ len-1 ] != '\\') )
+ {
+ filePtr.Append ( '\\' );
+ }
+
+ if ( !fileExtPresent )
+ {
+ // No file name present in the uri. Set the file name as index.html.
+ filePtr.Append ( KDefaultFilePath() );
+ }
+
+ CleanupStack::Pop ( filePath );
+ iTestUtils.LogIt ( _L("File Path: %S"), &filePtr );
+ return filePath;
+ }
+
+void CTestWebBrowser::ExecuteMainMenuL ()
+ {
+ iTestUtils.Test().Console()->ClearScreen ();
+
+ iTestUtils.Test().Printf(KSelectOption);
+
+
+ TInt selection = iTestUtils.GetSelection ( KPossibleSelectionsText, KPossibleSelections );
+
+ switch ( selection )
+ {
+ case EDownloadURL:
+ iCurrentState = EEnterUrl;
+ break;
+
+ case ESetProxy:
+ iCurrentState = ESelectProxy;
+ break;
+
+ case EQuit:
+ iCurrentState = EStop;
+ break;
+
+ default:
+ break;
+ }
+
+ IssueAndCompleteRequest ();
+ }
+
+/**
+ Accept the url from the user and validate.
+ */
+void CTestWebBrowser::AcceptUrlL ()
+ {
+
+ HBufC* uri = HBufC::NewLC ( KMaxURISize );
+ TPtr ptr( uri->Des() );
+ iTestUtils.GetAnEntry ( KEnterUrl, ptr );
+ if ( iBaseUri->Des().MaxLength() < ptr.Length() )
+ {
+ iBaseUri = iBaseUri->ReAllocL ( ptr.Length() );
+ }
+
+ iBaseUri->Des().Copy ( ptr );
+
+ if ( ValidateUri( iBaseUri->Des() ) )
+ {
+ iCurrentState = EStartTransaction;
+ }
+ else
+ {
+ iTestUtils.Test().Printf ( _L("Invalid entry.") );
+ iTestUtils.PressAnyKey ();
+ iCurrentState = EMainMenu;
+ }
+ CleanupStack::PopAndDestroy ( uri );
+
+ IssueAndCompleteRequest ();
+ }
+
+/**
+ Accept proxy information from the user.
+ */
+void CTestWebBrowser::AcceptProxyL ()
+ {
+ HBufC* proxy16 = HBufC::NewLC ( 128 ) ;
+ TPtr ptr( proxy16->Des() );
+ iTestUtils.GetAnEntry ( KEnterProxy, ptr );
+
+ HBufC8* proxy8 = HBufC8::NewLC ( ptr.Length() );
+ proxy8->Des().Copy ( ptr );
+
+ TRAPD ( err, SetProxyL ( proxy8->Des() ) );
+
+ if ( err != KErrNone )
+ {
+ iTestUtils.Test().Printf ( _L ( "Setting of proxy address failed." ) );
+ }
+
+ iCurrentState = EMainMenu;
+ IssueAndCompleteRequest ();
+ }
+
+/**
+ Set the state to EMainMenu and issues a request to be processed by the RunL.
+ */
+void CTestWebBrowser::OnTransactionCompleted ()
+ {
+ iTestUtils.Test().Printf ( _L ("Transaction completed.") );
+ iTestUtils.PressAnyKey();
+ iCurrentState = EMainMenu;
+ IssueAndCompleteRequest ();
+ }
+
+