⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http1.cpp

📁 《UIQ 3 The Complete Guide》书的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Http1.cpp - Http1 example
//
// Copyright (C) UIQ Technology AB, 2007
//
// This material is provided "as is" without any warranty to its performance or functionality. 
// In no event shall UIQ Technology be liable for any damages whatsoever arising out of the
// use or inabilty to use this material. 
//

#include "Http1.h"
#include "Http1.hrh"
#include <Http1.rsg>

#include <QikViewBase.h>
#include <QikCommand.h>
#include <QikCommandManager.h>
#include <QikListBoxModel.h>
#include <QikListBox.h>
#include <MQikListBoxData.h>
#include <eikstart.h>

#include <Http.h>

//////////////////////////////////////////////////////////////////////////////
// The application Uid here MUST match UID3 defined in the MMP file 
// This is a development UID and must NOT be used in production type software
const TUid KAppSpecificUid={0xEDEAD010};

// internal secondary view id, must be unique amongst this applications views
const TUid KUidAppView={0x00000001};

// views within applications are fully identified by the app Uid and secondary view id
#define KViewIdAppView TVwsViewId(KAppSpecificUid,KUidAppView)

//////////////////////////////////////////////////////////////////////////////////
class CLogText : public CBase
    {
public:
	// new methods
	~CLogText();
	void ConstructL();
	TInt Count();
	const TDesC& At(const TInt aIndex);
	void LogText(const TDesC& aBuf);
	void ResetText();

protected:
	CArrayFixFlat<HBufC*>* iText;
	};

CLogText::~CLogText()
	{
	ResetText();
	delete(iText);
	}

void CLogText::ConstructL()
	{
	iText=new(ELeave)CArrayFixFlat<HBufC*>(32);
	}
	
TInt CLogText::Count()
// Report number of logged messages
	{
	return(iText->Count());
	}

const TDesC& CLogText::At(const TInt aIndex)
// report 'n'th text message
	{
	return(*iText->At(aIndex));
	}

void CLogText::ResetText()
	{
	TInt count=Count();
	for (TInt i=0;i<count;i++)
		delete(iText->At(i));
	iText->Reset();
	}

void CLogText::LogText(const TDesC& aBuf)
	{ // add new text item to front of the list
	TRAPD(err,
		TBuf<128>bb;
		if (aBuf.Length()>120)
			bb=aBuf.Left(120);
		else
			bb=aBuf;
		HBufC* q=bb.AllocLC();
		iText->InsertL(0,q);	// at front of list
		CleanupStack::Pop(q);
		if (iText->Count()>100)
			{ // restrict to last 100 log msgs
			delete(iText->At(100));
			iText->Delete(100);
			}
		);
	}

//////////////////////////////////////////////////////////////////////////////////
class MHttpEngineObserver
	{
public:
	virtual void ReportEvent(const TInt aErr,const TInt aStatusCode,const TDesC& aStatusText)=0;
	virtual void ReportBody(const TDesC8& aBody)=0;
	virtual void LogInfo(const TDesC& aBuf)=0;
	};

//////////////////////////////////////////////////////////////////////////////////
class CHttpEngine : public CBase, public MHTTPTransactionCallback
	{
protected:
	// from MHTTPTransactionCallback
	void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
	TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
	
	// new methods
	void SetHeaderL(RHTTPHeaders aHeaders,TInt aHdrField,const TDesC8& aHdrValue);
public:
	// new methods
	~CHttpEngine();
	void ConstructL(MHttpEngineObserver* aObserver);
	void GetContentL(const TDesC8& aUrl);

	inline TBool IsBusy() const {return(iIsBusy);};

protected:
	MHttpEngineObserver* iObserver;
	RHTTPSession iSession;
	RHTTPTransaction iTransaction;

	TInt iStatusCode;			// status code returned by HTTP stack, 200=ok
	TBuf<256> iStatusText;		// any text message associated with the status code

	TBool iIsBusy;
	};

CHttpEngine::~CHttpEngine()
	{
	iSession.Close(); // will also cancel any outstanding transaction
	}

void CHttpEngine::ConstructL(MHttpEngineObserver* aObserver)
// Open an HTTP session. This is simply causing a connection to the internal device HTTP library code,
// probably implemented in a server process. 
	{
	iObserver=aObserver;
	iSession.OpenL();
	}

