applayerprotocols/httpexamples/httpexampleclient/httpexampleclient.cpp
changeset 0 b16258d2340f
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 // Copyright (c) 2001-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 <uri8.h>
       
    17 #include <e32base.h>
       
    18 #include <http.h>
       
    19 #include <chttpformencoder.h>
       
    20 #include <ssl.h>
       
    21 #include <signed.h>
       
    22 #include "httpexampleclient.h"
       
    23 #include "httpexampleutils.h"
       
    24  
       
    25 
       
    26 // format for output of data/time values
       
    27 _LIT(KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");
       
    28 
       
    29 // Format for hook file name and location for hooks
       
    30 _LIT(KHookFormat, "Z:\\httptest\\%S.esk");
       
    31 _LIT(KHookDir, "C:\\System\\Data\\");
       
    32 
       
    33 _LIT(KEnterProx, "Enter Proxy authority");
       
    34 _LIT(KEnterHook, "Enter Hook name (preface with '-' to delete)");
       
    35 _LIT(KEnterSessId, "Enter Session ID (positive integer or 'none')");
       
    36 
       
    37 
       
    38 /* 	If the file httpexampleclient.txt exists in the root directory of a drive
       
    39 	it will be used to provide default initial values for when setting the URL, 
       
    40 	proxy, etc. The file format is:
       
    41 		[var] = [value]
       
    42 	for example:
       
    43 		PROXY = my.proxy.co.uk:5473
       
    44 		URL = http://www.example.org/dir/file.html
       
    45 	whitespace is ignored.
       
    46 	
       
    47 	Note: these are the the values set at run time, they are merely the default
       
    48 	options presented to the user. In the above example the proxy is not turned
       
    49 	on by default, but the string "my.proxy.co.uk:5473" is presetned as the default
       
    50 	option when the use hits "p", saving them the need to have to type it in. 
       
    51 	*/
       
    52 // Defaults
       
    53 _LIT(KDefaultFileFormat,"%c:\\httpexampleclient.txt");
       
    54 _LIT(KHookString, "HOOK");
       
    55 _LIT(KProxyString, "PROXY");
       
    56 _LIT(KURLString, "URL");
       
    57 _LIT(KSessionIdString, "SESSIONID");
       
    58 _LIT(KNone, "none");
       
    59 _LIT(KSchemeHttps, "https");
       
    60 
       
    61 
       
    62 
       
    63 // File system root
       
    64 _LIT(KFileSystemRoot,"C:\\");
       
    65 
       
    66 // Standard headers used by default
       
    67 _LIT8(KUserAgent, "HTTPExampleClient (1.0)");
       
    68 _LIT8(KAccept, "*/*");
       
    69 
       
    70 _LIT(KHttpExampleClientPanic, "HTTP-EC");
       
    71 
       
    72 enum THttpExampleClientPanics
       
    73 	{
       
    74 	EReqBodySumitBufferNotAllocated,
       
    75 	KBodyWithInvalidSize,
       
    76 	KCouldntNotifyBodyDataPart
       
    77 	};
       
    78 
       
    79 // Size of buffer used when submitting request bodies
       
    80 const TInt KMaxSubmitSize = 1024;
       
    81 const TInt KMaxHeaderNameLen = 32;
       
    82 const TInt KMaxHeaderValueLen = 128;
       
    83 
       
    84 
       
    85 //
       
    86 // Implementation of CHttpClient
       
    87 //
       
    88 
       
    89 
       
    90 // Supplied as the name of the test program to CHttpExampleUtils
       
    91 _LIT(KHttpExampleClientTestName, "HttpExample");
       
    92 
       
    93 CHttpClient::CHttpClient()
       
    94 	: iReqBodySubmitBufferPtr(0,0)
       
    95 	{
       
    96 	// Initial timestamp is time now
       
    97 	ResetTimeElapsed();
       
    98 	}
       
    99 
       
   100 
       
   101 CHttpClient::~CHttpClient()
       
   102 	{
       
   103 	iSess.Close();
       
   104 	iFileServ.Close();
       
   105 	delete iReqBodySubmitBuffer;
       
   106 	delete iTransObs;
       
   107 	delete iFormEncoder;
       
   108 	delete iUtils;
       
   109 	}
       
   110 
       
   111 CHttpClient* CHttpClient::NewLC()
       
   112 	{
       
   113 	CHttpClient* me = new(ELeave) CHttpClient;
       
   114 	CleanupStack::PushL(me);
       
   115 	me->ConstructL();
       
   116 	return me;
       
   117 	}
       
   118 
       
   119 CHttpClient* CHttpClient::NewL()
       
   120 	{
       
   121 	CHttpClient* me = NewLC();
       
   122 	CleanupStack::Pop(me);
       
   123 	return me;
       
   124 	}
       
   125 
       
   126 void CHttpClient::ConstructL()
       
   127 	{
       
   128 	iUtils = CHttpExampleUtils::NewL(KHttpExampleClientTestName);
       
   129 	
       
   130 	// Open the RHTTPSession
       
   131 	iSess.OpenL();
       
   132 
       
   133 	// Install this class as the callback for authentication requests
       
   134 	InstallAuthenticationL(iSess);
       
   135 	
       
   136 	User::LeaveIfError(iFileServ.Connect());
       
   137 	iTransObs = CHttpEventHandler::NewL(*iUtils);
       
   138 	}
       
   139 
       
   140 
       
   141 TBool CHttpClient::ClearHook(TPtrC aHook)
       
   142 	{
       
   143 	TInt err = KErrNone;
       
   144 	if(aHook.Length()!=0)
       
   145 		{
       
   146 		err=iFileServ.Delete(aHook);
       
   147 		}
       
   148 	else if(iHookFileName.Length()>0) 
       
   149 		{
       
   150 		err=iFileServ.Delete(iHookFileName);
       
   151 		if(err==KErrNone) 
       
   152 			{
       
   153 			iHookFileName.Zero();
       
   154 			}
       
   155 		}
       
   156 	if(err == KErrNone)
       
   157 		{
       
   158 		User::InfoPrint(_L("Hook revmoved. Need to restart "));
       
   159 		return ETrue;
       
   160 		}
       
   161 	return EFalse;
       
   162 	}
       
   163 
       
   164 // return true if need to quit
       
   165 void CHttpClient::SetHookL(TDesC& aHook)
       
   166 	{
       
   167 	iHookFileName.Format(KHookFormat, &aHook);
       
   168 	CFileMan* fileMan = CFileMan::NewL(iFileServ);
       
   169 	CleanupStack::PushL(fileMan);
       
   170 	TInt err = fileMan->Copy( iHookFileName, KHookDir, CFileMan::EOverWrite );
       
   171 	if( err != KErrNone && err != KErrNotFound) 
       
   172 		{
       
   173 		User::Leave(err);
       
   174 		}
       
   175 	CleanupStack::PopAndDestroy(fileMan);
       
   176 	User::InfoPrint(_L("Hook installed. Need to restart "));
       
   177 	}
       
   178 
       
   179 // to avoid code bloat
       
   180 #define CHECKVAL(name)  if(var==K ##name##String)	{a##name.Copy(val);}
       
   181 
       
   182 void CHttpClient::SetDefaults(TDes& aURL, TDes& aProxy, TDes& aHook, TDes& aSessionId)
       
   183 	{
       
   184 	TFileName filename;
       
   185 	RFile file;
       
   186 	filename.Format(KDefaultFileFormat, 'C');
       
   187 	TInt err = file.Open(iFileServ, filename, EFileRead);
       
   188 	if(err != KErrNone) 
       
   189 		{
       
   190 		filename.Format(KDefaultFileFormat, 'Z');
       
   191 		err = file.Open(iFileServ, filename, EFileRead);
       
   192 		}
       
   193 	if(err == KErrNone) 
       
   194 		{
       
   195 		TFileText line;
       
   196 		line.Set(file);
       
   197 		TInt err = line.Read(filename);
       
   198 		while(err == KErrNone || err ==KErrTooBig) 
       
   199 			{
       
   200 			filename.Trim();
       
   201 			TInt div = filename.Locate('=');
       
   202 			if(div>0) 
       
   203 				{
       
   204 				TInt i;
       
   205 				for (i=div-1;i>0 && filename[i]==' ';i--);	// ibid
       
   206 				TPtrC var = filename.Left(i+1);
       
   207 				for (i=div+1;i<filename.Length() && filename[i]==' ';i++);	//ibid
       
   208 				TPtrC val = filename.Right(filename.Length()-i);
       
   209 				CHECKVAL(Hook)
       
   210 				else CHECKVAL(Proxy)
       
   211 				else CHECKVAL(URL)
       
   212 				else CHECKVAL(SessionId);	
       
   213 				}
       
   214 			err = line.Read(filename);
       
   215 			}
       
   216 		}
       
   217 		file.Close();
       
   218 	}
       
   219 
       
   220 
       
   221 void CHttpClient::StartClientL()
       
   222 	{
       
   223 
       
   224 	ResetTimeElapsed();
       
   225 	TBuf<256> url;
       
   226 	TBuf<256> prox;
       
   227 	TBuf<256> hook;
       
   228 	TBuf<16> sessid;
       
   229 	SetDefaults(url, prox, hook, sessid);
       
   230 	
       
   231 	RStringPool strP = iSess.StringPool();
       
   232 
       
   233 	// Repeat until user selects quit
       
   234 	TBool done = EFalse;
       
   235 	while (!done)
       
   236 		{
       
   237 		// Get user command from menu
       
   238 		iUtils->Test().Console()->ClearScreen();
       
   239 		_LIT(KSelectOption, " Select an option \n\n");
       
   240 		iUtils->Test().Printf(KSelectOption);
       
   241 		_LIT(KPossibleSelectionsText, " 1 Get \n 2 Post \n 3 Head \n 4 Trace \n 5 Toggle Verbose \n p Set Proxy\n s Set Session ID\n h Set Hook\n 6 Quit \n");
       
   242 		_LIT(KPossibleSelections,"123456psh");
       
   243 		TInt selection = iUtils->GetSelection(KPossibleSelectionsText, KPossibleSelections);
       
   244 		RStringF method;
       
   245 		iHasARequestBody = EFalse;
       
   246 
       
   247 
       
   248 		// Set the method to use and ask for a url
       
   249 		switch (selection)
       
   250 			{
       
   251 		case EGet: 
       
   252 			method = strP.StringF(HTTP::EGET,RHTTPSession::GetTable());
       
   253 			break;
       
   254 		case EPost:
       
   255 			method = strP.StringF(HTTP::EPOST,RHTTPSession::GetTable());
       
   256 			iHasARequestBody = ETrue; 
       
   257 			break;
       
   258 		case EHead: 
       
   259 			method = strP.StringF(HTTP::EHEAD,RHTTPSession::GetTable()); 
       
   260 			break;
       
   261 		case ETrace:
       
   262 			method = strP.StringF(HTTP::ETRACE,RHTTPSession::GetTable()); 
       
   263 			break;
       
   264 		case EToggleVerbosity: 
       
   265 			{
       
   266 			TBool verbose = iTransObs->Verbose();
       
   267 			iTransObs->SetVerbose(!verbose);
       
   268 			if (!verbose)
       
   269 				User::InfoPrint(_L("Verbosity is ON "));
       
   270 			else
       
   271 				User::InfoPrint(_L("Verbosity is OFF"));
       
   272 			}
       
   273 			break;
       
   274 		case EQuit:
       
   275 			done = ETrue;
       
   276 			break;
       
   277 		case EHook:
       
   278 			iUtils->GetAnEntry(KEnterHook, hook);
       
   279 			if(hook.Length() > 0) 
       
   280 				{		
       
   281 				if(hook[0]=='-')
       
   282 					{
       
   283 					hook.Replace(0,1,KHookDir);
       
   284 					hook.Append(_L(".esk"));
       
   285 					done = ClearHook(hook);
       
   286 					}
       
   287 				else 
       
   288 					{
       
   289 					SetHookL(hook);
       
   290 					done = ETrue;
       
   291 					}
       
   292 				}
       
   293 			break;
       
   294 		case ESession:
       
   295 			iUtils->GetAnEntry(KEnterSessId, sessid);
       
   296 			if(sessid.Length() > 0) 
       
   297 				{
       
   298 				TLex number(sessid);
       
   299 				TInt val;
       
   300 				if(number.Val(val)==KErrNone)
       
   301 					{
       
   302 					iSess.ConnectionInfo().SetPropertyL(strP.StringF(HTTP::ESessionId,RHTTPSession::GetTable()), val);
       
   303 					}
       
   304 				else if (sessid==KNone) 
       
   305 					{				
       
   306 					iSess.ConnectionInfo().RemoveProperty(strP.StringF(HTTP::ESessionId,RHTTPSession::GetTable()));
       
   307 					}
       
   308 				}
       
   309 			break;
       
   310 		case EProxy:
       
   311 			iUtils->GetAnEntry(KEnterProx, prox);
       
   312 			if(prox.Length() > 0) 
       
   313 				{
       
   314 			  	  iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), iSess.StringPool().StringF(HTTP::EUseProxy,RHTTPSession::GetTable()));
       
   315 				TBuf8<256> prox8;
       
   316 				prox8.Copy(prox);
       
   317 				 RStringF proxy = iSess.StringPool().OpenFStringL(prox8);
       
   318 				CleanupClosePushL(proxy);
       
   319 				 iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), proxy);
       
   320 				CleanupStack::PopAndDestroy(&proxy);
       
   321 				}
       
   322 			else
       
   323 				{
       
   324 			 	iSess.ConnectionInfo().SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), iSess.StringPool().StringF(HTTP::EDoNotUseProxy,RHTTPSession::GetTable()));
       
   325 				}
       
   326 			break;
       
   327 		default: 
       
   328 			 break;
       
   329 			} 
       
   330 
       
   331 		if (!done && (selection >= 0) && (selection <= 3))
       
   332 			{
       
   333 			// Get the URL
       
   334 			_LIT(KEnterUrl, "Enter Url");
       
   335 			iUtils->GetAnEntry(KEnterUrl, url);
       
   336 			if (url.Length() > 0) // back to main menu if we still have an empty URL
       
   337 				{
       
   338 				// Get a filename to submit as our request body, for methods that need one
       
   339 				if (iHasARequestBody)
       
   340 					{
       
   341 					GetRequestBodyL(method);
       
   342 					}
       
   343 
       
   344 				// Start the method off
       
   345 				TBuf8<256> url8;
       
   346 				url8.Copy(url);
       
   347 				InvokeHttpMethodL(url8, method);
       
   348 				}
       
   349 			else
       
   350 				{
       
   351 				_LIT(KEmptyUrlErrorText, "You must supply a non empty url");
       
   352 				iUtils->Test().Printf(KEmptyUrlErrorText);
       
   353 				User::After(1000000);
       
   354 				}
       
   355 			}
       
   356 
       
   357 		} // while
       
   358 
       
   359 	// End of tests
       
   360 	DisplayTimeElapsed();
       
   361 	iUtils->PressAnyKey();
       
   362 }
       
   363 
       
   364 /** Get the post body data from the user. 
       
   365 The user supplies name and value pairs. These are then encoded as added by CHTTPFormEncoder which acts as a data supplier
       
   366 for this request. This is typically how a form body for a html form submission that uses POST might be constructed.
       
   367 */
       
   368 void CHttpClient::GetPostBodyManuallyL()
       
   369 	{
       
   370 	if (iFormEncoder)
       
   371 		{
       
   372 		delete iFormEncoder;
       
   373 		iFormEncoder = NULL;
       
   374 		}
       
   375 
       
   376 	iFormEncoder = CHTTPFormEncoder::NewL(); 
       
   377 	TBuf<256> name;
       
   378 	TBuf<256> value;
       
   379 	TBuf8<256> name8;
       
   380 	TBuf8<256> value8;
       
   381 	
       
   382 	_LIT(KGetPostName, "Enter Name (END to finish)");
       
   383 	_LIT(KGetPostValue, "Enter Value ");
       
   384 	_LIT(KEnd, "END");
       
   385 	do
       
   386 		{
       
   387 		iUtils->GetAnEntry(KGetPostName, name);
       
   388 		if (name.CompareF(KEnd) != 0)
       
   389 			{
       
   390 			iUtils->GetAnEntry(KGetPostValue, value);
       
   391 			name8.Copy(name);
       
   392 			value8.Copy(value);
       
   393 			iFormEncoder->AddFieldL(name8, value8);
       
   394 			}
       
   395 		}
       
   396 		while (name.CompareF(KEnd) != 0);
       
   397 	}
       
   398 
       
   399 
       
   400 /** Gets the body that you wish to submit when using a POST Method
       
   401 This can be supplied as a file or can be input manually in name,value pairs
       
   402 */
       
   403 void CHttpClient::GetRequestBodyL(RStringF& aMethod)
       
   404 	{
       
   405 	if (aMethod== iSess.StringPool().StringF(HTTP::EPOST,RHTTPSession::GetTable()))
       
   406 		{
       
   407 		// get a post body by file or contruct manually?
       
   408 		_LIT(KConstructPostManually, "\n> Construct Post Manually?  Yes | No ");
       
   409 		_LIT(KYesNo, "YyNn");
       
   410 		TInt selection = iUtils->GetSelection(KConstructPostManually,KYesNo);
       
   411 		if (selection < 2) // 2 is NO
       
   412 			{
       
   413 			iManualPost = ETrue;
       
   414 			GetPostBodyManuallyL();
       
   415 			return;
       
   416 			}
       
   417 		// else carry on as usual and get post data from a file
       
   418 		}
       
   419 
       
   420 	iManualPost = EFalse;
       
   421 	_LIT(KRequestPathPrompt, "Enter path to request body file: ");
       
   422 	iUtils->GetAnEntry(KRequestPathPrompt, iReqBodyFileName);
       
   423 	_LIT(KRequestBodyContentType, "Enter request body content-type: ");
       
   424 	iUtils->GetAnEntry(KRequestBodyContentType, iReqBodyContentType);
       
   425 	iParsedFileName.Set(KFileSystemRoot,&iReqBodyFileName,NULL);
       
   426 
       
   427 	// Check it exists and open a file handle
       
   428 	if (iFileServ.IsValidName(iReqBodyFileName))
       
   429 		{
       
   430 		TInt err= iReqBodyFile.Open(iFileServ, iParsedFileName.FullName(), EFileRead);
       
   431 		if(err!=KErrNone)
       
   432 		   {
       
   433 		   _LIT(KFileNotOpen, "Unable to open a file.\n");
       
   434 		   iUtils->Test().Printf(KFileNotOpen);
       
   435 		   User::Leave(KErrNotFound);			
       
   436 		   } 
       
   437 		delete iReqBodySubmitBuffer;
       
   438 		iReqBodySubmitBuffer = NULL;
       
   439 		iReqBodySubmitBuffer = HBufC8::NewMaxL(KMaxSubmitSize);
       
   440 		iReqBodySubmitBufferPtr.Set(iReqBodySubmitBuffer->Des());
       
   441 		}
       
   442 	else
       
   443 		{
       
   444 		_LIT(KFileNameNotValid, "The specified filename is not valid!.\n");
       
   445 		iUtils->Test().Printf(KFileNameNotValid);
       
   446 		User::Leave(KErrBadName);
       
   447 		}
       
   448 	}
       
   449 
       
   450 TBool CHttpClient::GetNextDataPart(TPtrC8& aDataPart)
       
   451 	{
       
   452 	__ASSERT_DEBUG(iReqBodySubmitBuffer, User::Panic(KHttpExampleClientPanic, EReqBodySumitBufferNotAllocated));
       
   453 	// Read from the request body file
       
   454 	iNoMoreDate = EFalse;
       
   455 	TInt err = iReqBodyFile.Read(iReqBodySubmitBufferPtr);
       
   456 	if (err == KErrNone)
       
   457 		{
       
   458 		aDataPart.Set(iReqBodySubmitBufferPtr);
       
   459 		++iDataChunkCount;
       
   460 		iNoMoreDate = (iReqBodySubmitBufferPtr.Length() == 0);
       
   461 		}
       
   462 	return iNoMoreDate;
       
   463 	}
       
   464 
       
   465 void CHttpClient::ReleaseData()
       
   466 	{
       
   467 	// Clear out the submit buffer
       
   468 	TPtr8 buff = iReqBodySubmitBuffer->Des();
       
   469 	buff.Zero();
       
   470 	if (iNoMoreDate==EFalse)
       
   471 		{
       
   472 		// Notify HTTP of more data available immediately, since it's being read from file
       
   473 		TRAPD(err, iTrans.NotifyNewRequestBodyPartL());
       
   474 		if (err != KErrNone)
       
   475 			User::Panic(KHttpExampleClientPanic, KCouldntNotifyBodyDataPart);
       
   476 		}
       
   477 	}
       
   478 
       
   479 TInt CHttpClient::OverallDataSize()
       
   480 	{
       
   481 	TInt size = 0;
       
   482 	TInt err = iReqBodyFile.Size(size);
       
   483 	if (err < 0)
       
   484 		User::Panic(KHttpExampleClientPanic,KBodyWithInvalidSize);
       
   485 
       
   486 	return size;
       
   487 	}
       
   488 
       
   489 TInt CHttpClient::Reset()
       
   490   {
       
   491   if (iHasARequestBody)
       
   492     {
       
   493     // Reset to beginning of file
       
   494 	TInt pos = 0;
       
   495     iReqBodyFile.Seek(ESeekStart, pos);
       
   496     return KErrNone;
       
   497     }
       
   498   else
       
   499     {
       
   500     return KErrNotSupported;
       
   501     }
       
   502  } 
       
   503 
       
   504 /** Invoke the http method
       
   505 This actually creates the transaction, sets the headers and body and then starts the transaction 
       
   506 */
       
   507 void CHttpClient::InvokeHttpMethodL(const TDesC8& aUri, RStringF aMethod)
       
   508 	{
       
   509 	// Set the protocol, before the first transaction gets started
       
   510 /*	if (iUseWspProtocol)
       
   511 		{
       
   512 		RHTTPConnectionInfo ci = iSess.ConnectionInfo();
       
   513 		ci.SetPropertyL(iSess.StringPool().StringF(HTTP::EProtocol,RHTTPSession::GetTable()),
       
   514 						THTTPHdrVal(iSess.StringPool().StringF(HTTP::EWSP,RHTTPSession::GetTable())));
       
   515 		}*/
       
   516 
       
   517 	iDataChunkCount = 0;
       
   518 	TUriParser8 uri; 
       
   519 	uri.Parse( aUri );
       
   520 	HBufC* scheme = uri.DisplayFormL( EUriScheme );
       
   521 	
       
   522 	iTransObs->SetSecuredHttp( !scheme->CompareF( KSchemeHttps ) );
       
   523 	delete scheme;
       
   524 	
       
   525 	iTrans = iSess.OpenTransactionL(uri, *iTransObs, aMethod);
       
   526 	RHTTPHeaders hdr = iTrans.Request().GetHeaderCollection();
       
   527 
       
   528 	// Add headers appropriate to all methods
       
   529 	SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);
       
   530 	SetHeaderL(hdr, HTTP::EAccept, KAccept);
       
   531 
       
   532 	// Add headers and body data for methods that use request bodies
       
   533 	if (iHasARequestBody)
       
   534 		{
       
   535 		// Content type header
       
   536 		TBuf8<KMaxContentTypeSize> contTypeBuf;
       
   537 		contTypeBuf.Copy(iReqBodyContentType);
       
   538 		RStringF contTypeStr = iSess.StringPool().OpenFStringL(contTypeBuf);
       
   539 		CleanupClosePushL(contTypeStr);
       
   540 		THTTPHdrVal contType(contTypeStr);
       
   541 		hdr.SetFieldL(iSess.StringPool().StringF(HTTP::EContentType,RHTTPSession::GetTable()), contType);
       
   542 		CleanupStack::PopAndDestroy(&contTypeStr);
       
   543 		
       
   544 		MHTTPDataSupplier* dataSupplier = this;
       
   545 		if (iManualPost)
       
   546 			dataSupplier = iFormEncoder;
       
   547 		iTrans.Request().SetBody(*dataSupplier);
       
   548 		}
       
   549     
       
   550 	/*
       
   551 	//Set TimeOut Values
       
   552 	RStringF sendTimeOutProp = iSess.StringPool().StringF(HTTP::ESendTimeOutValue, iSess.GetTable());
       
   553 	THTTPHdrVal sendTimeOutPropValue;
       
   554 	sendTimeOutPropValue.SetInt(10);
       
   555 	iTrans.PropertySet().SetPropertyL(sendTimeOutProp, sendTimeOutPropValue);
       
   556  
       
   557 	RStringF recvTimeOutProp = iSess.StringPool().StringF(HTTP::EReceiveTimeOutValue, iSess.GetTable());
       
   558 	THTTPHdrVal recvTimeOutPropValue;
       
   559 	recvTimeOutPropValue.SetInt(10);
       
   560 	iTrans.PropertySet().SetPropertyL(recvTimeOutProp, recvTimeOutPropValue);
       
   561 	*/
       
   562 
       
   563 	// submit the transaction
       
   564 	iTrans.SubmitL();
       
   565 
       
   566 	// Start the scheduler, once the transaction completes or is cancelled on an error the scheduler will be
       
   567 	// stopped in the event handler
       
   568 	CActiveScheduler::Start();
       
   569 
       
   570 	// all done
       
   571 	iUtils->PressAnyKey();
       
   572 
       
   573 	// close the request body file, if one was opened
       
   574 	if (iHasARequestBody)
       
   575 		iReqBodyFile.Close();
       
   576 	}
       
   577 
       
   578 void CHttpClient::SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue)
       
   579 	{
       
   580 	RStringF valStr = iSess.StringPool().OpenFStringL(aHdrValue);
       
   581 	CleanupClosePushL(valStr);
       
   582 	THTTPHdrVal val(valStr);
       
   583 	aHeaders.SetFieldL(iSess.StringPool().StringF(aHdrField,RHTTPSession::GetTable()), val);
       
   584 	CleanupStack::PopAndDestroy(&valStr); 
       
   585 	}
       
   586 
       
   587 void CHttpClient::ResetTimeElapsed()
       
   588 // Resets timestamp to time now
       
   589 	{
       
   590 	iLastTimeStamp.UniversalTime(); 
       
   591 	}
       
   592 
       
   593 
       
   594 void CHttpClient::DisplayTimeElapsed()
       
   595 // Calculate elapsed time since last measurement, and display
       
   596 	{
       
   597 	TTime timeNow;
       
   598 	timeNow.UniversalTime();
       
   599 	TTimeIntervalMicroSeconds elapsedMicroSec =
       
   600 									timeNow.MicroSecondsFrom(iLastTimeStamp);
       
   601 	iLastTimeStamp = timeNow;
       
   602 	iUtils->Test().Printf(
       
   603 		_L("Time elapsed since last measurement is: %d ms\n"),
       
   604 		elapsedMicroSec.Int64()/1000
       
   605 		);
       
   606 	}
       
   607 
       
   608 
       
   609 /** Called when a authenticated page is requested
       
   610 Asks the user for a username and password that would be appropriate for the url that was
       
   611 supplied.
       
   612 */
       
   613 TBool CHttpClient::GetCredentialsL(const TUriC8& aURI, RString aRealm, 
       
   614 								   RStringF aAuthenticationType,
       
   615 								   RString& aUsername, 
       
   616 								   RString& aPassword)
       
   617 
       
   618 	{
       
   619 	TBuf<KMaxUserEntrySize> scratch;
       
   620 	TBuf8<KMaxUserEntrySize> scratch8;
       
   621 
       
   622 	// Convert to 16 bit to display
       
   623 	HBufC* uriDesBuf = HBufC::NewLC(aURI.UriDes().Length());
       
   624 	TPtr uriDesPtr = uriDesBuf->Des();
       
   625 	uriDesPtr.Copy(aURI.UriDes());
       
   626 
       
   627 	HBufC* uriRealmBuf = HBufC::NewLC(aRealm.DesC().Length());
       
   628 	TPtr uriRealmPtr = uriRealmBuf->Des();
       
   629 	uriRealmPtr.Copy(aRealm.DesC());
       
   630 
       
   631 	// Prompt user for credentials.
       
   632 	iUtils->Test().Printf(_L("Enter credentials for URL %S, realm %S\n"), &uriDesPtr, & uriRealmPtr);
       
   633 
       
   634 	CleanupStack::PopAndDestroy(2, uriDesBuf);
       
   635 
       
   636 	scratch.Copy(aAuthenticationType.DesC());
       
   637 	iUtils->Test().Printf(_L("Using %S authentication\n"), &scratch);
       
   638 	iUtils->GetAnEntry(_L("Username (or QUIT to give up): "), scratch);
       
   639 	scratch8.Copy(scratch);
       
   640 	if (scratch8.CompareF(_L8("quit")))
       
   641 		{
       
   642 		TRAPD(err, aUsername = aRealm.Pool().OpenStringL(scratch8));
       
   643 		if (!err)
       
   644 			{
       
   645 			iUtils->GetAnEntry(_L("Password: "), scratch);
       
   646 			scratch8.Copy(scratch);
       
   647 			TRAP(err, aPassword = aRealm.Pool().OpenStringL(scratch8));
       
   648 			if (!err)
       
   649 				return ETrue;
       
   650 			}
       
   651 		}
       
   652 	return EFalse;
       
   653 	}
       
   654 
       
   655 
       
   656 //
       
   657 // Implementation of class CHttpEventHandler
       
   658 //
       
   659 
       
   660 void CHttpEventHandler::ConstructL()
       
   661 	{
       
   662 	User::LeaveIfError(iFileServ.Connect());
       
   663 	}
       
   664 
       
   665 
       
   666 CHttpEventHandler::CHttpEventHandler(CHttpExampleUtils& aUtils) :
       
   667 	iUtils(aUtils)
       
   668 	{
       
   669 	}
       
   670 
       
   671 
       
   672 CHttpEventHandler::~CHttpEventHandler()
       
   673 	{
       
   674 	iFileServ.Close();
       
   675 	}
       
   676 
       
   677 
       
   678 CHttpEventHandler* CHttpEventHandler::NewLC(CHttpExampleUtils& aUtils)
       
   679 	{
       
   680 	CHttpEventHandler* me = new(ELeave)CHttpEventHandler(aUtils);
       
   681 	CleanupStack::PushL(me);
       
   682 	me->ConstructL();
       
   683 	return me;
       
   684 	}
       
   685 
       
   686 
       
   687 CHttpEventHandler* CHttpEventHandler::NewL(CHttpExampleUtils& aUtils)
       
   688 	{
       
   689 	CHttpEventHandler* me = NewLC(aUtils);
       
   690 	CleanupStack::Pop(me);
       
   691 	return me;
       
   692 	}
       
   693 
       
   694 
       
   695 void CHttpEventHandler::SetVerbose(TBool aVerbose)
       
   696 	{
       
   697 	iVerbose = aVerbose;
       
   698 	}
       
   699 
       
   700 
       
   701 TBool CHttpEventHandler::Verbose() const
       
   702 	{
       
   703 	return iVerbose;
       
   704 	}
       
   705 	
       
   706 void CHttpEventHandler::SetSecuredHttp( TBool aSecuredHttp )
       
   707 	{
       
   708 	iSecuredHttp = aSecuredHttp;
       
   709 	}
       
   710 
       
   711 
       
   712 TBool CHttpEventHandler::SecuredHttp() const
       
   713 	{
       
   714 	return iSecuredHttp;
       
   715 	}
       
   716 
       
   717 
       
   718 void CHttpEventHandler::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   719 	{
       
   720 	switch (aEvent.iStatus)
       
   721 		{
       
   722 		case THTTPEvent::EGotResponseHeaders:
       
   723 			{
       
   724 			// HTTP response headers have been received. We can determine now if there is
       
   725 			// going to be a response body to save.
       
   726 			RHTTPResponse resp = aTransaction.Response();
       
   727 			TInt status = resp.StatusCode();
       
   728 			RStringF statusStr = resp.StatusText();
       
   729 			TBuf<32> statusStr16;
       
   730 			statusStr16.Copy(statusStr.DesC());
       
   731 			iUtils.Test().Printf(_L("Status: %d (%S)\n"), status, &statusStr16);
       
   732 
       
   733 			// Dump the headers if we're being verbose
       
   734 			if (iVerbose)
       
   735 			{
       
   736 				DumpRespHeadersL(aTransaction);
       
   737 				
       
   738 				if ( iSecuredHttp )
       
   739 					{
       
   740 					CheckCertificatesL( aTransaction );
       
   741 					}
       
   742 			}
       
   743 
       
   744 			// Determine if the body will be saved to disk
       
   745 			iSavingResponseBody = EFalse;
       
   746 			TBool cancelling = EFalse;
       
   747 			if (resp.HasBody() && (status >= 200) && (status < 300) && (status != 204))
       
   748 				{
       
   749 				TInt dataSize = resp.Body()->OverallDataSize();
       
   750 				if (dataSize >= 0)
       
   751 					iUtils.Test().Printf(_L("Response body size is %d\n"), dataSize);
       
   752 				else
       
   753 					iUtils.Test().Printf(_L("Response body size is unknown\n"));
       
   754 
       
   755 				TInt selection = iUtils.GetSelection(_L("\n> Save response to disk? Yes | No | Cancel"), _L("YyNnCc"));
       
   756 				iSavingResponseBody = (selection < 2);
       
   757 				cancelling = (selection == 4) || (selection == 5);
       
   758 				}
       
   759 
       
   760 			// If we're cancelling, must do it now..
       
   761 			if (cancelling)
       
   762 				{
       
   763 				iUtils.Test().Printf(_L("\nTransaction Cancelled\n"));
       
   764 				aTransaction.Close();
       
   765 				CActiveScheduler::Stop();
       
   766 				}
       
   767 			else if (iSavingResponseBody) // If we're saving, then open a file handle for the new file
       
   768 				{
       
   769 				iUtils.GetAnEntry(_L("Enter filename including path to save response body"), iRespBodyFileName);
       
   770 				iParsedFileName.Set(KFileSystemRoot,&iRespBodyFileName,NULL);
       
   771 
       
   772 				// Check it exists and open a file handle
       
   773 				TInt valid = iFileServ.IsValidName(iRespBodyFileName);
       
   774 				if (!valid)
       
   775 					{
       
   776 					iUtils.Test().Printf(_L("The specified filename is not valid!.\n"));
       
   777 					iSavingResponseBody = EFalse;
       
   778 					}
       
   779 				else
       
   780 					{
       
   781 					TInt err = iRespBodyFile.Replace(iFileServ,
       
   782 													 iParsedFileName.FullName(),
       
   783 													 EFileWrite|EFileShareExclusive);
       
   784 					if (err)
       
   785 						{
       
   786 						iSavingResponseBody = EFalse;
       
   787 						User::Leave(err);
       
   788 						}
       
   789 					}
       
   790 				}
       
   791 
       
   792 			} break;
       
   793 		case THTTPEvent::EGotResponseBodyData:
       
   794 			{
       
   795 			// Get the body data supplier
       
   796 			iRespBody = aTransaction.Response().Body();
       
   797 
       
   798 			// Some (more) body data has been received (in the HTTP response)
       
   799 			if (iVerbose)
       
   800 				DumpRespBody(aTransaction);
       
   801 			else
       
   802 				iUtils.Test().Printf(_L("*"));
       
   803 
       
   804 			// Append to the output file if we're saving responses
       
   805 			if (iSavingResponseBody)
       
   806 				{
       
   807 				TPtrC8 bodyData;
       
   808 				TBool lastChunk = iRespBody->GetNextDataPart(bodyData);
       
   809 				iRespBodyFile.Write(bodyData);
       
   810 				if (lastChunk)
       
   811 					iRespBodyFile.Close();
       
   812 				}
       
   813 
       
   814 			// Done with that bit of body data
       
   815 			iRespBody->ReleaseData();
       
   816 			} break;
       
   817 		case THTTPEvent::EResponseComplete:
       
   818 			{
       
   819 			// The transaction's response is complete
       
   820 			iUtils.Test().Printf(_L("\nTransaction Complete\n"));
       
   821 			} break;
       
   822 		case THTTPEvent::ESucceeded:
       
   823 			{
       
   824 			iUtils.Test().Printf(_L("Transaction Successful\n"));
       
   825 			aTransaction.Close();
       
   826 			CActiveScheduler::Stop();
       
   827 			} break;
       
   828 		case THTTPEvent::EFailed:
       
   829 			{
       
   830 			iUtils.Test().Printf(_L("Transaction Failed\n"));
       
   831 			aTransaction.Close();
       
   832 			CActiveScheduler::Stop();
       
   833 			} break;
       
   834 		case THTTPEvent::ERedirectedPermanently:
       
   835 			{
       
   836 			iUtils.Test().Printf(_L("Permanent Redirection\n"));
       
   837 			} break;
       
   838 		case THTTPEvent::ERedirectedTemporarily:
       
   839 			{
       
   840 			iUtils.Test().Printf(_L("Temporary Redirection\n"));
       
   841 			} break;
       
   842 		case THTTPEvent::ERedirectRequiresConfirmation:
       
   843  			{
       
   844 			// 301(Moved Permanently), 302(Found) or 307(Temporary Redirect) status is received 
       
   845 			// from a transaction and hence ERedirectRequiresConfirmation is sent by filter
       
   846 			// client has opted to close the transaction
       
   847 			iUtils.Test().Printf(_L("Redirect requires confirmation\n"));
       
   848  			aTransaction.Close();
       
   849  			CActiveScheduler::Stop();
       
   850  			} break;
       
   851 	    case THTTPEvent::EReceiveTimeOut:
       
   852 			{
       
   853 			iUtils.Test().Printf(_L("Receive TimeOut\n"));
       
   854 			}break;
       
   855 		case THTTPEvent::ESendTimeOut:
       
   856 			{
       
   857 			iUtils.Test().Printf(_L("Send TimeOut\n"));
       
   858 			}break;
       
   859 		default:
       
   860 			{
       
   861 			iUtils.Test().Printf(_L("<unrecognised event: %d>\n"), aEvent.iStatus);
       
   862 			// close off the transaction if it's an error
       
   863 			if (aEvent.iStatus < 0)
       
   864 				{
       
   865 				aTransaction.Close();
       
   866 				CActiveScheduler::Stop();
       
   867 				}
       
   868 			} break;
       
   869 		}
       
   870 	}
       
   871 
       
   872 TInt CHttpEventHandler::MHFRunError(TInt aError, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/)
       
   873 	{
       
   874 	iUtils.Test().Printf(_L("MHFRunError fired with error code %d\n"), aError);
       
   875 
       
   876 	return KErrNone;
       
   877 	}
       
   878 
       
   879 
       
   880 void CHttpEventHandler::DumpRespHeadersL(RHTTPTransaction& aTrans)
       
   881 	{
       
   882 	RHTTPResponse resp = aTrans.Response();
       
   883 	RStringPool strP = aTrans.Session().StringPool();
       
   884 	RHTTPHeaders hdr = resp.GetHeaderCollection();
       
   885 	THTTPHdrFieldIter it = hdr.Fields();
       
   886 
       
   887 	TBuf<KMaxHeaderNameLen>  fieldName16;
       
   888 	TBuf<KMaxHeaderValueLen> fieldVal16;
       
   889 
       
   890 	while (it.AtEnd() == EFalse)
       
   891 		{
       
   892 		RStringTokenF fieldName = it();
       
   893 		RStringF fieldNameStr = strP.StringF(fieldName);
       
   894 		THTTPHdrVal fieldVal;
       
   895 		if (hdr.GetField(fieldNameStr,0,fieldVal) == KErrNone)
       
   896 			{
       
   897 			const TDesC8& fieldNameDesC = fieldNameStr.DesC();
       
   898 			fieldName16.Copy(fieldNameDesC.Left(KMaxHeaderNameLen));
       
   899 			switch (fieldVal.Type())
       
   900 				{
       
   901 			case THTTPHdrVal::KTIntVal:
       
   902 				iUtils.Test().Printf(_L("%S: %d\n"), &fieldName16, fieldVal.Int());
       
   903 				break;
       
   904 			case THTTPHdrVal::KStrFVal:
       
   905 				{
       
   906 				RStringF fieldValStr = strP.StringF(fieldVal.StrF());
       
   907 				const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   908 				fieldVal16.Copy(fieldValDesC.Left(KMaxHeaderValueLen));
       
   909 				iUtils.Test().Printf(_L("%S: %S\n"), &fieldName16, &fieldVal16);
       
   910 				}
       
   911 				break;
       
   912 			case THTTPHdrVal::KStrVal:
       
   913 				{
       
   914 				RString fieldValStr = strP.String(fieldVal.Str());
       
   915 				const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   916 				fieldVal16.Copy(fieldValDesC.Left(KMaxHeaderValueLen));
       
   917 				iUtils.Test().Printf(_L("%S: %S\n"), &fieldName16, &fieldVal16);
       
   918 				}
       
   919 				break;
       
   920 			case THTTPHdrVal::KDateVal:
       
   921 				{
       
   922 				TDateTime date = fieldVal.DateTime();
       
   923 				TBuf<40> dateTimeString;
       
   924 				TTime t(date);
       
   925 				t.FormatL(dateTimeString,KDateFormat);
       
   926 
       
   927 				iUtils.Test().Printf(_L("%S: %S\n"), &fieldName16, &dateTimeString);
       
   928 				} 
       
   929 				break;
       
   930 			default:
       
   931 				iUtils.Test().Printf(_L("%S: <unrecognised value type>\n"), &fieldName16);
       
   932 				break;
       
   933 				}
       
   934 
       
   935 			// Display realm for WWW-Authenticate header
       
   936 			RStringF wwwAuth = strP.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
       
   937 			if (fieldNameStr == wwwAuth)
       
   938 				{
       
   939 				// check the auth scheme is 'basic'
       
   940 				RStringF basic = strP.StringF(HTTP::EBasic,RHTTPSession::GetTable());
       
   941 				RStringF realm = strP.StringF(HTTP::ERealm,RHTTPSession::GetTable());
       
   942 				THTTPHdrVal realmVal;
       
   943 				if ((fieldVal.StrF() == basic) && 
       
   944 					(!hdr.GetParam(wwwAuth, realm, realmVal)))
       
   945 					{
       
   946 					RStringF realmValStr = strP.StringF(realmVal.StrF());
       
   947 					fieldVal16.Copy(realmValStr.DesC());
       
   948 					iUtils.Test().Printf(_L("Realm is: %S\n"), &fieldVal16);
       
   949 					}
       
   950 				}
       
   951 			}
       
   952 		++it;
       
   953 		}
       
   954 	}
       
   955 
       
   956 void CHttpEventHandler::DumpRespBody(RHTTPTransaction& aTrans)
       
   957 	{
       
   958 	MHTTPDataSupplier* body = aTrans.Response().Body();
       
   959 	TPtrC8 dataChunk;
       
   960 	TBool isLast = body->GetNextDataPart(dataChunk);
       
   961 	DumpIt(dataChunk);
       
   962 	if (isLast)
       
   963 		iUtils.Test().Printf(_L("Got last data chunk.\n"));
       
   964 	}
       
   965 
       
   966 
       
   967 void CHttpEventHandler::DumpIt(const TDesC8& aData)
       
   968 //Do a formatted dump of binary data
       
   969 	{
       
   970 	// Iterate the supplied block of data in blocks of cols=80 bytes
       
   971 	const TInt cols=16;
       
   972 	TInt pos = 0;
       
   973 	TBuf<KMaxFileName - 2> logLine;
       
   974 	TBuf<KMaxFileName - 2> anEntry;
       
   975 	const TInt dataLength = aData.Length();
       
   976 	while (pos < dataLength)
       
   977 		{
       
   978 		//start-line hexadecimal( a 4 digit number)
       
   979 		anEntry.Format(TRefByValue<const TDesC>_L("%04x : "), pos);
       
   980 		logLine.Append(anEntry);
       
   981 
       
   982 		// Hex output
       
   983 		TInt offset;
       
   984 		for (offset = 0; offset < cols; ++offset)
       
   985 			{
       
   986 			if (pos + offset < aData.Length())
       
   987 				{
       
   988 				TInt nextByte = aData[pos + offset];
       
   989 				anEntry.Format(TRefByValue<const TDesC>_L("%02x "), nextByte);
       
   990 				logLine.Append(anEntry);
       
   991 				}
       
   992 			else
       
   993 				{
       
   994 				//fill the remaining spaces with blanks untill the cols-th Hex number 
       
   995 				anEntry.Format(TRefByValue<const TDesC>_L("   "));
       
   996 				logLine.Append(anEntry);
       
   997 				}
       
   998 			}
       
   999 			anEntry.Format(TRefByValue<const TDesC>_L(": "));
       
  1000 			logLine.Append(anEntry);
       
  1001 
       
  1002 		// Char output
       
  1003 		for (offset = 0; offset < cols; ++offset)
       
  1004 			{
       
  1005 			if (pos + offset < aData.Length())
       
  1006 				{
       
  1007 				TInt nextByte = aData[pos + offset];
       
  1008 				if ((nextByte >= ' ') && (nextByte <= '~'))
       
  1009 					{
       
  1010 					anEntry.Format(TRefByValue<const TDesC>_L("%c"), nextByte);
       
  1011 					logLine.Append(anEntry);
       
  1012 					}
       
  1013 				else
       
  1014 					{
       
  1015 					anEntry.Format(TRefByValue<const TDesC>_L("."));
       
  1016 					logLine.Append(anEntry);
       
  1017 					}
       
  1018 				}
       
  1019 			else
       
  1020 				{
       
  1021 				anEntry.Format(TRefByValue<const TDesC>_L(" "));
       
  1022 				logLine.Append(anEntry);
       
  1023 				}
       
  1024 			}
       
  1025 			iUtils.Test().Printf(TRefByValue<const TDesC>_L("%S\n"), &logLine);	
       
  1026 			logLine.Zero();
       
  1027 
       
  1028 		// Advance to next  byte segment (1 seg= cols)
       
  1029 		pos += cols;
       
  1030 		}
       
  1031 	}
       
  1032 	
       
  1033 	
       
  1034 void CHttpEventHandler::CheckCertificatesL(RHTTPTransaction& aTrans)
       
  1035 	{
       
  1036 	
       
  1037 	if ( aTrans.Session().ServerCert() )
       
  1038 		{
       
  1039 		iUtils.Test().Printf( _L("Session CCertificate found\n") );
       
  1040 		
       
  1041 		const CCertificate* sessTCert;
       
  1042 		sessTCert = aTrans.ServerCert();
       
  1043 		
       
  1044 		if( sessTCert )
       
  1045 			{
       
  1046 			TPtrC8 serialNo8(sessTCert->SerialNumber());
       
  1047 			TBuf<KMaxUserEntrySize> serialNo16;
       
  1048 			serialNo16.Copy(serialNo8);
       
  1049 			HBufC16* issuer(sessTCert->IssuerL());
       
  1050 			iUtils.Test().Printf( _L("Serial No: %S, \n"),&serialNo16 );
       
  1051 			iUtils.Test().Printf( _L("Issuer: %S, "),issuer );
       
  1052 			delete issuer;
       
  1053 			}
       
  1054 		}
       
  1055 	else
       
  1056 		{
       
  1057 		iUtils.Test().Printf( _L("Session CCertificate NULL\n") );
       
  1058 		}
       
  1059 		
       
  1060 	if ( aTrans.ServerCert() )
       
  1061 		{
       
  1062 		iUtils.Test().Printf( _L("Transaction CCertificate found\n") );
       
  1063 		const CCertificate* transTCert;
       
  1064 		transTCert = aTrans.ServerCert();
       
  1065 		
       
  1066 		if( transTCert )
       
  1067 			{
       
  1068 			TPtrC8 serialNo8(transTCert->SerialNumber());
       
  1069 			TBuf<KMaxUserEntrySize> serialNo16;
       
  1070 			serialNo16.Copy(serialNo8);
       
  1071 			HBufC16* issuer(transTCert->IssuerL());
       
  1072 			iUtils.Test().Printf( _L("Serial No: %S, \n"),&serialNo16 );
       
  1073 			iUtils.Test().Printf( _L("Issuer: %S, \n"),issuer );
       
  1074 			delete issuer;
       
  1075 			}
       
  1076 		}
       
  1077 	else
       
  1078 		{
       
  1079 		iUtils.Test().Printf( _L("Transaction CCertificate NULL\n") );
       
  1080 		}
       
  1081 	}
       
  1082 
       
  1083 
       
  1084 //
       
  1085 // Main implementation
       
  1086 //
       
  1087 
       
  1088 LOCAL_D void TestL()
       
  1089 // Create a test object, invoke the tests using it and remove
       
  1090 	{
       
  1091 	// Start C32 and initalize some device drivers. This is necessary when running a test console as these won't 
       
  1092 	// have been started
       
  1093 	CHttpExampleUtils::InitCommsL();
       
  1094 
       
  1095 	// create an active scheduler to use
       
  1096 	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();
       
  1097 	CleanupStack::PushL(scheduler);
       
  1098 	CActiveScheduler::Install(scheduler);
       
  1099 
       
  1100 	// Create and start the client
       
  1101 	CHttpClient* httpCli = CHttpClient::NewLC();
       
  1102 	httpCli->StartClientL();
       
  1103 
       
  1104 	CleanupStack::PopAndDestroy(2); // httpCli, scheduler
       
  1105 	}
       
  1106 
       
  1107 
       
  1108 GLDEF_C TInt E32Main()
       
  1109 // Main program - run the tests within a TRAP harness, reporting any errors that
       
  1110 // occur via the panic mechanism. Test for memory leaks using heap marking.
       
  1111 	{
       
  1112 
       
  1113 	__UHEAP_MARK;
       
  1114 	CTrapCleanup* tc=CTrapCleanup::New();
       
  1115 
       
  1116 	TRAPD(err,TestL());
       
  1117 	if (err!=KErrNone)
       
  1118 		User::Panic(_L("Test failed with error code: %i"), err);
       
  1119 	delete tc;
       
  1120 	__UHEAP_MARKEND;
       
  1121 	return KErrNone;
       
  1122 	}
       
  1123