Writing an HTTP filter plugin
What is an HTTP filter plugin?
HTTP filter plugins classes that get loaded in to HTTP sessions on Symbian OS, and sit between the HTTP framework and the client, receiving HTTP events and potentially acting on them.
A chain of HTTP filter plugins is automatically loaded with every HTTP session you invoke. You can also manually load additional filters, or remove automatically loaded ones via the RHTTPSession::FilterCollection API.
What can I do with an HTTP filter?
Well, lots! You can modify outgoing requests, look at or modify the responses to a fairly high degree. As far as what you can do, the sky is the limit, basically.
How do I write an HTTP filter?
HTTP filters extend the MHTTPFilter (documented in the devlib.) Filters for automatic loading are packaged in an ECOM object, and also extend the CEComFilter, implementing the KUidFilterPluginInterface interface.
An example of an automatically loading plugin is included below.
A demo HTTP filter
A bare bones demo HTTP filter is attached to this page. It does nothing except log messages on load and unload, and record the URL of all transactions submitted. Hopefully, this will give you the bare essentials and you can flesh it out to create your own filter.
A walkthrough of the key components of the code:
CEComFilter* CDemoFilter::CreateFilterL(TAny* aHttpSession)
// The CEcomFilter class passes us a pointer to the RHTTPSession so we can install ourselves
RHTTPSession* session = reinterpret_cast<RHTTPSession*>(aHttpSession);
CDemoFilter* self = new (ELeave) CDemoFilter;
This is the ECOM plugin entry point. The HTTP framework will load our plugin, and pass us the current HTTP session. We should create an instance of ourselves, and load ourselves as a filter in to the session. This is done in ConstructL:
void CDemoFilter::ConstructL(RHTTPSession& aSession)
// install this filter in to the current session
iFilterName = aSession.StringPool().OpenFStringL(KDemoFilterName);
RStringF(), KAnyStatusCode, EClientFilters, iFilterName);
The parameters to AddFilterL define which transactions we're called for. We can choose to only get called for certain transactions or events. I've chosen to have my filter called for all transactions. The parameter where I've passed EClientFilters defines where in the chain of filters you get loaded. Most filters will choose EClientFilters, since this will ensure we are invoked after all the system filters.
// 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);
The MHTTPFilter interface defines the virtuals listed above. These aren't pure virtuals, you can choose not to implement some or all of them. My demo filter implements all of them for the purposes of demonstration.
const TImplementationProxy KImplementationTable =
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
aTableCount = sizeof(KImplementationTable) / sizeof(TImplementationProxy);
The standard ECOM entry point. Obviously, you'd change 0xA00033E9 to be your own implementation UID procured from Symbian Signed.
And that's pretty much it for the code. Pretty simple, eh?
Getting your HTTP filter loaded automatically
In my plugin, I'm using:
default_data = "HTTP/+DEMOFILTER";
Which means "always load this filter, and don't let it be unloaded."
A note on capabilities
I've given this demo plugin the capabilities:
ReadDeviceData WriteDeviceData ProtServ NetworkControl NetworkServices SwEvent LocalServices ReadUserData WriteUserData UserEnvironment
Which is the very minimum required for the filter to be loaded in the Nokia OSS browser process. I say "minimum", but it's still a hefty chunk of capabilities.
Ideally, you should have ALL-TCB for an HTTP filter. In practice, you'll probably end up with all the non-manufacturer granted capabilities plus Network Control.