void CHttpEngine::MHFRunL(RHTTPTransaction aTransaction,const THTTPEvent& aEvent)
//
// Apparently this is not allowed to leave on some events... despite it being an L function.
//
	{
	switch (aEvent.iStatus)
		{

	case THTTPEvent::EGotResponseHeaders:
		{	// HTTP response headers have been received.
		_LIT(KEGotResponseHeaders,"EGotResponseHeaders");
		iObserver->LogInfo(KEGotResponseHeaders);
		RHTTPResponse resp=aTransaction.Response();
		iStatusCode=resp.StatusCode();
		iStatusText.Copy(resp.StatusText().DesC());
		break;
		}

	case THTTPEvent::EGotResponseBodyData:
		{	// Some (more) body data has been received
		_LIT(KEGotResponseBodyData,"EGotResponseBodyData");
		iObserver->LogInfo(KEGotResponseBodyData);
		MHTTPDataSupplier* body=aTransaction.Response().Body();
		TPtrC8 bodyData;
		body->GetNextDataPart(bodyData);
		iObserver->ReportBody(bodyData);
		body->ReleaseData();
		break;
		}

	case THTTPEvent::EResponseComplete:		// transaction's response is complete (got all content etc)
		_LIT(KEResponseComplete,"EResponseComplete");
		iObserver->LogInfo(KEResponseComplete);
		break;

	case THTTPEvent::ESucceeded:			// transaction finished - all ok
		aTransaction.Close();
		iObserver->ReportEvent(KErrNone,iStatusCode,iStatusText);
		iIsBusy=EFalse;
		break;

	case THTTPEvent::EFailed:				// transaction finished - something fell over
		aTransaction.Close();
		iObserver->ReportEvent(KErrGeneral,iStatusCode,iStatusText);
		iIsBusy=EFalse;
		break;

	case THTTPEvent::ERedirectedPermanently:
		_LIT(KERedirectedPermanently,"ERedirectedPermanently");
		iObserver->LogInfo(KERedirectedPermanently);
		break;

	case THTTPEvent::ERedirectedTemporarily:
		_LIT(KERedirectedTemporarily,"ERedirectedTemporarily");
		iObserver->LogInfo(KERedirectedTemporarily);
		break;

	default:
		{ // -46 will mean you dont have NetworkServices CAPABILITY !
		TBuf<64>bb;
		_LIT(KUnhandled,"Unhandled: %d");
		bb.Format(KUnhandled,aEvent.iStatus);
		iObserver->LogInfo(bb);
		break;
		}
		}
	}

TInt CHttpEngine::MHFRunError(TInt aError,RHTTPTransaction aTransaction,const THTTPEvent& aEvent)
//
// Called by internal active object if an error occurs.
//
	{
	TBuf<64>bb;
	_LIT(KMHFRunError,"MHFRunError: %d,%d");
	bb.Format(KMHFRunError,aError,aEvent.iStatus);
	iObserver->LogInfo(bb);

	return(KErrNone);
	}

void CHttpEngine::SetHeaderL(RHTTPHeaders aHeaders,TInt aHdrField,const TDesC8& aHdrValue)
// Set a header field to be the value indicated
	{
	RStringF str=iSession.StringPool().OpenFStringL(aHdrValue);
	CleanupClosePushL(str);
	THTTPHdrVal val(str);
	aHeaders.SetFieldL(iSession.StringPool().StringF(aHdrField,RHTTPSession::GetTable()),val);
	CleanupStack::PopAndDestroy(&str);
	}

void CHttpEngine::GetContentL(const TDesC8& aUrl)
// Get content at the indicated indicated URL.
	{
	// use the system URI parser to contain the consituient parts of a URL
	TUriParser8 uri; 
	User::LeaveIfError(uri.Parse(aUrl));

	// the system contains pre-constructed 'pools' of non modifiable strings (tokens). 
	// We want the string identified by HTTP::EGET from the Http session string table
	RStringF method=iSession.StringPool().StringF(HTTP::EGET, RHTTPSession::GetTable());

	// Create a GET transaction...
	iTransaction=iSession.OpenTransactionL(uri,*this,method);

	// a transaction contains a set of headers, refer to that set of hdrs
	RHTTPHeaders hdrs=iTransaction.Request().GetHeaderCollection();

	TRAPD(err,
		// configure whichever headers are appropriate to your application
		_LIT8(KUserAgent,"UIQ Http Example (1.0)");
		SetHeaderL(hdrs,HTTP::EUserAgent,KUserAgent);

		// we only accept text content 
		_LIT8(KAccept,"text/*");
		SetHeaderL(hdrs,HTTP::EAccept,KAccept);

		// submitting the transaction means it will start..
		// This will call back MHTTPTransactionCallback methods
		iTransaction.SubmitL();
		iIsBusy=ETrue;
		);

	if (err!=KErrNone)
		{
		iTransaction.Close();
		User::Leave(err);
		}
	}


