本文章由杨芹勍原创,如需转载请注明作者及出处,否则保留追究法律责任的权利!
在IE浏览器中,如果想捕获浏览器的HTTP请求,可以通过BHO或者“异步可插协议”技术实现,类似于“迅雷”之类的下载软件,当用户点击一个下载链接会自动弹出。在Symbian OS中有一种技术与“异步可插协议”非常类似,Symbian OS会在HTTP请求中每一步处理过程都通知用户代码,本文将介绍这种技术的实现,并在文章的最后提供在手机上实现下载软件的具体思路。
从类名可以看出,CEComFilter是一个ECOM接口类(关于ECOM方面的编程总结,我会在后面的章节陆续放出),以下列出CEComFilter类的关键代码(SDK中文件cecomfilter.h内):
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > 1 const TUid KUidFilterPluginInterface = { 0x101F446D };
2 class CEComFilter : public CBase
3 {
4 public :
5 static CEComFilter * InstallFilterL(RHTTPSession aSession, const TUid aEComFilterUid)
6 {
7 TAny * filterPlugin = REComSession::CreateImplementationL(aEComFilterUid, _FOFF(CEComFilter,iEcomDtorID), & aSession);
8 return REINTERPRET_CAST(CEComFilter * , filterPlugin);
9 }
10
11 static CEComFilter * InstallFilterL(RHTTPSession aSession, const TDesC8 & aEComFilterDataType)
12 {
13 TEComResolverParams resolverParams;
14 resolverParams.SetDataType(aEComFilterDataType);
15
16 // This will leave if the plugin is not found
17 TAny * filterPlugin = REComSession::CreateImplementationL(KUidFilterPluginInterface,
18 _FOFF(CEComFilter,iEcomDtorID),
19 & aSession, resolverParams);
20 return REINTERPRET_CAST(CEComFilter * , filterPlugin);
21 }
22
23 ~ CEComFilter()
24 {
25 REComSession::DestroyedImplementation(iEcomDtorID);
26 }
27
28 private :
29 TUid iEcomDtorID;
30 };
通过代码我们可以分析出以下结论:
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > class REComSession : public RSessionBase
{
...
IMPORT_C static void ListImplementationsL(TUid aInterfaceUid, RImplInfoPtrArray & aImplInfoArray);
...
}
实现CEComFilter,其实就是实现一个普通的ECOM接口,步骤非常简单,在此不再说明具体步骤。重点在第5步:如何对传入的RHTTPSession进行监控。
SDK中关于RHTTPSession::FilterCollection()方法的解释:
Accessor for the filter collection. Note that the filter collection can't be edited after the first transaction has been created.
注意:如果已经在RHTTPSession上创建了RHTTPTransaction,则不能对Filter Collection进行修改。
此方法返回类型RHTTPFilterCollection,使用RHTTPFilterCollection::AddFilterL的重载函数向RHTTPSession的监视器队列中添加“监视器”,用于捕获HTTP请求信息:
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > IMPORT_C void AddFilterL(MHTTPFilter & aFilter, THTTPEvent aEvent, RStringF aHeader, TInt aStatusCode, TInt aPosition, RStringF aName);
参数说明:
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > 1 class MHTTPFilter
2 {
3 public :
4 IMPORT_C virtual void MHFUnload(RHTTPSession aSession, THTTPFilterHandle aHandle);
5 IMPORT_C virtual void MHFLoad(RHTTPSession aSession, THTTPFilterHandle aHandle);
6 IMPORT_C virtual void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent & aEvent);
7 IMPORT_C virtual void MHFSessionRunL( const THTTPSessionEvent & aEvent);
8 IMPORT_C virtual TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent & aEvent);
9 IMPORT_C virtual TInt MHFSessionRunError(TInt aError, const THTTPSessionEvent & aEvent);
10 };
根据以上分析,我们可以通过实现CEComFilter接口完成一个Demo:只要系统提交了HTTP进行Url的请求,就弹出一个全局消息框,显示HTTP所请求的Url地址。
完整源代码请点击此处下载
1、实现接口的类名叫CFelixHttpFilter,定义如下:
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > 1 class CFelixHttpFilter: public CEComFilter, private MHTTPFilter
2 {
3 public :
4 ~ CFelixHttpFilter();
5 static CFelixHttpFilter * NewL(TAny * aHttpSession);
6 static CFelixHttpFilter * NewLC(TAny * aHttpSession);
7
8 public :
9 // MHTTPFilter
10 void MHFUnload(RHTTPSession aSession, THTTPFilterHandle aHandle);
11 void MHFLoad(RHTTPSession aSession, THTTPFilterHandle aHandle);
12 void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent & aEvent);
13
14 private :
15 CFelixHttpFilter();
16 void ConstructL(TAny * aHttpSession);
17
18 private :
19 RStringF iFilterName;
20 };
21
2、关键类代码实现如下:
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > 1 _LIT8(KFilterName, " FelixFilter " );
2
3 CFelixHttpFilter:: ~ CFelixHttpFilter()
4 {
5 iFilterName.Close();
6 }
7
8 CFelixHttpFilter * CFelixHttpFilter::NewLC(TAny * aHttpSession)
9 {
10 CFelixHttpFilter * self = new (ELeave) CFelixHttpFilter();
11 CleanupStack::PushL(self);
12 self -> ConstructL(aHttpSession);
13 return self;
14 }
15
16 CFelixHttpFilter * CFelixHttpFilter::NewL(TAny * aHttpSession)
17 {
18 CFelixHttpFilter * self = CFelixHttpFilter::NewLC(aHttpSession);
19 CleanupStack::Pop(); // self;
20 return self;
21 }
22
23 void CFelixHttpFilter::ConstructL(TAny * aHttpSession)
24 {
25 RHTTPSession & httpSession = * (reinterpret_cast < RHTTPSession *> (aHttpSession));
26
27 iFilterName = httpSession.StringPool().OpenFStringL(KFilterName);
28 CleanupClosePushL(iFilterName);
29
30 httpSession.FilterCollection().AddFilterL( * this , THTTPEvent::EAnyTransactionEvent, RStringF(), KAnyStatusCode, EClientFilters, iFilterName);
31 CleanupStack::Pop( & iFilterName);
32 }
33
34 void CFelixHttpFilter::MHFUnload(RHTTPSession aSession, THTTPFilterHandle aHandle)
35 {
36 delete this ;
37 }
38
39 void CFelixHttpFilter::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent & aEvent)
40 {
41 if (aEvent == THTTPEvent::ESubmit)
42 {
43 // 在此处拦截到请求的Url
44 const TDesC8 & url = aTransaction.Request().URI().UriDes();
45 TBuf < KMaxFileName > url16;
46 url16.Copy(url);
47
48 // 效果:将url打印到屏幕上
49 CEikonEnv::Static() -> InfoWinL(url16, KNullDesC16);
50 }
51 }
52
53 const TImplementationProxy kImplementationTable[] =
54 {
55 IMPLEMENTATION_PROXY_ENTRY( 0xA00133E9 , CFelixHttpFilter::NewL)
56 };
57
58 EXPORT_C const TImplementationProxy * ImplementationGroupProxy(TInt & aTableCount)
59 {
60 aTableCount = sizeof (kImplementationTable) / sizeof (TImplementationProxy);
61 return kImplementationTable;
62 }
63
注意,代码第55行中的0xA00133E9是我们ECOM实现的implementation_uid。
3、我们的程序UID3为0xA00133E8,ECOM资源文件名:A00133E8.rss,内容如下:
< 本插件原作者为 Steve Dunn,汉化刘建成. http://www.tvwz.com.cn >< Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ > 1 RESOURCE REGISTRY_INFO filterinfo
2 {
3 dll_uid = _UID3;
4 interfaces =
5 {
6 INTERFACE_INFO
7 {
8 interface_uid = 0x101F446D ;
9 implementations =
10 {
11 IMPLEMENTATION_INFO
12 {
13 implementation_uid = 0xA00133E9 ;
14 version_no = 1 ;
15 display_name = " Felix Filter " ;
16 default_data = " HTTP/+FELIXFILTER " ;
17 opaque_data = "" ;
18 }
19 };
20 }
21 };
22 }
23
以上资源文件第16行,default_data的作用:
HTTP监视器能够“主动的”加载或者“被动的”加载,这取决于你资源文件中IMPLEMENTATION_INFO小节中的“default_data”字段(以上代码第16行)所设定的值,有如下三个加载选项被支持:
基本概念都已经清楚,现在我们来想想如何实现手机上的迅雷。根据以下流程可以容易的做到:
本文章由杨芹勍原创,如需转载请注明作者及出处,否则保留追究法律责任的权利!