×
Namespaces

Variants
Actions

Archived:Modifying web content using an HTTP filter on Symbian

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Article Metadata
Code ExampleTested with
Devices(s): All (S60)
Compatibility
Platform(s): S60 3rd Edition
S60 3rd Edition FP1
S60 3rd Edition FP2
S60 5th Edition
S60 3rd Edition FP2
S60 3rd Edition FP1
Article
Keywords: MHTTPFilter, MHTTPDataSupplier
Created: User:Technical writer 1 (August 7, 2008
Last updated: October 20, 2010)
Last edited: hamishwillee (01 Jul 2012)


Contents

Description

HTTP filters are add-on modules that provide additional features to an HTTP session beyond the simple request-response transaction. A filter can be written so that it can perform certain encoding on the content received from the server and then pass this modified content to the client.

Note that there are high capability requirements for HTTP filters, including ProtServ, NetworkControl, and SwEvent. See the related example application File:SampleFilter.zip for more information.

Solution

The filter must be inherited from MHTTPDataSupplier so that it can replace the content.

  class CSampleFilter : public CEComFilter, public MHTTPFilter, public MHTTPDataSupplier
{
public:
static CEComFilter* CreateFilterL(TAny* aHttpSession);
// virtuals from the HTTP filter M classes
void MHFUnload(RHTTPSession aSession, THTTPFilterHandle aHandle);
void MHFLoad(RHTTPSession aSession, THTTPFilterHandle aHandle);
void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
void MHFSessionRunL(const THTTPSessionEvent& aEvent);
TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
TInt MHFSessionRunError(TInt aError, const THTTPSessionEvent& aEvent);
 
//methods inherited from MHTTPDataSupplier
TBool GetNextDataPart(TPtrC8& aDataPart);
TInt OverallDataSize();
void ReleaseData();
TInt Reset();
 
~CSampleFilter();
private:
void ConstructL(RHTTPSession& aHttpSession);
 
private:
RStringF iFilterName;
TBool isLast;
HBufC8* iPostData;
TInt iOverallDataSize;
MHTTPDataSupplier* iBody;
};

The content is modified in the MHFRunL function of the filter.

    void CSampleFilter ::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
{
// called when a RHTTPTransaction event happens.
switch ( aEvent.iStatus )
{
 
case THTTPEvent::EGotResponseHeaders:
{
 
}
break;
 
case THTTPEvent::EGotResponseBodyData:
{
iBody = aTransaction.Response().Body();
TPtrC8 dataChunk;
isLast = iBody->GetNextDataPart(dataChunk);
iOverallDataSize = iBody->OverallDataSize();
 
TRAPD(err,iPostData = dataChunk.AllocL());
 
// The last datachunk of every transaction
// is replaced with the iPostData of the filter.
if(!err && isLast)
{
TPtr8 tempDataPtr = iPostData->Des(); //This pointer can be used
//to modify the received content.
aTransaction.Response().RemoveBody();
MHTTPDataSupplier* dataSupplier = this;
 
//Replacing the Transaction body
aTransaction.Response().SetBody(*dataSupplier);
}
}
break;
 
default:
// There are more events in THTTPEvent, but they are usually not
// needed. However, event status smaller than zero should be handled
// correctly since it is an error.
{
 
}
break;
}
}

The inherited functions of MHTTPDataSupplier are to be overridden as shown below.

    //OverallDataSize() function of MHTTPDataSupplier	  
TInt CSampleFilter::OverallDataSize()
{
return iOverallDataSize;
}
 
//ReleaseData() function of MHTTPDataSupplier
void CSampleFilter::ReleaseData()
{
iBody->ReleaseData();
 
if(iPostData)
{
delete iPostData;
iPostData = 0;
}
}
 
//Reset() function of MHTTPDataSupplier
TInt CSampleFilter::Reset()
{
return KErrNone;
}
 
//GetNextDataPart() function of MHTTPDataSupplier
TBool CSampleFilter::GetNextDataPart(TPtrC8& aDataPart)
{
if(iPostData)
{
aDataPart.Set(iPostData->Des();
}
return isLast;
}

Inspecting request headers

Additionally, it is possible to iterate through all headers in an HTTP request using the following piece of code:

_LIT( KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3" );
 
void CSampleFilter::DumpHeadersL( RHTTPTransaction& aTransaction )
{
RHTTPRequest resp = aTransaction.Request();
RStringPool strP = aTransaction.Session().StringPool();
RHTTPHeaders hdr = resp.GetHeaderCollection();
THTTPHdrFieldIter it = hdr.Fields();
while( it.AtEnd() == EFalse )
{
RStringTokenF fieldName = it();
RStringF fieldNameStr = strP.StringF( fieldName );
 
// fieldNameStr now contains the header field name
 
THTTPHdrVal fieldVal;
TInt fieldPart = 0;
while( hdr.GetField( fieldNameStr, fieldPart++, fieldVal ) == KErrNone )
{
TBuf8<512> buf;
switch( fieldVal.Type() )
{
case THTTPHdrVal::KTIntVal: // integer
{
buf.Num( fieldVal.Int() );
break;
}
 
case THTTPHdrVal::KStrFVal: // case-insensitive string
{
RStringF fieldValStr = strP.StringF( fieldVal.StrF() );
const TDesC8& fieldValDesC = fieldValStr.DesC();
buf.Copy( fieldValDesC );
}
break;
 
case THTTPHdrVal::KStrVal: // case-sensitive string
{
RString fieldValStr = strP.String( fieldVal.Str() );
const TDesC8& fieldValDesC = fieldValStr.DesC();
buf.Copy( fieldValDesC );
}
break;
 
case THTTPHdrVal::KDateVal: // date
{
TDateTime date = fieldVal.DateTime();
TBuf<64> dateTimeString;
TTime tim( date );
tim.FormatL( dateTimeString, KDateFormat );
buf.Copy( dateTimeString );
}
break;
 
default:
break;
}
 
// buf now contains (all or part of) the field value(s)
}
++it;
}
}

Example application

This example filter application shows how to modify the HTML content received from an HTTP server and pass the modified content to the client.

File:SampleFilter.zip

This page was last modified on 1 July 2012, at 15:04.
69 page views in the last 30 days.