您的位置:首页 > 理论基础 > 计算机网络

IHttpModule与IHttpHandler的区别和http请求处理过程,ihttpmodule,ihttphandler 处理流程

2016-01-26 11:39 615 查看
IHttpModule与IHttpHandler的区别主要有两点:

1.先后次序.先IHttpModule,后IHttpHandler.

2.对请求的处理上:

IHttpModule是属于大小通吃类型,无论客户端请求的是什么文件,都会调用到它;例如aspx,rar,html的请求.

IHttpHandler则属于挑食类型,只有ASP.net注册过的文件类型(例如aspx,asmx等等)才会轮到调用它.

IHttpHandler按照你的请求生成响应的内容,IHttpModule对请求进行预处理,如验证、修改、过滤等等,同时也可以对响应进行处理。

http请求处理过程,ihttpmodule,ihttphandler 处理流程

在以前的ASP时候,当请求一个*.asp页面文件的时候,这个HTTP请求首先会被一个名为inetinfo.exe进程所截获,这个进程实际上就是www服务。截获之后它会将这个请求转交给asp.dll进程,这个进程就会解释这个asp页面,然后将解释后的数据流返回给客户端浏览器。其实ASP.DLL是一个依附在IIS的ISAPI文件,它负责了对诸如ASP文件,ASA等文件的解释执行,

-------------------------------------

ASP.NET的HTTP请求处理方法

当客户端向web服务器请求一个*.aspx的页面文件时,同asp类似,这个http请求也会被inetinfo.exe进程截获(www服务),它判断文件后缀之后,把这个请求转交给ASPNET_ISAPI.DLL而ASPNET_ISAPI.DLL则会通过一个Http PipeLine的管道,将这个http请求发送给ASPNET_WP.EXE进程,当这个HTTP请求进入ASPNET_WP.EXE进程之后,asp.net framework就会通过HttpRuntime来处理这个Http请求,处理完毕后将结果返回给客户端。

------------------------------------

当一个http请求被送入到HttpRuntime之后,这个Http请求会继续被送入到一个被称之为HttpApplication Factory的一个容器当中,而这个容器会给出一个HttpApplication实例来处理传递进来的http请求,而后这个Http请求会依次进入到如下几个容器中:

HttpModule --> HttpHandler Factory --> HttpHandler

当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成了,客户端也就得到相应的东东了。

完整的http请求在asp.net framework中的处理流程:

HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

如果想在中途截获一个httpRequest并做些自己的处理,就应该在HttpRuntime运行时内部来做到这一点,确切的说时在HttpModule这个容器中做到这个的。

----------------------------------------

-------------------------------------

系统本身的HttpModule实现一个IHttpModule的接口,当然我们自己的类也能够实现IHttpModule接口,这就可以替代系统的HttpModule对象了。

ASP.NET系统中默认的HttpModule:
DefaultAuthenticationModule 确保上下文中存在 Authentication 对象。无法继承此类。

FileAuthorizationModule 验证远程用户是否具有访问所请求文件的 NT 权限。无法继承此类。

FormsAuthenticationModule 启用 ASP.NET 应用程序以使用 Forms 身份验证。无法继承此类。

PassportAuthenticationModule 提供环绕 PassportAuthentication 服务的包装。无法继承此类。

SessionStateModule 为应用程序提供会话状态服务。

UrlAuthorizationModule 提供基于 URL 的授权服务以允许或拒绝对指定资源的访问。无法继承此类。

WindowsAuthenticationModule 启用 ASP.NET 应用程序以使用 Windows/IIS 身份验证。无法继承此类
--------------------------------------

这些系统默认的HttpModule是在文件machine.config中配置的,和我们开发时使用到的web.config的关系是:是在ASP.NET FRAMEWORK启动处理一个Http Request的时候,它会依次加载machine.config和请求页面所在目录的web.config文件,如果在machine中配置了一个自己的HttpModule,你仍然可以在所在页面的web.config文件中remove掉这个映射关系。

public class HelloWorldModule : IHttpModule

