【小结】IIS7下的Http Native Module开发
今天接到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开发的更多相关文章
- react-native —— 在Windows下搭建React Native Android开发环境
在Windows下搭建React Native Android开发环境 前段时间在开发者头条收藏了 @天地之灵_邓鋆 分享的<在Windows下搭建React Native Android开发环 ...
- 【转】在Windows下搭建React Native Android开发环境
http://www.jianshu.com/p/2fdc4655ddf8 安装JDK 从Java官网下载JDK并安装.请注意选择x86还是x64版本. 推荐将JDK的bin目录加入系统PATH环境变 ...
- 手把手教你在Windows下搭建React Native Android开发环境
最近看到React Native好像好厉害的样子,好奇心驱使之下体验了一下并将在Window下搭建React Natvie Android环境的步骤记录下来,并有需要的朋友参考.(我都是参考官方文档的 ...
- 一步一步在Windows下搭建React Native Android开发环境
搭建JAVA开发环境 依据操作系统分为x86或x64位的.下载jdk1.8以上的版本号. 本机安装时的java版本号:jdk-8u45-windows-x64.exe 配置JAVA的环境变量 JAVA ...
- 在Windows下搭建React Native Android开发环境
widows版本: win7 64位 专业版 1. 安装jdk.(我用的jdk7) 注意选择x86还是x64版本, 添加到系统PATH环境变量 2. 准备好android sdk 这个不多说,同时推荐 ...
- Windows下搭建React Native Android开发环境
准备工作 安装JDK 安装Android SDK 安装C++环境 安装node.js 安装react-native命令行工具 创建项目 运行packager 运行模拟器 安卓运行 安卓调试 安装JDK ...
- 【RN - 基础】之Windows下搭建React Native开发环境
前言 React Native由Facebook公司于2015年F8大会上开源,其主张“Learn once, write everywhere”.React Native的核心设计理念是:既拥有Na ...
- 【初探IONIC】不会Native可不可以开发APP?
前言 Hybrid技术流行已经有一段日子了,楼主的关注点也一直围绕着移动端围绕着Hybrid相关展开,Hybrid已经是大大提升开发效率的开发方式了,但是仍然需要至少一个IOS与Andriod,那么可 ...
- Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)
文章目录: 1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...
随机推荐
- kuangbin专题七 ZOJ1610 Count the Colors (灵活线段树)
Painting some colored segments on a line, some previously painted segments may be covered by some th ...
- Set\HashSet集合为什么能去重(转)
如果想查找一个集合中是否包含有某个对象,大概的程序代码怎样写呢?当发现某个元素与要查找的对对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则返回否定的信息.如果是一个集合中 ...
- c++中STL中的next_permutation函数基本用法
对于next_permutation函数是针对于排列组合问题的库函数,它的排序方式是按照字典的方式排列的·: 如以下代码对于next_permutation函数的初步解释: #include<c ...
- Codeforces Round #334(div.2)(新增不用二分代码) B
B. More Cowbell time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- 求js数组的最大值和最小值
数组 ,,,,,,,,,]; 方法1 - 字符串拼接法 利用toString或join把数组转换为字符串,再和Math的max和min方法分别进行拼接,最后执行eval方法 var max = eva ...
- Problem09 求完数
题目:一个数如果恰好等于它的因子之和,这个数就称为"完数". 分析:例如6=1+2+3. 编程找出1000以内的所有完数. 假如整数n除以m,结果是无余数的整数,那么我们称m就是n ...
- Dev Express Report 学习总结(五)在分组中使用聚集表达式AggregateExpression
聚集表达式AggregateExpression主要包括几种:Avg(),Count(),Exists(),Max(),Min(),Single()和Sum().其中对于Sum(),在我看来主要有两种 ...
- JavaSE---位运算符
1.Java支持的位运算符有7个: &:按位与 [2个相同取相同.2个不同取0] |:按位或 [2个相同取相同.2个不同取1] ~:按位非 ^:按位异或 [2个相同取0.2个不同取1] < ...
- JavaSE---对象序列化
1.对象序列化机制 允许把内存中的Java对象转换成平台无关的二进制流,从而可以将二进制流持久保存到磁盘 或 在网络中直接传输: (目的:使得对象可以脱离程序的运行而独立存在) package com ...
- 以多进程读取oss符合条件的数据为例,综合使用多进程间的通信、获取多进程的数据
import datetime import sys import oss2 from itertools import islice import pandas as pd import re im ...