今天接到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:\Windows\System32\inetsrv下

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

  3. IIS 7中,[Domain\User]下,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 = ;
PCSTR pHeaderValue = (PCSTR) pHttpContext->AllocateRequestMemory( cbValue ); for(HTTP_HEADER_ID i = (HTTP_HEADER_ID); i < HttpHeaderRequestMaximum; i = (HTTP_HEADER_ID)((int)i + ))
{
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;
}

【小结】IIS7下的Http Native Module开发的更多相关文章

  1. react-native —— 在Windows下搭建React Native Android开发环境

    在Windows下搭建React Native Android开发环境 前段时间在开发者头条收藏了 @天地之灵_邓鋆 分享的<在Windows下搭建React Native Android开发环 ...

  2. 【转】在Windows下搭建React Native Android开发环境

    http://www.jianshu.com/p/2fdc4655ddf8 安装JDK 从Java官网下载JDK并安装.请注意选择x86还是x64版本. 推荐将JDK的bin目录加入系统PATH环境变 ...

  3. 手把手教你在Windows下搭建React Native Android开发环境

    最近看到React Native好像好厉害的样子,好奇心驱使之下体验了一下并将在Window下搭建React Natvie Android环境的步骤记录下来,并有需要的朋友参考.(我都是参考官方文档的 ...

  4. 一步一步在Windows下搭建React Native Android开发环境

    搭建JAVA开发环境 依据操作系统分为x86或x64位的.下载jdk1.8以上的版本号. 本机安装时的java版本号:jdk-8u45-windows-x64.exe 配置JAVA的环境变量 JAVA ...

  5. 在Windows下搭建React Native Android开发环境

    widows版本: win7 64位 专业版 1. 安装jdk.(我用的jdk7) 注意选择x86还是x64版本, 添加到系统PATH环境变量 2. 准备好android sdk 这个不多说,同时推荐 ...

  6. Windows下搭建React Native Android开发环境

    准备工作 安装JDK 安装Android SDK 安装C++环境 安装node.js 安装react-native命令行工具 创建项目 运行packager 运行模拟器 安卓运行 安卓调试 安装JDK ...

  7. 【RN - 基础】之Windows下搭建React Native开发环境

    前言 React Native由Facebook公司于2015年F8大会上开源,其主张“Learn once, write everywhere”.React Native的核心设计理念是:既拥有Na ...

  8. 【初探IONIC】不会Native可不可以开发APP?

    前言 Hybrid技术流行已经有一段日子了,楼主的关注点也一直围绕着移动端围绕着Hybrid相关展开,Hybrid已经是大大提升开发效率的开发方式了,但是仍然需要至少一个IOS与Andriod,那么可 ...

  9. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

随机推荐

  1. EOS 增发与生产者的奖励制度

    EOS每年增发1%的机制在系统合约中,其实说每年增发1%只是一年的总数,其实是只要在出块,EOS就在增发的路途中,下面分析一下增发的代码. 其实增发的1%的都是分给所有区块生产者的,只要出块了或者获得 ...

  2. CF912E Prime Gift 数学

    Opposite to Grisha's nice behavior, Oleg, though he has an entire year at his disposal, didn't manag ...

  3. xshell一直连接中断 守护进程

    last指令 重新登录使用last指令查看登录情况 pts的理解 who:查看目前有谁在线 pts是所谓的伪终端或虚拟终端,具体表现就是你打开一个终端,这个终端就叫pts/0,如果你再打开一个终端,这 ...

  4. Python语言、编译解释、动态库静态库、编译过程、头文件

    学习Python这门语言首先要了解 什么是编译与解释,什么是连接,什么是动态库与静态库, 什么是编译: 编译就是先把高级语言设计的程序翻译成二进制的机器语言,然后CPU直接执行机器码就可以了.一把翻译 ...

  5. windows 中使用 winscp 工具连接linux

    1.安装winscp 2.在linux系统中安装ssh,执行命令:sudo apt-get install openssh-server 3.连接成功

  6. IDEA中如何添加jar包

    File -> Project Structure -> Libraries -> + -> jar -> 选择classes

  7. docker(3)docker下的centos7下安装jdk

    1.将jdk-8u65-linux-x64.tar.gz文件传到docker的宿主机上 rz 2.将宿主机上的jdk-8u65-linux-x64.tar.gz复制到centos7的容器下 #在宿主机 ...

  8. pgadmin-linux-centos7.3-连接pgsql

    每次远程连接linux-centos上面的pgsql的时候,需要修改ip,命令如下: -->cd /var/lib/pgsql/data -->vi pg_hba.conf 添加ip如下, ...

  9. java将pdf转成base64字符串及将base64字符串反转pdf

    package cn.wonders.utils; import java.io.BufferedInputStream;import java.io.BufferedOutputStream;imp ...

  10. RedHat6.5安装MySQL5.7

    安装环境:RedHat6.5  第一步:下载 下载MySQL5.7:http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.12-1.el6.x8 ...