common/tools/ats/smoketest/http/src/testhttpeboclientstep.cpp
changeset 836 675529c38614
child 872 17498133d9ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/tools/ats/smoketest/http/src/testhttpeboclientstep.cpp	Wed Jan 06 13:41:51 2010 +0000
@@ -0,0 +1,542 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Contains implementation of CHttpEboClientStep class
+// @internalAll
+// 
+//
+
+// User Include
+#include "testhttpeboclientstep.h"
+// Additional headers
+#include "CommDbConnPref.h"
+#include "CommDb.h"
+#include "es_sock.h"
+
+// Standard headers used by default
+_LIT8(KUserAgent, "TestHttpEboClient");
+_LIT8(KAccept, "*/*");
+
+/**
+Constructor: Sets the test step name.
+@internalTechnology
+@test
+*/
+CHttpEboClientStep::CHttpEboClientStep()
+	{
+	
+	//Call base class method to set human readable name for test step
+	SetTestStepName(KTestHttpEboClientStep);
+	}
+
+
+/**
+Destructor
+@internalTechnology
+@test
+*/
+CHttpEboClientStep::~CHttpEboClientStep()
+	{
+	}
+
+
+/**
+Sets the proxy and HttpDataOptimiser implemetation to session
+based on the patameter values in ini file and calls InvokeHttpMethodL()
+@internalTechnology
+@test
+@param		None
+@return		None
+*/
+void CHttpEboClientStep::StartClientL()
+	{
+	TPtrC uri;
+	TPtrC proxyPtr;
+	TBool proxyUsage;
+	TPtrC resbodyFilename;
+	TBool sessHttpOptUsage;
+    if (!GetStringFromConfig(ConfigSection(), KIniUri, uri) ||
+        !GetStringFromConfig(ConfigSection(), KIniFileName, resbodyFilename) ||
+	    !GetBoolFromConfig(ConfigSection(), KIniSessProxyUsage, proxyUsage) 
+	   )
+		{
+		ERR_PRINTF4(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n%S\n%S\n"
+					  ),&KIniUri, &KIniFileName, &KIniSessProxyUsage
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	iOutputFilename.Set(resbodyFilename);
+	if (proxyUsage)
+		if(!GetStringFromConfig(ConfigSection(), KIniSessProxy, proxyPtr)
+	      )
+			{
+			ERR_PRINTF2(_L("Problem in reading values from ini.			\
+							\nExpected field is: \n%S\n"
+						  ),&KIniSessProxy
+					   );
+			SetTestStepResult(EFail);
+			return;
+			}
+	RStringPool strP = iSess.StringPool();
+	RStringF method;
+	//setting proxy to session
+	if(proxyUsage)
+		{
+		iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), iSess.StringPool().StringF(HTTP::EUseProxy,RHTTPSession::GetTable()));
+		TBuf8<256> prox8;
+		prox8.Copy(proxyPtr);
+		RStringF proxy = iSess.StringPool().OpenFStringL(prox8);
+		CleanupClosePushL(proxy);
+		iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), proxy);
+		CleanupStack::PopAndDestroy(&proxy);
+		}
+	// Setting HttpDataOptimiser to session
+	if (!GetBoolFromConfig(ConfigSection(), KIniSessHttpOptUsage, sessHttpOptUsage))
+	   	{
+		ERR_PRINTF2(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n"
+					  ),&KIniSessHttpOptUsage
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	if (sessHttpOptUsage)
+		iSess.SetupHttpDataOptimiser(*this);
+	
+	// method
+	method = strP.StringF(HTTP::EGET,RHTTPSession::GetTable());		
+	TBuf8<256> url8;
+	url8.Copy(uri);
+	TRAPD(err,InvokeHttpMethodL(url8, method));
+	if (err != KErrNone)
+		{
+		ERR_PRINTF2(_L("Teststep Failed: Leave occured in CTestHttpBaseStep::InvokeHttpMethodL: %D\n"
+					  ),err
+				   );
+		SetTestStepResult(EFail);
+		}
+	method.Close(); 
+	}
+
+
+/**
+Invoke the http method
+This actually creates the transaction, sets the headers and HttpDataOptimiser implemetation to transaction
+and then starts the transaction 
+@internalTechnology
+@test
+@param		aUri 		Requested uri
+@param		aMethod 	Requested method
+@return		None		
+*/
+void CHttpEboClientStep::InvokeHttpMethodL(const TDesC8& aUri, RStringF aMethod)
+	{
+
+	TBool tranProxyUsage;
+	TBool tranHttpOptUsage;
+	TPtrC tranProxy;
+	TUriParser8 uri; 
+	uri.Parse( aUri );
+
+	//This code has been added by Maciej Seroka to get rid of the access point selection dialog
+
+	// Initialise the socket server session.
+	RSocketServ socketServ;
+	User::LeaveIfError(socketServ.Connect());
+
+	// Initialise the RConnection.
+	RConnection connection;
+	User::LeaveIfError(connection.Open(socketServ));
+		
+	// open the IAP communications database 
+	CCommsDatabase* commDB = CCommsDatabase::NewL(EDatabaseTypeIAP);
+	CleanupStack::PushL(commDB);
+	
+	// initialize a view 
+	CCommsDbConnectionPrefTableView* commDBView = 
+	commDB->OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirectionOutgoing);
+	
+	// go to the first record 
+	User::LeaveIfError(commDBView->GotoFirstRecord());
+
+	// Declare a prefTableView Object.
+	CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref pref;
+	
+	// read the connection preferences 
+	commDBView->ReadConnectionPreferenceL(pref);
+	TUint32 iapID = pref.iBearer.iIapId;
+
+	// pop and destroy the IAP View 
+	CleanupStack::PopAndDestroy(commDBView);
+
+	// pop and destroy the database object
+	CleanupStack::PopAndDestroy(commDB);
+	
+	// Now we have the iap Id. Use it to connect for the connection.
+	// Create a connection preference variable.
+	TCommDbConnPref connectPref;
+
+	// setup preferences 
+	connectPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
+	connectPref.SetDirection(ECommDbConnectionDirectionOutgoing);
+	connectPref.SetBearerSet(ECommDbBearerGPRS);
+	connectPref.SetIapId(iapID);
+
+	// start a synchronous connection
+	TInt errConnect = connection.Start(connectPref);
+	
+	// Then, associate the current socket server session and rconnection object
+	//used above with the HttpSession which u will be using.
+
+	RStringPool strP = iSess.StringPool();
+	RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+	connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketServ,	RHTTPSession::GetTable() ),
+			                   THTTPHdrVal (socketServ.Handle()));
+	TInt connPtr = REINTERPRET_CAST(TInt, &(connection));
+	connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketConnection,
+								RHTTPSession::GetTable() ), 
+								THTTPHdrVal (connPtr) );
+		
+	//and it ends here.
+	
+	
+	// Opening a transaction	
+	iTrans = iSess.OpenTransactionL(uri, *this, aMethod);
+	RHTTPHeaders hdr = iTrans.Request().GetHeaderCollection();
+	// Add headers appropriate to all methods
+	SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);
+	SetHeaderL(hdr, HTTP::EAccept, KAccept);
+	
+	if (!GetBoolFromConfig(ConfigSection(), KIniTranProxyUsage, tranProxyUsage))
+	  	{
+		ERR_PRINTF2(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n"
+					  ),&KIniTranProxyUsage
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	if (tranProxyUsage)
+		if (!GetStringFromConfig(ConfigSection(), KIniTranProxy, tranProxy))
+		    {
+			ERR_PRINTF2(_L("Problem in reading values from ini.			\
+							\nExpected field is: \n%S\n"
+						  ),&KIniTranProxy
+					   );
+			SetTestStepResult(EFail);
+			return;
+			}
+	//setting transaction proxy
+	RHTTPTransactionPropertySet transactionProperties = iTrans.PropertySet();
+//	RStringPool strP = iSess.StringPool();
+	if (tranProxyUsage)
+		{
+		TBuf8<256> tranProx8;
+		tranProx8.Copy(tranProxy);
+		RStringF proxyAddr = strP.OpenFStringL(tranProx8);
+		CleanupClosePushL(proxyAddr);
+		THTTPHdrVal proxyUsage(strP.StringF(HTTP::EUseProxy, RHTTPSession::GetTable()));
+		transactionProperties.SetPropertyL(strP.StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), proxyUsage);
+		transactionProperties.SetPropertyL(strP.StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), proxyAddr);
+		CleanupStack::PopAndDestroy(1,&proxyAddr);
+		}
+	
+	// Setting HttpDataOptimiser for transaction.
+	if (!GetBoolFromConfig(ConfigSection(), KIniTranHttpOptUsage, tranHttpOptUsage))
+	  	{
+		ERR_PRINTF2(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n"
+					  ),&KIniTranHttpOptUsage
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	if (tranHttpOptUsage)
+		iTrans.SetupHttpDataOptimiser(*this);
+	// submit the transaction
+	iTrans.SubmitL();
+	// Start the scheduler, once the transaction completes or is cancelled on an error the scheduler will be
+	// stopped in the event handler
+	CActiveScheduler::Start();
+	}
+
+
+/**
+This is the implementation of interface method MHttpDataOptimiser::MHFRunL
+If there is a reponse body it will be copied to a file.
+Just printing the fired events to the log file.
+@internalTechnology 
+@test
+@param		aTransaction Transaction which is being processed currently
+@param      THTTPEvent Event for which it is called
+@return		None
+*/	
+void CHttpEboClientStep::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
+	{
+	switch (aEvent.iStatus)
+		{
+		case THTTPEvent::EGotResponseHeaders:
+			{
+			// HTTP response headers have been received. We can determine now if there is
+			// going to be a response body to save.
+			RHTTPResponse resp = aTransaction.Response();
+			TInt status = resp.StatusCode();
+			RStringF statusStr = resp.StatusText();
+			TBuf<32> statusStr16;
+			statusStr16.Copy(statusStr.DesC());
+			INFO_PRINTF3(_L("Status: %D (%S)\n"),status, &statusStr16);
+            // Determine if the body will be saved to disk
+			iSavingResponseBody = EFalse;
+			if (resp.HasBody() && (status >= 200) && (status < 300) && (status != 204))
+				{
+				TInt dataSize = resp.Body()->OverallDataSize();
+				if (dataSize >= 0)
+					INFO_PRINTF2(_L("Response body size is %d\n"), dataSize);
+				else
+					INFO_PRINTF1(_L("Response body size is unknown\n"));
+				
+				// Save response to file in disk.
+				iSavingResponseBody = ETrue;
+				}
+
+			    if (iSavingResponseBody) // If we're saving, then open a file handle for the new file
+				{
+				// Check it exists and open a file handle
+				TInt valid = iFileServ.IsValidName(iOutputFilename);
+				if (!valid)
+					{
+					ERR_PRINTF1(_L("The specified filename is not valid!.\n"));
+					iSavingResponseBody = EFalse;
+					}
+				else
+					{
+					TInt err = iRespBodyFile.Replace(iFileServ,
+													 iOutputFilename,
+													 EFileWrite|EFileShareExclusive);
+					if (err)
+						{
+						iSavingResponseBody = EFalse;
+						User::Leave(err);
+						}
+					}
+				}
+            
+			} break;
+		case THTTPEvent::EGotResponseBodyData:
+			{
+			// Get the body data supplier
+			iRespBody = aTransaction.Response().Body();
+
+			// Append to the output file if we're saving responses
+			if (iSavingResponseBody)
+				{
+				INFO_PRINTF1(_L("Saving response body...\n"));
+				TPtrC8 bodyData;
+				TBool lastChunk = iRespBody->GetNextDataPart(bodyData);
+				iRespBodyFile.Write(bodyData);
+				if (lastChunk)
+					iRespBodyFile.Close();
+				}
+
+			// Done with that bit of body data
+			iRespBody->ReleaseData();
+			} break;
+		case THTTPEvent::EResponseComplete:
+			{
+			// The transaction's response is complete
+			INFO_PRINTF1(_L("\nTransaction Complete\n"));
+			} break;
+		case KErrHttpOptimiserFailsTrans:
+			{
+			INFO_PRINTF1(_L("Cancelling/Failing Transaction\n"));
+			aTransaction.Fail(THTTPFilterHandle::EProtocolHandler);
+			//CActiveScheduler::Stop();
+			} break;
+		case THTTPEvent::ESucceeded:
+			{
+			INFO_PRINTF1(_L("Transaction Successful\n"));
+			aTransaction.Close();
+			CActiveScheduler::Stop();
+			} break;
+		case THTTPEvent::EFailed:
+			{
+			INFO_PRINTF1(_L("Transaction Failed\n"));
+			aTransaction.Close();
+			CActiveScheduler::Stop();
+			//Line added to fail the test if no connection to a web server
+			SetTestStepResult(EFail);
+			} break;
+		case THTTPEvent::ERedirectedPermanently:
+			{
+			INFO_PRINTF1(_L("Permanent Redirection\n"));
+			} break;
+		case THTTPEvent::ERedirectedTemporarily:
+			{
+			INFO_PRINTF1(_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
+			INFO_PRINTF1(_L("Redirect requires confirmation\n"));
+ 			aTransaction.Close();
+ 			CActiveScheduler::Stop();
+ 			} break;
+		default:
+			{
+			INFO_PRINTF2(_L("<unrecognised event: %D>\n"), aEvent.iStatus);
+			// close off the transaction if it's an error
+			if (aEvent.iStatus < 0)
+				{
+				aTransaction.Close();
+				CActiveScheduler::Stop();
+				}
+			//Line added to fail the test if no connection to a web server
+			SetTestStepResult(EFail);
+			} break;
+		}
+	}
+
+
+/**
+This is the implementation of interface method MHttpDataOptimiser::MHFRunError
+@internalTechnology 
+@test
+@param		aError  Error which has been raised.	
+@param		aTransaction Transaction which is being processed currently
+@param      THTTPEvent Event which it is being handled currently.
+@return		None
+*/
+TInt CHttpEboClientStep::MHFRunError(TInt aError, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/)
+	{
+	INFO_PRINTF2(_L("MHFRunError fired with error code %D\n"), aError);
+	return KErrNone;
+	}
+
+
+/**
+It enocodes the request data.
+@internalTechnology 
+@test
+@param		aHttpData  Actual request.
+@param		aEncodedData Encoded request.
+@return		None
+*/
+void CHttpEboClientStep::EncodeL (const TDesC8& /*aHttpData*/, HBufC8* &aEncodedData)
+	{
+	
+	INFO_PRINTF1(_L("######## CHttpEboClientStep::EncodeL ########\n"));
+	TBool isEncoded;
+	if (!GetBoolFromConfig(ConfigSection(), KIniIsEncoded, isEncoded))
+	  	{
+		ERR_PRINTF2(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n"
+					  ),&KIniIsEncoded
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	// Checking whether enocoding is needed.
+	if (isEncoded)
+		{
+		// Encoding: Changing the request data to http://www.google.co.uk/
+		_LIT8(KTestRequest, "GET http://www.google.co.uk/ HTTP/1.1\r\nHost: www.google.co.uk\r\nAccept: */*\r\nUser-Agent: TestHttpEboClient\r\n\r\n");
+		const TDesC8& encodedReq(KTestRequest);
+		TRAPD(err,
+			{
+			aEncodedData =  encodedReq.AllocLC();
+			CleanupStack::Pop();
+			});	
+		if (err != KErrNone)
+			{
+			ERR_PRINTF2(_L("Test step failed: Leave occured while encoding the request: %D\n"), err);
+       	    SetTestStepResult(EFail);
+			}
+		else
+			{
+			INFO_PRINTF1(_L("Encoded/Changed the request\n"));
+			}
+		}
+	else
+		INFO_PRINTF1(_L("Not encoding the request [passing NULL]\n"));	
+	}
+
+	
+/**
+It decodes the responsing data before parsing.
+@internalTechnology 
+@test
+@param		aHttpData  Actual response.
+@param		aEncodedData Decoded response.
+@return		None
+*/
+void CHttpEboClientStep::DecodeL (const TDesC8& aData, HBufC8*& aHttpData, TBool& aTransFail)
+	{
+	INFO_PRINTF1(_L("######## CHttpEboClientStep::DecodeL ########\n"));
+	TBool isDecoded;
+	TBool failTransaction;
+	if (!GetBoolFromConfig(ConfigSection(), KIniIsDecoded, isDecoded))
+	  	{
+		ERR_PRINTF2(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n"
+					  ),&KIniIsDecoded
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	// Checking whether decoding is needed.
+	if (isDecoded)
+		{
+		TRAPD(err, 
+			{
+			// Copying same actual response to decoded response
+			aHttpData = aData.AllocLC();
+			CleanupStack::Pop();	
+			});
+		if (err != KErrNone)
+			{
+			ERR_PRINTF2(_L("Test step failed: Leave occured while decoding the response: %D\n"), err);
+       	    SetTestStepResult(EFail);
+			}
+		else
+			{
+			INFO_PRINTF1(_L("Sent the actual response as a decoded response\n"));
+			}
+		}
+	else
+		INFO_PRINTF1(_L("Not decoding the response [passing NULL]\n"));
+	
+	if(!GetBoolFromConfig(ConfigSection(), KIniFailTransaction, failTransaction))
+	  	{
+		ERR_PRINTF2(_L("Problem in reading values from ini.			\
+						\nExpected fields are: \n%S\n"
+					  ),&KIniFailTransaction
+				   );
+		SetTestStepResult(EFail);
+		return;
+		}
+	// Checking to fail the transaction.
+	if (failTransaction)
+		{
+		aTransFail = ETrue;
+		INFO_PRINTF1(_L("CHttpEboClientStep::DecodeL returing ETrue(intend to fail the transaction)\n"));	
+		}
+	else
+		{
+		aTransFail = EFalse;	
+		INFO_PRINTF1(_L("CHttpEboClientStep::DecodeL returing EFalse(not failing the transaction)\n"));	
+		}
+	}