{

public HelloWorldModule()

{

}
public String ModuleName

{

get { return "HelloWorldModule"; }

}
// In the Init function, register for HttpApplication

// events by adding your handlers.

public void Init(HttpApplication application)

{

application.BeginRequest +=

(new EventHandler(this.Application_BeginRequest));

application.EndRequest +=

(new EventHandler(this.Application_EndRequest));

}
private void Application_BeginRequest(Object source,

EventArgs e)

{

// Create HttpApplication and HttpContext objects to access

// request and response properties.

HttpApplication application = (HttpApplication)source;

HttpContext context = application.Context;

context.Response.Write("<h1><font color=red> HelloWorldModule: Beginning of Request</font></h1><hr>");

}
private void Application_EndRequest(Object source, EventArgs e)

{

HttpApplication application = (HttpApplication)source;

HttpContext context = application.Context;

context.Response.Write("<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>");

}
public void Dispose()

{

}

}
<system.web>

<httpModules>

<add name="HelloWorldModule" type="HelloWorldModule"/>

</httpModules>

</system.web>

-----------------------------------------------------------------------------------

深入HttpModule

一个Http请求在被ASP.NET Framework捕获之后会依次交给HttpModule以及HttpHandler来处理。hm与hh之间不是完全独立的,实际上,http请求在hm传递的过程中会在某个事件内将控制权转交给hh的,而真正的处理在HttpHandler中执行完成后,HttpHandler会再次将控制权交还给HttpModule

上面的代码中的HttpModule的Init()中的参数是HttpApplication类型,它具有许多事件,包括BeginRequest,EndRequest,AuthentiacteRequest 等等。

-----------------------------------------------------------------

IHttpHandler

它是asp.net Framework提供的一个接口,定义了如果要实现一个Http请求的处理所需要必须实现的一些系统约定。也就是说,如果你想要自行处理某些类型的HTTP请求信息流的话,你需要实现这些系统约定才能做到。譬如一个*.aspx文件,用来处理此类型的Http请求,ASP.NET FRAMEWORK将会交给一个名为System.Web.UI.PageHandlerFactory的HttpHandler类来处理。

HH和HM一样,系统会在最初始由ASP.NET FRAMEWORK首先加载machine.config中的HttpHandler,而后会加载Web应用程序所在目录的web.config中的用户自定义的HttpHandler类。但是系统与我们自定义的HH之间的关系是"覆盖"的,也就是说如果我们自定义了一个针对"*.aspx"的HttpHandler类的话,那么系统会将对此http请求的处理权完全交给我们自己定义的这个HttpHandler类来处理,而我们自己的HttpHandler类则需要自己完全解析这个Http请求,并作出处理。

IHttpHandler接口中最重要的方法ProcessRequest,这个方法就是HttpHandler用来处理一个Http请求,当一个Http请求经过由HttpModule容器传递到HttpHandler容器中的时候,framework会调用HttpHandler的ProcessRequest方法来做对这个Http请求做真正的处理。

framework实际上并不是直接把相关页面的HTTP请求定位到一个内部默认的IHttpHandler容器之上的,而是定位到了其 内部默认的IHttpHandler Factory上了。IHttpHandler Factory的作用就是对很多系统已经实现了的IHttpHandler容器进行调度和管理的,这样做的优点是大大增强了系统的负荷性,提升了效率。

我们用Asp.Net做出来的Web通常是.Aspx后缀的.但是,你希望能有其它属于自己的后缀吗?我们一起来研究研究!

首先谈谈ASP.net的一些参数传递和页面定向的方式

第一,ASP.net是用Page.Navigate()调用新页面的URL。Page.Navigate()向浏览器返回了一个http状态码302,使得浏览器向server请求那个新的URL。这种导航方法导致每次客户请求都需两次在client和server之间往返。

第二,任何要传递到新页面的信息都需作为URL的参数或存储在Session中或存储在数据库中以便新页面得到这些信息。传统的ASP开发人员很习惯这种做法,但其他的web编程人员则有一些更高级的方法。但是很明显的这两个页面是有依赖性的,而依赖性是编译器捕捉不到的也是不容易在设计阶段建模的。所以在debug时,参数是否被正确的传递就只有我们自己检查了。再有传统的数据传递方式有可能会暴露一些关键的数据。更为关键的是这使得面向对象的设计变得很复杂。

但是我们可以自定义httphandler来扩充这种支持。

要对HTTPMODULE和IHTTPHANDLER进行研究,必须先对ASP.NET的处理管道有一个了解。

在ASP.NET应用程序中,系统使用一组相关的类,通过一定的顺序来处理客户端的请求(REQUEST),ASP.NET应用程序的处理模式可称之为HTTP处理管道。

HTTPMODULE和IHTTPHANDLER就是这个处理管道上的两个处理环节。 HTTP处理管道中的类在SYSTEM.WEB名称空间中定义,主要有以下类型: HTTPWORKERREQUEST 抽象类定义了ASP.NET页面处理请求的基本方法;

HTTPRutime 提供了处理应用的一组服务;

HTTPContext 保存了处理一次请求的所有相关上下文信息;

HTTPApplicationFactory 提供相关目录的应用程序;

HTTPApplication 定义了所有ASP.NET应用程序的通用的方法、属性和事件。这个类也是在用户在GLOBAL.ASAX文件中定义的应用的基类;

Modules 处理请求前和响应后的事件;

Handlerfactories 提供应用程序中的HANDLERS;

Handlers 处理请求和响应。

在WINDOWS平台上,HTTP PIPLINE需要IIS的支持。为了运行ASP.NET应用,IIS需要以下两个文件:ASPNET_ISAPI.DLL和ASPNET_WP.EXE ASPNET_ISAPI.DLL是一个ISAPI EXTENTION他将发向IIS的请转交ASPNET_WP.EXE处理 ASPNET_WP.EXE使用HTTPRUNTIME对请求进行具体处理 处理的过程可以用图表示如下:

下面一个简单的例子来理解! 1). 建立一个名为SimpleHandler的工程,添加一个类MyHandler.cs,代码如下:

namespace SimpleHandler

{

public class MyHandler : IHttpHandler

{

public void ProcessRequest(HttpContext ctx)

{

HttpResponse response = ctx.Response;

response.Write(" My first Handler !");

}

public bool IsReusable

{

get { return true; }

}

}

}

2).将上面的代码编译,生成SimpleHandler.dll文件;

3).建立一个新的Web项目,将文件SimpleHandler.dll添加到项目的引用中;

4).修改Web.config,添加如下内容:

<system.web>

<httpHandlers>

<add verb="*" path="*.ASPX" type="SimpleHandler.MyHandler,SimpleHandler" />

</httpHandlers>

</system.web>

配置文件中的选项说明:

VERB可以是"GET"或"POST",表示对GET或POST的请求进行处理。

"*"表示对所有请求进行处理。

PATH指明对相应的文件进行处理,"*.ASPX"表示对发给所有ASPX页面的请求进行处理。可以指明路径,如"/TEST/*.ASPX",表明只对TEST目录下的ASPX文件进行处理。

TYPE属性中,逗号前的字符串指明HTTPHANDLER的实现类的类名,后面的字符串指明DLL文件的名称。

现在,请求项目中的任何ASPX页面,页面上显示的始终只有如下一行字:My first Handler !

因为,我们自定义的HANDLER截获了所有发向ASPX页面的请求,并且用自己的的方法来处理这些请求了。

为了使我们的字定义页面如: *.AAA能够顺利运行,我们需要修改WEB.CONFIG文件:

<system.web>

<httpHandlers>

<add verb="*" path="*.AAA" type="SimpleHandler.MyHandler,SimpleHandler" />

</httpHandlers>

</system.web>

为了让对后缀名为.AAA的文件的请求能够被我们的HANDLER截获运行,我们还需要一些额外的工作。打开IIS的管理控制台,又键单击站点,选择"属性",跳出站点的属性对话框。选择主目录选项,选择配置,弹出应用程序配置对话框,将".AAA"添加到应用程序映射中
.好了,我们现在可以在项目中添加一个.AAA文件,当向该文件发送请求时,浏览器显示: My first Handler ! 而对其他ASPX文件的访问不受影响。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: