commands/wget/wget.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // wget.cpp
       
     2 // 
       
     3 // Copyright (c) 2008 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 // TODO: byte-range support
       
    14 
       
    15 #include <commdbconnpref.h>
       
    16 #include <httpstringconstants.h>
       
    17 #include <httperr.h>
       
    18 #include <mhttpdatasupplier.h>
       
    19 #include <rhttpheaders.h>
       
    20 #include <thttphdrfielditer.h>
       
    21 #include <bautils.h>
       
    22 #include "wget.h"
       
    23 
       
    24 using namespace IoUtils;
       
    25 
       
    26 _LIT8(KHttpProtocol,	"HTTP/TCP");
       
    27 _LIT(KDateFormat,		"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");
       
    28 const TInt KMaxHeaderNameLen = 32;
       
    29 const TInt KMaxHeaderValueLen = 128;
       
    30 
       
    31 CCommandBase* CCmdWget::NewLC()
       
    32 	{
       
    33 	CCmdWget* self = new(ELeave) CCmdWget();
       
    34 	CleanupStack::PushL(self);
       
    35 	self->BaseConstructL();
       
    36 	return self;
       
    37 	}
       
    38 
       
    39 CCmdWget::~CCmdWget()
       
    40 	{
       
    41 	delete iUrl;
       
    42 	delete iUsername;
       
    43 	delete iPassword;
       
    44 	if (iSessionIsOpen)
       
    45 		{
       
    46 		iSession.Close(); // closes iTransaction also
       
    47 		}
       
    48 	if (iConnection.SubSessionHandle() > 0)
       
    49 		{
       
    50 		iConnection.Close();
       
    51 		}
       
    52 	if (iSocketServ.Handle() > 0)
       
    53 		{
       
    54 		iSocketServ.Close();
       
    55 		}
       
    56 	if (iLocalFile.SubSessionHandle() > 0)
       
    57 		{
       
    58 		iLocalFile.Flush();
       
    59 		iLocalFile.Close();
       
    60 		}
       
    61 	}
       
    62 
       
    63 CCmdWget::CCmdWget() : CCommandBase(CCommandBase::EManualComplete)
       
    64 	{
       
    65 	}
       
    66 
       
    67 const TDesC& CCmdWget::Name() const
       
    68 	{
       
    69 	_LIT(KName, "wget");
       
    70 	return KName;
       
    71 	}
       
    72 
       
    73 void CCmdWget::DoRunL()
       
    74 	{
       
    75 	// sanity check parameters
       
    76 	if (!iUrl || iUrl->Des().Length() > KMaxName)
       
    77 		{
       
    78 		if (iVerbose)
       
    79 			{
       
    80 			PrintError(KErrArgument, _L("Url not specified or is too large."));
       
    81 			}
       
    82 		User::Leave(KErrArgument);
       
    83 		}		
       
    84 	if ((iUsername && iUsername->Des().Length() > KMaxName) || (iPassword && iPassword->Des().Length() > KMaxName))
       
    85 		{
       
    86 		if (iVerbose)
       
    87 			{
       
    88 			PrintError(KErrArgument, _L("Username or Password is too large."));
       
    89 			}
       
    90 		User::Leave(KErrArgument);
       
    91 		}
       
    92 
       
    93 	if (iUploadFilename.Length())
       
    94 		{
       
    95 		iPostData = ETrue; // Keep this member variable because lots of code assumes it
       
    96 		}
       
    97 
       
    98 	LaunchConnectionL(); // start a connection - KErrNone returned if successfully started or a compatible connection already exists
       
    99 		
       
   100 	if (iPostData)
       
   101 		{
       
   102 		// http post
       
   103 		PrepareUploadFileL();
       
   104 		}
       
   105 	else
       
   106 		{
       
   107 		// http get
       
   108 		PrepareDownloadFileL(); // prep. the local file to receive the downloaded data
       
   109 		}
       
   110 	User::LeaveIfError(iLocalFile.Size(iLocalFileSize));
       
   111 	ConfigureHTTPL(); // setup http session & configure with connection parameters
       
   112 	LaunchHTTPTransactionL(); // launch a http transaction
       
   113 	}
       
   114 
       
   115 void CCmdWget::ArgumentsL(RCommandArgumentList& aArguments)
       
   116 	{
       
   117 	_LIT(KArg1, "url");
       
   118 	aArguments.AppendStringL(iUrl, KArg1);
       
   119 	}
       
   120 
       
   121 void CCmdWget::OptionsL(RCommandOptionList& aOptions)
       
   122 	{
       
   123 	_LIT(KOptContinue, "continue");
       
   124 	aOptions.AppendBoolL(iContinue, KOptContinue);
       
   125 
       
   126 	_LIT(KOptDestinationFilename, "downloadfile");
       
   127 	aOptions.AppendFileNameL(iDestinationFilename, KOptDestinationFilename);
       
   128 
       
   129 	_LIT(KOptSourceFilename, "uploadfile");
       
   130 	aOptions.AppendFileNameL(iUploadFilename, KOptSourceFilename);
       
   131 
       
   132 	_LIT(KOptIapId, "iap");
       
   133 	aOptions.AppendIntL(iIapId, KOptIapId);
       
   134 
       
   135 	_LIT(KOptUsername, "username");
       
   136 	aOptions.AppendStringL(iUsername, KOptUsername);
       
   137 
       
   138 	_LIT(KOptPassword, "password");
       
   139 	aOptions.AppendStringL(iPassword, KOptPassword);
       
   140 	
       
   141 	_LIT(KOptVerbose, "verbose");
       
   142 	aOptions.AppendBoolL(iVerbose, KOptVerbose);
       
   143 	}
       
   144 
       
   145 //
       
   146 // CCmdWget::PrepareDownloadFileL
       
   147 // determine the destination file & path and open a handle to a local file
       
   148 //
       
   149 void CCmdWget::PrepareDownloadFileL()
       
   150 	{
       
   151 	ASSERT(iUrl);
       
   152 	ASSERT(!iPostData);
       
   153 	TFileName fname;
       
   154 	RFs& fs = FsL(); 
       
   155 	fname.Zero();
       
   156 	if (iDestinationFilename.Length() <= 0)
       
   157 		{
       
   158 		// use current path
       
   159 		fname.Append(Env().Pwd());
       
   160 		
       
   161 		// use the same name as the file we're intending to download
       
   162 		TChar dirMarker('/');
       
   163 		TInt mark = iUrl->Des().LocateReverse(dirMarker);
       
   164 		if (mark <= 0)
       
   165 			{
       
   166 			User::Leave(KErrNotFound);
       
   167 			}
       
   168 		fname.Append(iUrl->Des().Mid(++mark)); // increment mark to step over the '/' 
       
   169 		}
       
   170 	else 
       
   171 		{
       
   172 		fname.Copy(iDestinationFilename); // user has specified a local file name
       
   173 		}
       
   174 	if (BaflUtils::FileExists(fs, fname))
       
   175 		{
       
   176 		if (iContinue)
       
   177 			{
       
   178 			// open the file & append any new data to what's already in there
       
   179 			User::LeaveIfError(iLocalFile.Open(fs, fname, EFileShareExclusive));
       
   180 			}
       
   181 		else
       
   182 			{
       
   183 			// open the file & replace old data with new data
       
   184 			User::LeaveIfError(iLocalFile.Replace(fs, fname, EFileShareExclusive));
       
   185 			}
       
   186 		}
       
   187 	else
       
   188 		{
       
   189 		// create the file for the first time
       
   190 		User::LeaveIfError(iLocalFile.Create(fs, fname, EFileShareExclusive));
       
   191 		}
       
   192 	}
       
   193 
       
   194 //
       
   195 // CCmdWget::PrepareUploadFileL
       
   196 // prep. the local file containing data for upload to the web server
       
   197 //
       
   198 void CCmdWget::PrepareUploadFileL()
       
   199 	{
       
   200 	ASSERT(iUrl);
       
   201 	ASSERT(iPostData);
       
   202 	
       
   203 	User::LeaveIfError(iLocalFile.Open(FsL(), iUploadFilename, EFileRead | EFileShareReadersOnly));
       
   204 		
       
   205 	
       
   206 	}
       
   207 
       
   208 //
       
   209 // CCmdWget::LaunchConnectionL
       
   210 // establish a connection to the network
       
   211 //
       
   212 void CCmdWget::LaunchConnectionL()
       
   213 	{
       
   214 	User::LeaveIfError(iSocketServ.Connect());
       
   215 	User::LeaveIfError(iConnection.Open(iSocketServ));
       
   216 	
       
   217 	TInt connError = KErrNone;	
       
   218 	TCommDbConnPref prefs;
       
   219 	if (iIapId > 0)
       
   220 		{
       
   221 		prefs.SetIapId(iIapId);
       
   222 		prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   223 		connError = iConnection.Start(prefs);
       
   224 		}
       
   225 	else
       
   226 		{
       
   227 		connError = iConnection.Start();
       
   228 		}
       
   229 	if (iVerbose && (connError != KErrNone))
       
   230 		{
       
   231 		PrintError(connError, _L("Unable to establish network connection"));
       
   232 		User::Leave(connError);
       
   233 		}	
       
   234 	}
       
   235 
       
   236 //
       
   237 // CCmdWget::ConfigureHTTPL
       
   238 //
       
   239 void CCmdWget::ConfigureHTTPL()
       
   240 	{
       
   241 	iSession.OpenL(KHttpProtocol);
       
   242 	iSessionIsOpen = ETrue;
       
   243 	iSession.SetSessionEventCallback(this);
       
   244 	RStringPool pool = iSession.StringPool();
       
   245 	RHTTPConnectionInfo conInf = iSession.ConnectionInfo();
       
   246 	conInf.SetPropertyL(pool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), THTTPHdrVal(iSocketServ.Handle()));
       
   247 	conInf.SetPropertyL(pool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable()), THTTPHdrVal(reinterpret_cast<TInt> (&iConnection)));
       
   248 	InstallAuthenticationL(iSession);
       
   249 	}
       
   250 
       
   251 //
       
   252 // CCmdWget::LaunchHTTPTransactionL
       
   253 // launches a new http transaction
       
   254 //
       
   255 void CCmdWget::LaunchHTTPTransactionL()
       
   256 	{
       
   257 	// create the transaction
       
   258 	TBuf8<KMaxName> url8;
       
   259 	url8.Copy(iUrl->Des());
       
   260 	TUriParser8 uri;
       
   261 	User::LeaveIfError(uri.Parse(url8));
       
   262 	RStringPool pool = iSession.StringPool();
       
   263 	RStringF method = pool.StringF(HTTP::EGET,RHTTPSession::GetTable());
       
   264 	if (iPostData)
       
   265 		{
       
   266 		method = pool.StringF(HTTP::EPOST,RHTTPSession::GetTable());
       
   267 		}
       
   268 	iTransaction = iSession.OpenTransactionL(uri, *this, method);
       
   269 	
       
   270 	// some transaction configuration is required for posting data
       
   271 	if (iPostData)
       
   272 		{
       
   273 		RHTTPRequest req = iTransaction.Request();
       
   274 		req.SetBody(*this); // ccmdwget to supply the data for posting
       
   275 		THTTPHdrVal length(OverallDataSize());
       
   276 		THTTPHdrVal type(pool.StringF(HTTP::ETextAny, RHTTPSession::GetTable()));
       
   277 		RHTTPHeaders hdr = req.GetHeaderCollection();
       
   278 		hdr.SetFieldL(pool.StringF(HTTP::EContentLength, RHTTPSession::GetTable()), length);
       
   279 		hdr.SetFieldL(pool.StringF(HTTP::EContentType, RHTTPSession::GetTable()), type);
       
   280 		}
       
   281 	
       
   282 	// launch it
       
   283 	iTransaction.SubmitL();	
       
   284 	}
       
   285 
       
   286 //
       
   287 // CCmdWget::GetCredentialsL
       
   288 // request from the underlying HTTP session to provide it with some authentication credentials (if present)
       
   289 //
       
   290 TBool CCmdWget::GetCredentialsL(const TUriC8& /*aURI*/, RString aRealm, RStringF /*aAuthenticationType*/, RString& aUsername, RString& aPassword)
       
   291 	{
       
   292 	TBool present = EFalse;
       
   293 	RStringPool pl = aRealm.Pool();
       
   294 	if (iUsername)
       
   295 		{
       
   296 		present = ETrue;
       
   297 		TBuf8<KMaxName> user;
       
   298 		user.Copy(iUsername->Des());
       
   299 		aUsername = pl.OpenStringL(user);
       
   300 		}
       
   301 	if (iPassword)
       
   302 		{
       
   303 		present = ETrue;
       
   304 		TBuf8<KMaxName> pwd;
       
   305 		pwd.Copy(iPassword->Des());
       
   306 		aPassword = pl.OpenStringL(pwd);
       
   307 		}
       
   308 	return present;
       
   309 	}
       
   310 	
       
   311 //
       
   312 // CCmdWget::MHFSessionRunL
       
   313 // handles any up-calls from the http session
       
   314 //
       
   315 void CCmdWget::MHFSessionRunL(const THTTPSessionEvent& aEvent)
       
   316 	{
       
   317 	switch (aEvent.iStatus)
       
   318 		{
       
   319 		case THTTPSessionEvent::EConnect:
       
   320 			{
       
   321 			if (iVerbose)
       
   322 				{
       
   323 				Printf(_L("HTTP Session Connect\r\n"));
       
   324 				}
       
   325 			}
       
   326 		break;
       
   327 		
       
   328 		case THTTPSessionEvent::EConnectedOK:
       
   329 			{
       
   330 			if (iVerbose)
       
   331 				{
       
   332 				Printf(_L("HTTP Session Connected OK\r\n"));
       
   333 				}
       
   334 			}
       
   335 		break;
       
   336 		
       
   337 		case THTTPSessionEvent::EDisconnect:
       
   338 			{
       
   339 			if (iVerbose)
       
   340 				{
       
   341 				Printf(_L("HTTP Session Disconnect\r\n"));
       
   342 				}
       
   343 			}
       
   344 		break;
       
   345 		
       
   346 		case THTTPSessionEvent::EConnectedWithReducedCapabilities:
       
   347 			{
       
   348 			if (iVerbose)
       
   349 				{
       
   350 				Printf(_L("HTTP Session Connected with reduced capabilities\r\n"));
       
   351 				}
       
   352 			
       
   353 			}
       
   354 		break;
       
   355 
       
   356 		case THTTPSessionEvent::EDisconnected:
       
   357 			{
       
   358 			if (iVerbose)
       
   359 				{
       
   360 				Printf(_L("HTTP Session Disconnected\r\n"));
       
   361 				}
       
   362 			
       
   363 			}
       
   364 		break;
       
   365 
       
   366 		case THTTPSessionEvent::EAuthenticatedOK:
       
   367 			{
       
   368 			if (iVerbose)
       
   369 				{
       
   370 				Printf(_L("HTTP Session Authenticated OK\r\n"));
       
   371 				}
       
   372 			
       
   373 			}
       
   374 		break;
       
   375 
       
   376 		case THTTPSessionEvent::EAuthenticationFailure:
       
   377 			{
       
   378 			if (iVerbose)
       
   379 				{
       
   380 				Printf(_L("HTTP Session Authentication failure\r\n"));
       
   381 				}
       
   382 			
       
   383 			}
       
   384 		break;
       
   385 
       
   386 		case THTTPSessionEvent::EConnectionTimedOut:
       
   387 			{
       
   388 			if (iVerbose)
       
   389 				{
       
   390 				Printf(_L("HTTP Session Connection timed out\r\n"));
       
   391 				}
       
   392 			
       
   393 			}
       
   394 		break;
       
   395 
       
   396 		case THTTPSessionEvent::ENotConnected:
       
   397 			{
       
   398 			if (iVerbose)
       
   399 				{
       
   400 				Printf(_L("HTTP Session Not connected\r\n"));
       
   401 				}
       
   402 			
       
   403 			}
       
   404 		break;
       
   405 
       
   406 		case THTTPSessionEvent::EExceptionInfo:
       
   407 			{
       
   408 			if (iVerbose)
       
   409 				{
       
   410 				Printf(_L("HTTP Session Exception info\r\n"));
       
   411 				}
       
   412 			
       
   413 			}
       
   414 		break;
       
   415 
       
   416 		case THTTPSessionEvent::ERedirected:
       
   417 			{
       
   418 			if (iVerbose)
       
   419 				{
       
   420 				Printf(_L("HTTP Session Redirected\r\n"));
       
   421 				}
       
   422 			
       
   423 			}
       
   424 		break;
       
   425 
       
   426 		case THTTPSessionEvent::EAlreadyConnecting:
       
   427 			{
       
   428 			if (iVerbose)
       
   429 				{
       
   430 				Printf(_L("HTTP Session Already connecting\r\n"));
       
   431 				}
       
   432 			
       
   433 			}
       
   434 		break;
       
   435 
       
   436 		case THTTPSessionEvent::EAlreadyConnected:
       
   437 			{
       
   438 			if (iVerbose)
       
   439 				{
       
   440 				Printf(_L("HTTP Session Already connected\r\n"));
       
   441 				}
       
   442 			
       
   443 			}
       
   444 		break;
       
   445 
       
   446 		case THTTPSessionEvent::EAlreadyDisconnecting:
       
   447 			{
       
   448 			if (iVerbose)
       
   449 				{
       
   450 				Printf(_L("HTTP Session Already disconnecting\r\n"));
       
   451 				}
       
   452 			
       
   453 			}
       
   454 		break;
       
   455 
       
   456 		case THTTPSessionEvent::EAlreadyDisconnected:
       
   457 			{
       
   458 			if (iVerbose)
       
   459 				{
       
   460 				Printf(_L("HTTP Session Already disconnected\r\n"));
       
   461 				}
       
   462 			
       
   463 			}
       
   464 		break;
       
   465 
       
   466 		default:
       
   467 			{
       
   468 			if (iVerbose)
       
   469 				{
       
   470 				Printf(_L("HTTP Session Event unrecgonised\r\n"));
       
   471 				}
       
   472 			}
       
   473 		break;
       
   474 		};
       
   475 	}
       
   476 
       
   477 //
       
   478 // CCmdWget::MHFSessionRunError
       
   479 // handles an error related up-calls 
       
   480 TInt CCmdWget::MHFSessionRunError(TInt aError, const THTTPSessionEvent& /*aEvent*/)
       
   481 	{
       
   482 	if (iVerbose)
       
   483 		{
       
   484 		PrintError(aError, _L("HTTP Session Error"));
       
   485 		}
       
   486 	return KErrNone;
       
   487 	}
       
   488 	
       
   489 //
       
   490 // CCmdWget::MHFRunL
       
   491 // handles any up-calls regarding a current transaction
       
   492 //
       
   493 void CCmdWget::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   494 	{
       
   495 	if (aTransaction.Id() != iTransaction.Id())
       
   496 		{
       
   497 		if (iVerbose)
       
   498 			{
       
   499 			PrintError(KErrUnknown, _L("HTTP Transaction Id is invalid"));
       
   500 			}
       
   501 		User::Leave(KErrUnknown);
       
   502 		}
       
   503 	switch (aEvent.iStatus)
       
   504 		{
       
   505 		case THTTPEvent::EGotResponseHeaders:
       
   506 			{
       
   507 			if (iVerbose)
       
   508 				{
       
   509 				DumpRespHeadersL(aTransaction);
       
   510 				}
       
   511 			}
       
   512 		break;
       
   513 		
       
   514 		case THTTPEvent::EGotResponseBodyData:
       
   515 			{
       
   516 			RHTTPResponse response = aTransaction.Response();
       
   517 			if (iVerbose)
       
   518 				{
       
   519 				Printf(_L("HTTP <%d> received\r\n"), response.StatusCode());
       
   520 				}
       
   521 			switch (response.StatusCode())
       
   522 				{
       
   523 				// informational codes (1xx)
       
   524 				case HTTPStatus::EContinue:
       
   525 				case HTTPStatus::ESwitchingProtocols:
       
   526 				break;
       
   527 				
       
   528 				// successful codes (2xx)
       
   529 				case HTTPStatus::EOk:
       
   530 					{
       
   531 					MHTTPDataSupplier* body = aTransaction.Response().Body();
       
   532 					TPtrC8 data;
       
   533 					TBool last = body->GetNextDataPart(data);
       
   534 					if (!iPostData)
       
   535 						{
       
   536 						User::LeaveIfError(iLocalFile.Write(data));
       
   537 						if (last)
       
   538 							{
       
   539 							iLocalFile.Flush();
       
   540 							}
       
   541 						if (iVerbose)
       
   542 							{
       
   543 							Printf(_L("bytes: %d\r\n"), data.Length());
       
   544 							}
       
   545 						}
       
   546 					else
       
   547 						{
       
   548 						TBuf<512> woop;
       
   549 						woop.Copy(data);
       
   550 						Stdout().Write(woop);
       
   551 						}
       
   552 					body->ReleaseData();
       
   553 					}
       
   554 				break;
       
   555 				
       
   556 				case HTTPStatus::ECreated:
       
   557 				case HTTPStatus::EAccepted:
       
   558 				case HTTPStatus::ENonAuthoritativeInfo:
       
   559 				case HTTPStatus::ENoContent:
       
   560 				case HTTPStatus::EResetContent:
       
   561 				break;
       
   562 				
       
   563 				case HTTPStatus::EPartialContent:
       
   564 					{
       
   565 					// TODO - byte range support
       
   566 					}
       
   567 				break;
       
   568 				
       
   569 				// Redirection codes (3xx)
       
   570 				case HTTPStatus::EMultipleChoices:
       
   571 				case HTTPStatus::EMovedPermanently:
       
   572 				case HTTPStatus::EFound:
       
   573 				case HTTPStatus::ESeeOther:
       
   574 				case HTTPStatus::ENotModified:
       
   575 				case HTTPStatus::EUseProxy:
       
   576 				case HTTPStatus::EUnused:
       
   577 				case HTTPStatus::ETemporaryRedirect:
       
   578 					if (iVerbose)
       
   579 						{
       
   580 						Printf(_L("Redirecting\r\n"));
       
   581 						}
       
   582 					
       
   583 				break;
       
   584 				
       
   585 				// Client error codes (4xx)
       
   586 				case HTTPStatus::EBadRequest:
       
   587 				case HTTPStatus::EUnauthorized:
       
   588 				case HTTPStatus::EPaymentRequired:
       
   589 				case HTTPStatus::EForbidden:
       
   590 				case HTTPStatus::ENotFound:
       
   591 				case HTTPStatus::EMethodNotAllowed:
       
   592 				case HTTPStatus::ENotAcceptable:
       
   593 				case HTTPStatus::EProxyAuthenticationRequired:
       
   594 				case HTTPStatus::ERequestTimeout:
       
   595 				case HTTPStatus::EConflict:
       
   596 				case HTTPStatus::EGone:
       
   597 				case HTTPStatus::ELengthRequired:
       
   598 				case HTTPStatus::EPreconditionFailed:
       
   599 				case HTTPStatus::ERequestEntityTooLarge:
       
   600 				case HTTPStatus::ERequestURITooLong:
       
   601 				case HTTPStatus::EUnsupportedMediaType:
       
   602 				case HTTPStatus::ERequestedRangeNotSatisfiable:
       
   603 				case HTTPStatus::EExpectationFailed:
       
   604 					{
       
   605 					if (iVerbose)
       
   606 						{
       
   607 						PrintError(KErrGeneral, _L("HTTP client error"));
       
   608 						}
       
   609 					Complete(KErrGeneral);
       
   610 					}
       
   611 				break;
       
   612 				
       
   613 				// Server error codes (5xx)
       
   614 				case HTTPStatus::EInternalServerError:
       
   615 				case HTTPStatus::ENotImplemented:
       
   616 				case HTTPStatus::EBadGateway:
       
   617 				case HTTPStatus::EServiceUnavailable:
       
   618 				case HTTPStatus::EGatewayTimeout:
       
   619 				case HTTPStatus::EHTTPVersionNotSupported:
       
   620 					{
       
   621 					if (iVerbose)
       
   622 						{
       
   623 						PrintError(KErrGeneral, _L("HTTP Remote Server Error"));
       
   624 						}
       
   625 					Complete(KErrGeneral);
       
   626 					}
       
   627 				break;
       
   628 
       
   629 				default:
       
   630 					Complete(KErrGeneral);
       
   631 				break;
       
   632 				};
       
   633 			}
       
   634 		break;
       
   635 		
       
   636 		case THTTPEvent::EResponseComplete:
       
   637 			{
       
   638 			if (iVerbose)
       
   639 				{
       
   640 				Printf(_L("HTTP Response complete.\r\n"));
       
   641 				}
       
   642 			}
       
   643 		break;
       
   644 		
       
   645 		case THTTPEvent::ESucceeded:
       
   646 			{
       
   647 			if (iVerbose)
       
   648 				{
       
   649 				Printf(_L("Download transaction complete.\r\n"));
       
   650 				}
       
   651 			Complete(KErrNone);
       
   652 			}
       
   653 		break;
       
   654 		
       
   655 		case THTTPEvent::EFailed:
       
   656 			{
       
   657 			if (iVerbose)
       
   658 				{
       
   659 				Printf(_L("Download transaction failed. Aborting\r\n"));
       
   660 				}
       
   661 			Complete(KErrGeneral);			
       
   662 			}
       
   663 		break;
       
   664 		
       
   665 		case THTTPEvent::ERedirectedPermanently:
       
   666 		case THTTPEvent::ERedirectedTemporarily:
       
   667 			{
       
   668 			if (iVerbose)
       
   669 				{
       
   670 				Printf(_L("Redirecting\r\n"));
       
   671 				}
       
   672 			}
       
   673 		break;
       
   674 		
       
   675 		case THTTPEvent::ERedirectRequiresConfirmation:
       
   676 			{
       
   677 			if (iVerbose)
       
   678 				{
       
   679 				Printf(_L("Redirect requires confirmation. Aborting\r\n"));
       
   680 				}
       
   681 			Complete(KErrAbort);
       
   682 			}
       
   683 		break;
       
   684 		
       
   685 		default:
       
   686 			{
       
   687 			if (iVerbose)
       
   688 				{
       
   689 				Printf(_L("Transaction result: <%d>\r\n"), aEvent.iStatus);
       
   690 				}
       
   691 			if (aEvent.iStatus < 0)
       
   692 				{
       
   693 				Complete(aEvent.iStatus);
       
   694 				}
       
   695 			}
       
   696 		break;
       
   697 		};
       
   698 	}
       
   699 	
       
   700 //
       
   701 // CCmdWget::MHFRunError
       
   702 // handles any error related up-calls from an underlying transaction in progress
       
   703 //
       
   704 TInt CCmdWget::MHFRunError(TInt aError, RHTTPTransaction /* aTransaction */, const THTTPEvent& /* aEvent */)
       
   705 	{
       
   706 	if (iVerbose)
       
   707 		{
       
   708 		PrintError(aError, _L("HTTP Transaction error"));
       
   709 		}
       
   710 	return KErrNone;
       
   711 	}
       
   712 	
       
   713 //
       
   714 // CCmdWget::DumpRespHeadersL
       
   715 // dump the transaction response headers
       
   716 //
       
   717 void CCmdWget::DumpRespHeadersL(RHTTPTransaction& aTransaction)
       
   718 	{
       
   719 	RHTTPResponse resp = aTransaction.Response();
       
   720 	RStringPool strP = aTransaction.Session().StringPool();
       
   721 	RHTTPHeaders hdr = resp.GetHeaderCollection();
       
   722 	THTTPHdrFieldIter it = hdr.Fields();
       
   723 
       
   724 	TBuf<KMaxHeaderNameLen>  fieldName16;
       
   725 	TBuf<KMaxHeaderValueLen> fieldVal16;
       
   726 
       
   727 	while (it.AtEnd() == EFalse)
       
   728 		{
       
   729 		RStringTokenF fieldName = it();
       
   730 		RStringF fieldNameStr = strP.StringF(fieldName);
       
   731 		THTTPHdrVal fieldVal;
       
   732 		if (hdr.GetField(fieldNameStr,0,fieldVal) == KErrNone)
       
   733 			{
       
   734 			const TDesC8& fieldNameDesC = fieldNameStr.DesC();
       
   735 			fieldName16.Copy(fieldNameDesC.Left(KMaxHeaderNameLen));
       
   736 			switch (fieldVal.Type())
       
   737 				{
       
   738 			case THTTPHdrVal::KTIntVal:
       
   739 				Printf(_L("%S: %d\r\n"), &fieldName16, fieldVal.Int());
       
   740 				break;
       
   741 			case THTTPHdrVal::KStrFVal:
       
   742 				{
       
   743 				RStringF fieldValStr = strP.StringF(fieldVal.StrF());
       
   744 				const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   745 				fieldVal16.Copy(fieldValDesC.Left(KMaxHeaderValueLen));
       
   746 				Printf(_L("%S: %S\r\n"), &fieldName16, &fieldVal16);
       
   747 				}
       
   748 				break;
       
   749 			case THTTPHdrVal::KStrVal:
       
   750 				{
       
   751 				RString fieldValStr = strP.String(fieldVal.Str());
       
   752 				const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   753 				fieldVal16.Copy(fieldValDesC.Left(KMaxHeaderValueLen));
       
   754 				Printf(_L("%S: %S\r\n"), &fieldName16, &fieldVal16);
       
   755 				}
       
   756 				break;
       
   757 			case THTTPHdrVal::KDateVal:
       
   758 				{
       
   759 				TDateTime date = fieldVal.DateTime();
       
   760 				TBuf<40> dateTimeString;
       
   761 				TTime t(date);
       
   762 				t.FormatL(dateTimeString,KDateFormat);
       
   763 				Printf(_L("%S: %S\r\n"), &fieldName16, &dateTimeString);
       
   764 				} 
       
   765 				break;
       
   766 			default:
       
   767 				Printf(_L("%S: <unrecognised value type>\r\n"), &fieldName16);
       
   768 				break;
       
   769 				};
       
   770 
       
   771 			// Display realm for WWW-Authenticate header
       
   772 			RStringF wwwAuth = strP.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
       
   773 			if (fieldNameStr == wwwAuth)
       
   774 				{
       
   775 				// check the auth scheme is 'basic'
       
   776 				RStringF basic = strP.StringF(HTTP::EBasic,RHTTPSession::GetTable());
       
   777 				RStringF realm = strP.StringF(HTTP::ERealm,RHTTPSession::GetTable());
       
   778 				THTTPHdrVal realmVal;
       
   779 				if ((fieldVal.StrF() == basic) && 
       
   780 					(!hdr.GetParam(wwwAuth, realm, realmVal)))
       
   781 					{
       
   782 					RStringF realmValStr = strP.StringF(realmVal.StrF());
       
   783 					fieldVal16.Copy(realmValStr.DesC());
       
   784 					Printf(_L("Realm is: %S\r\n"), &fieldVal16);
       
   785 					}
       
   786 				}
       
   787 			}
       
   788 		++it;
       
   789 		}	
       
   790 	}
       
   791 
       
   792 //
       
   793 // MHTTPDataSupplier methods
       
   794 //
       
   795 
       
   796 //
       
   797 // CCmdWget::GetNextDataPart
       
   798 // reads a chunk of data from the source file
       
   799 // 
       
   800 TBool CCmdWget::GetNextDataPart(TPtrC8& aDataPart)
       
   801 	{
       
   802 	ASSERT(iPostData);
       
   803 	ASSERT(iLocalFile.SubSessionHandle() > 0);
       
   804 		
       
   805 	TBool result = EFalse;
       
   806 	
       
   807 	// calc read length
       
   808 	TInt readlength = KDefaultChunkSize;
       
   809 	if ((iLocalFileSize - iLocalBytesRead) < readlength)
       
   810 		{
       
   811 		readlength = iLocalFileSize - iLocalBytesRead;
       
   812 		}
       
   813 	
       
   814 	// if necessary, return previous chunk (per the SDK's MHTTPDataSupplier documentation)
       
   815 	if (!iReleaseDataCalled && (iPrevData.Length() > 0))
       
   816 		{
       
   817 		iReleaseDataCalled = EFalse;
       
   818 		aDataPart.Set(iPrevData);
       
   819 		return result;
       
   820 		}
       
   821 	
       
   822 	// read another chunk of the data & pass it back
       
   823 	TInt error = iLocalFile.Read(iPrevData, readlength);
       
   824 	if (error != KErrNone)
       
   825 		{
       
   826 		if (iVerbose)
       
   827 			{
       
   828 			PrintError(error, _L("Unable to read data from local file."));
       
   829 			}
       
   830 		Complete(error);
       
   831 		return result;
       
   832 		}
       
   833 	aDataPart.Set(iPrevData);
       
   834 	iReleaseDataCalled = EFalse;
       
   835 	iLocalBytesRead += readlength;
       
   836 	if (iLocalBytesRead >= iLocalFileSize)
       
   837 		{
       
   838 		ASSERT((iLocalBytesRead == iLocalFileSize)); // else our math has gone wrong somewhere 
       
   839 		result = ETrue;
       
   840 		}
       
   841 	return result;
       
   842 	}
       
   843 
       
   844 //
       
   845 // CCmdWget::ReleaseData
       
   846 // tell the http transaction we have more data available
       
   847 //
       
   848 void CCmdWget::ReleaseData()
       
   849 	{
       
   850 	ASSERT(iPostData);
       
   851 	iReleaseDataCalled = ETrue;
       
   852 	if ((iLocalFileSize - iLocalBytesRead) > 0)
       
   853 		{
       
   854 		// more data to come
       
   855 		TRAPD(error, iTransaction.NotifyNewRequestBodyPartL());
       
   856 		if (error != KErrNone)
       
   857 			{
       
   858 			if (iVerbose)
       
   859 				{
       
   860 				PrintError(error, _L("Unable to release data."));
       
   861 				}
       
   862 			Complete(error);
       
   863 			}
       
   864 		}
       
   865 	}
       
   866 
       
   867 //
       
   868 // CCmdWget::OverallDataSize
       
   869 // return the total size of the data we're to upload to the server
       
   870 //
       
   871 TInt CCmdWget::OverallDataSize()
       
   872 	{
       
   873 	ASSERT(iPostData);
       
   874 	ASSERT(iLocalFile.SubSessionHandle() > 0);
       
   875 	return iLocalFileSize;
       
   876 	}
       
   877 
       
   878 //
       
   879 // CCmdWget::Reset
       
   880 // Reset the data supply to the beginning of the local file
       
   881 // 
       
   882 TInt CCmdWget::Reset()
       
   883 	{
       
   884 	ASSERT(iPostData);
       
   885 	ASSERT(iLocalFile.SubSessionHandle() > 0);
       
   886 	TInt pos = 0;
       
   887 	TInt error = iLocalFile.Seek(ESeekStart, pos); // not interested in pos
       
   888 	return error;
       
   889 	}
       
   890 
       
   891 
       
   892 EXE_BOILER_PLATE(CCmdWget)