//////////////////////////////////////////////////////////////////////////////////
// We have chosen to separate out an HTTP post engine from an HTTP get engine to aid in clarity.
// There is no special requirement to do this other than separating out what applications would 
// typically do for GET compared to POST to aid in understanding. 
class CHttpPostEngine : public CBase, public MHTTPTransactionCallback, public MHTTPDataSupplier
	{
protected:
	// from MHTTPDataSupplier
	TBool GetNextDataPart(TPtrC8& aDataPart);
	void ReleaseData();
	TInt OverallDataSize();
	TInt Reset();

	// from MHTTPTransactionCallback
	void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
	TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
	
	// new methods
	void SetHeaderL(RHTTPHeaders aHeaders,TInt aHdrField,const TDesC8& aHdrValue);
public:
	// new methods
	~CHttpPostEngine();
	void ConstructL(MHttpEngineObserver* aObserver);
	void PostContentL(const TDesC8& aUrl,HBufC8* aData);
	inline TBool IsBusy() const {return(iIsBusy);};

protected:
	MHttpEngineObserver* iObserver;
	RHTTPSession iSession;
	RHTTPTransaction iTransaction;

	TInt iStatusCode;			// status code returned by HTTP stack, 200=ok
	TBuf<256> iStatusText;		// any text message associated with the status code

	HBufC8* iData;				// the content we wish to post

	TBool iIsBusy;
	};

CHttpPostEngine::~CHttpPostEngine()
	{
	iSession.Close(); // will also cancel any outstanding transaction
	}

void CHttpPostEngine::ConstructL(MHttpEngineObserver* aObserver)
// Open an HTTP session. This is simply causing a connection to the internal device HTTP library code,
// probably implemented in a server process. 
	{
	iObserver=aObserver;
	iSession.OpenL();
	}

TBool CHttpPostEngine::GetNextDataPart(TPtrC8& aDataPart)
// From MHTTPDataSupplier. Supply the next data section. 
	{
	TBuf<64>bb;
	_LIT(KGetNextDataPart,"GetNextDataPart %d");
	bb.Format(KGetNextDataPart,(*iData).Length());
	iObserver->LogInfo(bb);

	aDataPart.Set(*iData);
	return(ETrue);	// we have a single chunk so finished
	}

void CHttpPostEngine::ReleaseData()
// From MHTTPDataSupplier. We can release any data we hold as its no longer required to exist as 
// far as the HTTP stack is concerned. 
	{
	_LIT(KReleaseData,"ReleaseData");
	iObserver->LogInfo(KReleaseData);

	delete(iData);
	iData=NULL;
	}

TInt CHttpPostEngine::OverallDataSize()
// From MHTTPDataSupplier. We only have a single chunk at this time so we report the size of the
// content we have.
	{
	if (!iData)
		return(0);

	TBuf<64>bb;
	_LIT(KOverallDataSize,"OverallDataSize %d");
	bb.Format(KOverallDataSize,(*iData).Length());
	iObserver->LogInfo(bb);

	return((*iData).Length());
	}

TInt CHttpPostEngine::Reset()
// From MHTTPDataSupplier. Reset to the first part, even if weve supplied the last part...
// We have chosen not to support this. When redirects occur this should be supported
	{
	_LIT(KReset,"Reset");
	iObserver->LogInfo(KReset);

	return(KErrNotSupported);
	}

void CHttpPostEngine::MHFRunL(RHTTPTransaction aTransaction,const THTTPEvent& aEvent)
// 
	{
	switch (aEvent.iStatus)
		{

	case THTTPEvent::EGotResponseHeaders:
		{	// HTTP response headers have been received.
		_LIT(KPostEGotResponseHeaders,"Post:EGotResponseHeaders");
		iObserver->LogInfo(KPostEGotResponseHeaders);
		RHTTPResponse resp=aTransaction.Response();
		iStatusCode=resp.StatusCode();
		iStatusText.Copy(resp.StatusText().DesC());
		break;
		}

	case THTTPEvent::EGotResponseBodyData:
		// Some (more) body data has been received
		{
		_LIT(KPostEGotResponseBodyData,"Post:EGotResponseBodyData");
		iObserver->LogInfo(KPostEGotResponseBodyData);
		MHTTPDataSupplier* body=aTransaction.Response().Body();
		TPtrC8 bodyData;
		body->GetNextDataPart(bodyData);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -