【小结】IIS7下的Http Native Module开发 – kevin_song

  今天接到Product Manager的通知,Exchange 2007环境下的Native Module不再需要开发(详情可见上篇),但最近几天一直在做Prototype,那就做一下小结吧,总结一下最近几天的收获。

  一. 准备工作:

  1. 开发前安装Windows Platform SDK,主要是使用其中的#include <httpserv.h>(用到的很多接口都可以在其中看到)

  2. WireShark,用来进行抓包,可以验证自己是否正确拿到http request和response的信息

  

  二. Visual Studio 2005编码:

  1. Native Module主要使用3个基本组件:

    A. HttpModule类 – HttpModule是当前模块的积累。在HttpModule类中我们将实现请求通知方法,这个方法是由IIS在相关的请求处理事件中调用的。(其中主要是定义我们的处理时间方法,例如onBeginRequest)

    B. HttpModule类工厂 – 针对每个被处理的请求,HttpModule类工厂可以创建或删除用于处理请求的模块

    C. RegisterModule类函数 – 一个Native Module只会实现一个此函数,用于导出函数,使IIS能够加载模块(我遇到一个问题,至今还没解决,就是此函数中我发现只能注册一个事件,如果多个会导致IIS ative sync pool stop掉,DLL用不起来)

  2. 其他具体编码可参见我的示例,具体开发流程可参见《IIS 7开发与管理完全参考手册》

  

  三. 安装此Native Module

  经过我的测试发现,我的Native Module能够工作,主要是做了以下几项工作:

  1. 编译后的DLL放置在C:WindowsSystem32inetsrv下

  2. 修改applicationHost.xml配置文件,C:WindowsSystem32inetsrvconfig,在其中的<globalModules>中添加我们的模块

  3. IIS 7中,[DomainUser]下,Module中,右键选择Configure Native Module,然后选择Register,填入我们模块的信息。

  目前我还不确定2,3是否是重复了,但是我发现这两者都做的情况,我的Native Module是工作的,而3的Register不是修改2的配置文件,具体有待验证。

 

  经过以上三个步骤,我的Native Module可以工作了!目前可以拿到Http的Request Header的信息。希望这次小结,能对有开发此类需求的同学一点参考,由于此功能被PM去掉了,所以很遗憾这块我不能继续做下去,只能是小结啦。:-)

 

参考资料:

1. 《Professional IIS7》,Wrox出版社出版(Programmer to Programer的理念),非常详细的讲解IIS7,其中12章详细介绍了Http两类Module的开发。其中文版是《IIS 7开发与管理完全参考手册》

2. MSDN

  http://msdn.microsoft.com/en-us/library/ms690856(v=vs.90).aspx

 

Prototype代码附上,功能:取Http request的header信息

#define _WINSOCKAPI_
#include
<windows.h>
#include
<sal.h>
#include
<httpserv.h>
#include
writeLog.h

// Create the module class.
class CTestNativeModule : public CHttpModule
{
//TODO
// Implement Notification Method/s
REQUEST_NOTIFICATION_STATUS
OnBeginRequest( IN IHttpContext
* pHttpContext,
IN IHttpEventProvider
* pProvider
)
{
WriteLog(
–> CTestNativeModule, OnBeginRequest());
// We won’t be using this, so confirm that to avoid compiler warnings
UNREFERENCED_PARAMETER( pProvider );

IHttpRequest* pHttpRequest = pHttpContext->GetRequest();

//dump request header
DumpRequestHeader(pHttpContext, pHttpRequest);

WriteLog(<– CTestNativeModule, OnBeginRequest());
      
return RQ_NOTIFICATION_CONTINUE;
}
  
void DumpRequestHeader(IHttpContext * pHttpContext, IHttpRequest* pHttpRequest)
{
WriteLog(
–> CTestNativeModule, DumpRequestHeader());

// Buffer size for returned variable values.
DWORD cbValue = 512;
PCSTR pHeaderValue
= (PCSTR) pHttpContext->AllocateRequestMemory( cbValue );

for(HTTP_HEADER_ID i = (HTTP_HEADER_ID)0; i < HttpHeaderRequestMaximum; i = (HTTP_HEADER_ID)((int)i + 1))
{
pHeaderValue
= pHttpRequest->GetHeader(i);
WriteLog(pHeaderValue);
}

HTTP_REQUEST* rawHttpRequest = pHttpRequest->GetRawHttpRequest();
WriteLog(
RawUrl, rawHttpRequest->pRawUrl);

PCSTR pKey = “”;

pKey = Cmd;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

pKey = DeviceId;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

pKey = DeviceType;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

pKey = AttachmentName;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

pKey = MS-ASProtocolVersion;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

pKey = X-EAS-Proxy;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

pKey = User-Agent;
pHeaderValue
= pHttpRequest->GetHeader(pKey);
WriteLog(pKey, pHeaderValue);

/*
//Authorization
pKey = “Authorization”;
pHeaderValue = pHttpRequest->GetHeader(pKey);
writeLog(pKey, pHeaderValue);

//Content-Type
pKey = “Content-Type”;
pHeaderValue = pHttpRequest->GetHeader(pKey);
writeLog(pKey, pHeaderValue);

//Host
pKey = “Host”;
pHeaderValue = pHttpRequest->GetHeader(pKey);
writeLog(pKey, pHeaderValue);

//Content-Length
pKey = “Content-Length”;
pHeaderValue = pHttpRequest->GetHeader(pKey);
writeLog(pKey, pHeaderValue);*/

WriteLog(<– CTestNativeModule, DumpRequestHeader());
}

void DumpRequestContent(IHttpContext* pHttpContext, IHttpRequest* pHttpRequest)
{
// Create an HRESULT to receive return values from methods.
/*HRESULT hr;
// Allocate a 1K buffer.
DWORD cbBytesReceived = 1024;
void* pvRequestBody = pHttpContext->AllocateRequestMemory(cbBytesReceived);
hr = pHttpRequest->ReadEntityBody( pvRequestBody, cbBytesReceived, false, &cbBytesReceived, NULL);
*/
}

};

// Create the module’s class factory.
class CTestNativeModuleFactory : public IHttpModuleFactory
{
public:
HRESULT
GetHttpModule(
OUT CHttpModule
** ppModule,
IN IModuleAllocator
* pAllocator
)
{
WriteLog(
–> CTestNativeModuleFactory, GetHttpModule());

UNREFERENCED_PARAMETER( pAllocator );

// Create a new instance.
CTestNativeModule * pModule = new CTestNativeModule;

// Test for an error.
if (!pModule)
{
// Return an error if the factory cannot create the instance.
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
else
{
// Return a pointer to the module.
*ppModule = pModule;
pModule
= NULL;
// Return a success status.
return S_OK;
}
WriteLog(
<– CTestNativeModuleFactory, GetHttpModule());
}

void
Terminate()
{
WriteLog(
–> CTestNativeModuleFactory, Terminate());
// Remove the class from memory.
delete this;
WriteLog(
<– CTestNativeModuleFactory, Terminate());
}
};

// Create the module’s exported registration function.
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo
* pModuleInfo,
IHttpServer
* pGlobalInfo
)
{
WriteLog(
–> RegisterModule());
HRESULT hr
= S_OK;

UNREFERENCED_PARAMETER( dwServerVersion );
UNREFERENCED_PARAMETER( pGlobalInfo );

// TODO
// Register for notifications
// Set notification priority

CTestNativeModuleFactory
* testNMFacotry = new CTestNativeModuleFactory;

// Set the request notifications
// BeginRequest
hr = pModuleInfo->SetRequestNotifications(
testNMFacotry,
RQ_BEGIN_REQUEST, // Register for BeginRequest notifications
0);

if( hr == S_OK ) // Do this only if there was no error
{
hr = pModuleInfo->SetPriorityForRequestNotification(
RQ_BEGIN_REQUEST, // which notification
PRIORITY_ALIAS_FIRST // what priority
);
}
WriteLog(
<– RegisterModule());
return hr;
}

本文链接:http://www.cnblogs.com/KevinSong/p/3347314.html,转载请注明。



You must enable javascript to see captcha here!

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress

无觅相关文章插件,快速提升流量