diff -r 000000000000 -r b16258d2340f applayerprotocols/httpexamples/TestWebBrowser/src/testwebbrowser.cpp --- /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 +#include +#include + +#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 (); + } + +