今天接到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. kuangbin专题七 ZOJ1610 Count the Colors (灵活线段树)

    Painting some colored segments on a line, some previously painted segments may be covered by some th ...

  2. Set\HashSet集合为什么能去重(转)

    如果想查找一个集合中是否包含有某个对象,大概的程序代码怎样写呢?当发现某个元素与要查找的对对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则返回否定的信息.如果是一个集合中 ...

  3. c++中STL中的next_permutation函数基本用法

    对于next_permutation函数是针对于排列组合问题的库函数,它的排序方式是按照字典的方式排列的·: 如以下代码对于next_permutation函数的初步解释: #include<c ...

  4. Codeforces Round #334(div.2)(新增不用二分代码) B

    B. More Cowbell time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  5. 求js数组的最大值和最小值

    数组 ,,,,,,,,,]; 方法1 - 字符串拼接法 利用toString或join把数组转换为字符串,再和Math的max和min方法分别进行拼接,最后执行eval方法 var max = eva ...

  6. Problem09 求完数

    题目:一个数如果恰好等于它的因子之和,这个数就称为"完数". 分析:例如6=1+2+3. 编程找出1000以内的所有完数. 假如整数n除以m,结果是无余数的整数,那么我们称m就是n ...

  7. Dev Express Report 学习总结(五)在分组中使用聚集表达式AggregateExpression

    聚集表达式AggregateExpression主要包括几种:Avg(),Count(),Exists(),Max(),Min(),Single()和Sum().其中对于Sum(),在我看来主要有两种 ...

  8. JavaSE---位运算符

    1.Java支持的位运算符有7个: &:按位与 [2个相同取相同.2个不同取0] |:按位或 [2个相同取相同.2个不同取1] ~:按位非 ^:按位异或 [2个相同取0.2个不同取1] < ...

  9. JavaSE---对象序列化

    1.对象序列化机制 允许把内存中的Java对象转换成平台无关的二进制流,从而可以将二进制流持久保存到磁盘 或 在网络中直接传输: (目的:使得对象可以脱离程序的运行而独立存在) package com ...

  10. 以多进程读取oss符合条件的数据为例,综合使用多进程间的通信、获取多进程的数据

    import datetime import sys import oss2 from itertools import islice import pandas as pd import re im ...