📄 http1.cpp
字号:
//
// 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 + -