src/HttpClient.cpp
changeset 0 0049171ecffb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HttpClient.cpp	Fri Jul 24 08:46:02 2009 +0100
@@ -0,0 +1,278 @@
+/*
+ ============================================================================
+ Name	: HttpClient.cpp
+ Author	: John Kern
+ 
+ Copyright (c) 2009 Symbian Foundation Ltd
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ - Symbian Foundation Ltd - initial contribution.
+ 
+ Contributors:
+ - John Kern
+ - Symsource
+ 
+ Description : Web client 
+ ============================================================================
+ */
+
+#include <activeapdb.h>
+#include <HttpStringConstants.h>  // HTTP
+
+#include "HttpClient.h"
+
+// HTTP header values
+_LIT8(KUserAgent, "NPR 1.0");		// Name of the client app.
+_LIT8(KAccept, "text/*");	// Accept any (but only) text content (errors may not be sent as "text/x-visto-ota-activation").
+
+CHttpClient* CHttpClient::NewL(MHTTPObserver& aObserver)
+	{
+	CHttpClient* self = new (ELeave)CHttpClient(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CHttpClient::CHttpClient(MHTTPObserver& aObserver)
+	:iObserver(aObserver)
+	{
+	}
+
+CHttpClient::~CHttpClient()
+	{
+	if (iTransactionActive)
+		{
+		iHttpTransaction.Cancel();
+		iTransactionActive = EFalse;
+		}
+
+	iHTTPSession.Close();
+	iConnection.Close();
+	iSocketServ.Close();
+	delete iResponseBuffer;
+	delete iUri;
+	}
+
+void CHttpClient::ConstructL()
+	{
+	// Open the Http session
+	iHTTPSession.OpenL();
+    User::LeaveIfError(iSocketServ.Connect());
+    User::LeaveIfError(iConnection.Open(iSocketServ));
+    User::LeaveIfError(iConnection.Start());
+	}
+
+
+void CHttpClient::SendRequestL(const TDesC& aUri)
+	{
+	if(iUri)
+		{
+		delete iUri;
+		iUri = NULL;
+		}
+	
+	iUri = HBufC8::NewL(aUri.Length());
+	TPtr8 uriPtr = iUri->Des();
+	uriPtr.Copy(aUri);
+
+	TUriParser8 uriParser;
+	User::LeaveIfError(uriParser.Parse(uriPtr));
+	
+	TBuf8<256> buf;
+	buf.Copy(uriParser.UriDes());
+			
+	RStringPool strPool = iHTTPSession.StringPool();
+	iHttpConnInfo = iHTTPSession.ConnectionInfo();
+	iHttpConnInfo.SetPropertyL(strPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable() ), THTTPHdrVal(iSocketServ.Handle()));
+	iHttpConnInfo.SetPropertyL(strPool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ),THTTPHdrVal (REINTERPRET_CAST(TInt, &(iConnection))));
+	
+	if(iTransactionActive)
+		{
+		iHttpTransaction.Cancel();
+		iHttpTransaction.Close();
+		iTransactionActive = EFalse;
+		}
+
+	// Create transaction
+	iHttpTransaction = iHTTPSession.OpenTransactionL(
+		uriParser, 
+		*this,
+		iHTTPSession.StringPool().StringF(HTTP::EPOST, RHTTPSession::GetTable()));
+	iTransactionActive = ETrue;
+	
+	
+	// Set transaction headers.
+	RHTTPHeaders headers = iHttpTransaction.Request().GetHeaderCollection();
+	AddHeaderL(headers, HTTP::EUserAgent, KUserAgent);
+	AddHeaderL(headers, HTTP::EAccept, KAccept);
+	
+	// Delete any previous response.
+	delete iResponseBuffer;
+	iResponseBuffer = NULL;
+	
+	// Set the body.
+	iHttpTransaction.Request().SetBody(*this);
+	
+	// Submit the request
+	iHttpTransaction.SubmitL();
+	}
+
+/**
+* Add a header to a header set
+*
+* @param aHeaders The header set to be modified
+* @param aHeaderField The name of the header to be added
+* @param aHeaderValue The value for the header to be added
+*/
+void CHttpClient::AddHeaderL(RHTTPHeaders aHeaders,
+								TInt aHeaderField,
+								const TDesC8& aHeaderValue)
+	{
+	RStringPool stringPool = iHTTPSession.StringPool();	// Do not close this session here.
+	RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
+	CleanupClosePushL(valStr);
+	THTTPHdrVal headerVal(valStr);
+	aHeaders.SetFieldL(stringPool.StringF(aHeaderField, RHTTPSession::GetTable()), headerVal);
+	CleanupStack::PopAndDestroy();	// valStr
+	}
+
+/**
+ * Add a header to a header set
+ *
+ * @param aHeaders The header set to be modified
+ * @param aHeaderField The name of the header to be added
+ * @param aHeaderValue The value for the header to be added
+ * @param aExtensionValue The extension value for the header
+ */
+void CHttpClient::AddHeaderL(RHTTPHeaders aHeaders, 
+								TInt aHeaderField, 
+								const TDesC8& aHeaderValue,
+								TInt aExtensionField,
+								const TDesC8& aExtensionValue)
+	{
+	RStringPool stringPool = iHTTPSession.StringPool();	// Do not close this session here.
+	RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
+	CleanupClosePushL(valStr);
+	THTTPHdrVal headerVal(valStr);
+	RStringF extensionStr = stringPool.OpenFStringL(aExtensionValue);
+	CleanupClosePushL(extensionStr);
+	THTTPHdrVal extensionVal(extensionStr);
+	aHeaders.SetFieldL(
+		stringPool.StringF(aHeaderField, RHTTPSession::GetTable()), 
+		headerVal,
+		stringPool.StringF(aExtensionField, RHTTPSession::GetTable()),
+		extensionVal);
+	CleanupStack::PopAndDestroy(2);	// extensionStr, valStr
+	}
+
+void CHttpClient::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent &aEvent)
+	{
+	switch (aEvent.iStatus){
+		case THTTPEvent::EGotResponseHeaders:
+			{
+			// HTTP response headers have been received.
+			// Pass status information to observer.
+			RHTTPResponse resp = aTransaction.Response();
+			// Get status code
+			TInt statusCode = resp.StatusCode();
+
+			// Get status text
+			RStringF statusStr = resp.StatusText();
+			HBufC* statusBuf = HBufC::NewLC(statusStr.DesC().Length());
+			statusBuf->Des().Copy(statusStr.DesC());
+
+			// Inform observer
+			iObserver.ResponseStatusL(statusCode, *statusBuf);
+
+			CleanupStack::PopAndDestroy(statusBuf);
+			break;
+			}
+	    case THTTPEvent::EGotResponseBodyData:
+	    	{
+			// Get text of response body
+			MHTTPDataSupplier* dataSupplier = aTransaction.Response().Body();
+			TPtrC8 ptr;
+			dataSupplier->GetNextDataPart(ptr);
+
+			// Append to iResponseBuffer
+			if (!iResponseBuffer)
+				{
+				iResponseBuffer = ptr.AllocL();
+				}
+			else
+				{
+				iResponseBuffer = iResponseBuffer->ReAllocL(iResponseBuffer->Length() + ptr.Length());
+				iResponseBuffer->Des().Append(ptr);
+				}
+
+			// Release the body data
+			dataSupplier->ReleaseData();
+			break;
+			}
+	    case THTTPEvent::EResponseComplete:
+			iObserver.ResponseReceivedL(*iResponseBuffer);
+	    	break;
+	    case THTTPEvent::ESucceeded:
+	    case THTTPEvent::EFailed:
+	    	{
+	    	aTransaction.Close();
+			iTransactionActive = EFalse;
+	    	break;
+	    	}
+		case THTTPEvent::ERedirectedPermanently:
+			break;
+		case THTTPEvent::ERedirectedTemporarily:
+			break;
+		default:
+			{
+			if (aEvent.iStatus < 0)
+				{
+				aTransaction.Close();
+				iTransactionActive = EFalse;
+				}
+			break;
+			}
+		}
+	}
+
+TInt CHttpClient::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& /*aEvent*/)
+	{
+	if(!aError)
+		{
+		aTransaction.Close();
+		iTransactionActive = EFalse;
+		}
+	return KErrNone;
+	}
+
+TBool CHttpClient::GetNextDataPart(TPtrC8& /*aDataPart*/)
+	{
+	// Not implemented for now as assuming that chunked response won't be sent 
+	// by the server
+	return ETrue;
+	}
+
+void CHttpClient::ReleaseData()
+	{
+	// Not implemented for now as assuming that chunked response won't be sent 
+	// by the server
+	}
+
+TInt CHttpClient::OverallDataSize()
+	{
+	// Not implemented for now as assuming that chunked response won't be sent 
+	// by the server
+	return 0;
+	}
+
+TInt CHttpClient::Reset()
+	{
+	// Not implemented for now as assuming that chunked response won't be sent 
+	// by the server
+	return KErrNone;
+	}