这已经是系列的第13篇了,实际上到现在为止您应该对BlogEngine.Net的整体设计有了一定的把握,对部分实现细节有了比较深刻的认识,在阅读BlogEngine.Net时希望坚持到最后,并把握住宏观,深入到微观。本文将详细介绍BlogEngine.Net中的HttpHandlers与HttpModules,主要说明它们要实现的功能以及如何使用,并对几个必要的HttpHandler或HttpModule进行比较细致的分析。

HttpHandler和HttpModule

对于HttpHandler和HttpModule我这里不想多说了,因为关于它们讲解的文章实在太多太多了,大家可以在博客园的找找看中直接输入“HttpHandler和HttpModule”就可以找到。我的理解就是一个HttpHandler要实现IHttpHandler接口,主要是对某个请求进行直接处理,一个HttpModule要实现IHttpModule接口,主要是在HttpApplication的生命周期的事件中对请求和响应进行过滤。它们都可以在Web.config文件中进行配置。

BlogEngine.Net中的HttpHandler

BlogEngine.Net中的HttpHandler都在BlogEngine.Core.Web.HttpHandlers空间下(除了MetaWeblogHandler,已经讲过,这里就不包含它了),通过Web.config我们可以看到它们的映射关系:

HttpHandlers映射表
<httpHandlers>
    <add verb="*" path="file.axd" type="BlogEngine.Core.Web.HttpHandlers.FileHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="image.axd" type="BlogEngine.Core.Web.HttpHandlers.ImageHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="syndication.axd" type="BlogEngine.Core.Web.HttpHandlers.SyndicationHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="sitemap.axd" type="BlogEngine.Core.Web.HttpHandlers.SiteMap, BlogEngine.Core" validate="false"/>
    <add verb="*" path="trackback.axd" type="BlogEngine.Core.Web.HttpHandlers.TrackbackHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="pingback.axd" type="BlogEngine.Core.Web.HttpHandlers.PingbackHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="opensearch.axd" type="BlogEngine.Core.Web.HttpHandlers.OpenSearchHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="metaweblog.axd" type="BlogEngine.Core.API.MetaWeblog.MetaWeblogHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="rsd.axd" type="BlogEngine.Core.Web.HttpHandlers.RsdHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="css.axd" type="BlogEngine.Core.Web.HttpHandlers.CssHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="js.axd" type="BlogEngine.Core.Web.HttpHandlers.JavaScriptHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="rating.axd" type="BlogEngine.Core.Web.HttpHandlers.RatingHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="opml.axd" type="BlogEngine.Core.Web.HttpHandlers.OpmlHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="blogml.axd" type="BlogEngine.Core.Web.HttpHandlers.BlogMLExportHandler, BlogEngine.Core" validate="false"/>
    <add verb="*" path="sioc.axd" type="BlogEngine.Core.Web.HttpHandlers.Sioc, BlogEngine.Core" validate="false"/>
    <add verb="*" path="apml.axd" type="BlogEngine.Core.Web.HttpHandlers.Apml, BlogEngine.Core" validate="false"/>
    <add verb="*" path="foaf*.axd" type="BlogEngine.Core.Web.HttpHandlers.Foaf, BlogEngine.Core" validate="false"/>
</httpHandlers>

下面对它们进行一一描述:

FileHandler:主要完成对于一些物理文件的请求,例如在文章中插入的文件资源的请求就由它来处理。它的实现比较简单,就直接去磁盘的文件保存目录中读取,我们只要留意一下SetContentType就行了。

ImageHandler:与FileHandler类似,不过它处理的是图片。与FileHandler分开的原因主要就是图片需要在页面上展现(ContentType必须给浏览器讲清楚或采用默认)。

SyndicationHandler:它比较复杂,主要完成各种订阅需求的处理,需要结合SyndicationFormat(格式枚举)和SyndicationGenerator(按照SyndicationFormat的格式生成XML)一起使用。我们可以看一下它的实现过程,首先根据请求的查询字符串生成标题,格式,列表(GenerateItemList使用了Search等),使用CleanList进行了一个过滤,分页处理,SetHeader,最后使用SyndicationGenerator的WriteFeed进行了输出。这里考虑的情况比较多,但是BlogEngine.Net使用的分割方法很好的解决了复杂的订阅问题,值得研究一下。

SiteMap:网站地图,可以给一些搜索引擎提供更好的搜索信息,以XML格式将一些文章等页面的链接输出。

TrackbackHandler:接收Trackback信息的处理,前文已经讲过,这里不多说了。

PingbackHandler:接收Pingback信息的处理,前文已经讲过,这里也不多说了。

OpenSearchHandler:提供公开搜索处理,前文已经讲过,这里也不多说了。

RsdHandler:这个处理器很有用,它完成将BlogEngine.Net中的一些公开的接口等信息发布出去,类似WebService的WSDL文件。

CssHandler:主要处理了页面中的Css文件的压缩,上文中讲述BlogBasePage中提及过。处理器的实现很值得关注,压缩可以使用gzip或deflate两种格式,

经典的压缩处理
 1private const string GZIP = "gzip";
 2private const string DEFLATE = "deflate";
 3
 4private static void Compress(HttpContext context)
 5{
 6    if (context.Request.UserAgent != null && context.Request.UserAgent.Contains("MSIE 6"))
 7        return;
 8
 9    if (IsEncodingAccepted(GZIP))
10    {
11        context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
12        SetEncoding(GZIP);
13    }
14    else if (IsEncodingAccepted(DEFLATE))
15    {
16        context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
17        SetEncoding(DEFLATE);
18    }
19}

并提供了一些事件供外界Hookup处理。压缩之前去掉空格等字符,分为从本地获得文件和从远程使用WebClient下载文件。并使用了缓存。

JavaScriptHandler:主要处理页面中引用的脚本的压缩,与Css处理方式类似。注意StripWhitespace的处理与Css的不同。

RatingHandler:主要完成给Post打分的功能,记得上文中有部分涉及到,从PostViewBase中的Rating可以看出,这个请求实际上是通过Ajax发送过来的。

OpmlHandler:获得OPML列表文件,类似收藏文章的列表。

BlogMLExportHandler:BlogEngine.Net中的文章导出处理,以前的文章讲过。

Sioc、Foaf、Apml的注释都是“Based on John Dyer's (http://johndyer.name/) extension.”,这个应该是对于某个标准XML的输出吧,主要提供了本博客系统中的一些公开的信息。关于它们不做太多的研究,我想这并不影响我们对BlogEngine.Net的研究。

实际上这些HttpHandlers的请求链接很多都是在BlogBasePage加入到Html的Head中的,或者给浏览器使用,或者给搜索引擎使用。

BlogEngine.Net中的HttpModule

BlogEngine.Net中的HttpModule都在BlogEngine.Core.Web.HttpModules空间下,通过Web.config我们可以看到它们的映射关系:

httpModules映射表
<httpModules>
    <add name="WwwSubDomainModule" type="BlogEngine.Core.Web.HttpModules.WwwSubDomainModule, BlogEngine.Core"/>
    <add name="UrlRewrite" type="BlogEngine.Core.Web.HttpModules.UrlRewrite, BlogEngine.Core"/>
    <add name="CompressionModule" type="BlogEngine.Core.Web.HttpModules.CompressionModule, BlogEngine.Core"/>
    <add name="ReferrerModule" type="BlogEngine.Core.Web.HttpModules.ReferrerModule, BlogEngine.Core"/>
    <!--Remove the default ASP.NET modules we don't need-->
    <remove name="PassportAuthentication"/>
    <remove name="Profile"/>
    <remove name="AnonymousIdentification"/>
</httpModules>

请注意它们的注册顺序,因为WwwSubDomainModule和UrlRewrite都Hookup了HttpApplication的BeginRequest事件。下面对它们进行一一描述:

WwwSubDomainModule:Hookup了HttpApplication的BeginRequest事件,主要是对请求的URL中的"www"的处理以得到绝对的链接。

UrlRewrite:Hookup了HttpApplication的BeginRequest事件,对一些URL的重写,实际上WwwSubDomainModule和UrlRewrite都是在处理URL,我们在看BlogEngine.Net中的源代码时多留意一下它的URL,包括Post中的各种链接的URL等,注意区分它们都是做什么用的。

ReferrerModule:主要是对于请求的Referrer进行统计,纪录这些请求都是从哪里发送来的,提供了相应的事件供外部Hookup,注意IsSpam的实现和对于纪录日志使用了新线程来异步完成。

CompressionModule:一个Page页面的压缩处理模块,同样根据请求来判断是使用gzip还是deflate,对于页面中链接的WebResource也是用WebResourceFilter进行了过滤处理,WebResourceFilter实现了Stream,

WebResourceFilter的Write方法
 1public override void Write(byte[] buffer, int offset, int count)
 2{
 3    byte[] data = new byte[count];
 4    Buffer.BlockCopy(buffer, offset, data, 0, count);
 5    string html = System.Text.Encoding.Default.GetString(buffer);
 6
 7    Regex regex = new Regex("<script\\s*src=\"((?=[^\"]*webresource.axd)[^\"]*)\"\\s*type=\"text/javascript\"[^>]*>[^<]*(?:</script>)?", RegexOptions.IgnoreCase);
 8    foreach (Match match in regex.Matches(html))
 9    {
10        string relative = match.Groups[1].Value;
11        string absolute = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
12        html = html.Replace(relative, Utils.RelativeWebRoot + "js.axd?path=" + HttpUtility.UrlEncode(absolute + relative));
13    }
14
15    byte[] outdata = System.Text.Encoding.Default.GetBytes(html);
16    _sink.Write(outdata, 0, outdata.GetLength(0));
17}

在重写的Write中主要是将webresource.axd转交给了JavaScriptHandler处理以达到压缩的目的。注意它是在PreRequestHandlerExecute中Hookup的,都是给Response提供的流过滤器。

总结

由于篇幅所限,对于BlogEngine.Net中一些HttpHandlers和HttpModules我并没有作更多的深入讨论,这里只是提供给大家一个学习指南,希望有所帮助。BlogEngine.Net中大量使用了正则匹配,Url处理,压缩,缓存等都是比较通用的,值得我们关注与学习。

通用的处理方法值得我们去收藏

上一篇:BlogEngine.Net架构与源代码分析系列part12:页面共同的基类——BlogBasePage

下一篇:BlogEngine.Net架构与源代码分析系列part14:实现分析(下)——网站页面上值得参考的部分

返回到目录

转载于:https://www.cnblogs.com/Thriving-Country/archive/2008/11/13/1332659.html

BlogEngine.Net架构与源代码分析系列part13:实现分析(上)——HttpHandlers与HttpModules...相关推荐

  1. BlogEngine.Net架构与源代码分析系列(转载)

    01.BlogEngine.Net架构与源代码分析系列part1:开篇介绍 02.BlogEngine.Net架构与源代码分析系列part2:业务对象--共同的父类BusinessBase 03.Bl ...

  2. BlogEngine.Net架构与源代码分析系列part12:页面共同的基类——BlogBasePage

    上一篇文章我向大家展示了BlogEngine.Net中Theme的原理和一些开发规范,里面有很多内容和这篇文章有着联系,建议大家这两篇文章结合在一起看,这样效果会更好.在这篇文章中我主要向大家说明Bl ...

  3. [循证理论与实践] meta分析系列之一: meta分析的类型

    证据是循证医学( Evidence-based medcine,EBM) 的核心,基于随机对照试验( RCT) 的系统评价/meta分析是当前 公认的最高级别证据. meta分析在医学领域应用最为广泛 ...

  4. BlogEngine.Net架构与源代码分析系列索引贴

    http://www.cnblogs.com/Thriving-Country/category/166792.html

  5. 病毒分析系列 _ 病毒分析环境搭建

    前言 通常进行病毒分析,需要有一个配置好的病毒分析环境,fireeye之前也出过配置好的虚拟机,但是虚拟机安装过程很慢,不如我们自己配置一个,下边对虚拟机的配置和病毒分析的基本原则进行展开说明,打好病 ...

  6. python股票分析系列_Python股票分析系列——基础股票数据操作(一)

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第3部分.在本教程中,我们将使用我们的股票数据进一步分解一些基本的数据操作和可视化.我们将要使用 ...

  7. python股票分析系列_Python股票分析系列——基础股票数据操作(一).p3

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第3部分.在本教程中,我们将使用我们的股票数据进一步分解一些基本的数据操作和可视化.我们将要使用 ...

  8. python股票分析系列_Python股票分析系列——基础股票数据操作(二).p4

    该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第4部分.在本教程中,我们将基于Adj Close列创建烛台/ OHLC图,这将允许我介绍重新采 ...

  9. MyBatis架构设计及源代码分析系列(一):MyBatis架构

    一.概述 MyBatis并不是一个完整的ORM框架,其官方首页是这么介绍自己 The MyBatis data mapper framework makes it easier to use a re ...

  10. Quartz.NET 架构与源代码分析系列 part 2 :Job 作业

    在上一篇Quartz.NET 架构与源代码分析系列 part 1 :Quartz.NET 入门我们介绍了Quartz.NET 的基本知识和简单的应用,可以看出来它的使用是非常简单的,只要短短的几行代码 ...

最新文章

  1. 管理数百个Kubernetes集群需要什么?
  2. 香港中文大学(深圳)罗元教授招收计算机与信息工程全奖博士
  3. search result
  4. 三、CXF对Interceptor拦截器的支持
  5. MySQL 语句的执行顺序
  6. centOS 7 yum安装MySQL5.6
  7. 51单片机c语言数字输入输出,第五章 51单片机C语言程序--输入输出接口.pdf
  8. ABAP开发中常用的两个F4搜索帮助函数的区别
  9. CodeForces - 1363E Tree Shuffling(树上贪心)
  10. IMYAOPTableView 源码学习笔记
  11. c语言link错误什么原因,C语言 OpenCV错误:“LINK:致命错误LNK1104:无法打开文件’opencv_core231d.lib’”...
  12. P - C语言实验——某年某月的天数
  13. JS中var和let
  14. 华为三层交换机之基本操作
  15. 计算机网络原理_第8章 局域网技术 之二 令牌环
  16. Pandas各种骚操作
  17. lc谐振计算机网络,LC谐振回路解析,LC谐振回路的选频特性
  18. 应试教育与理想教育之间
  19. 通俗讲解分布式锁:场景和使用方法
  20. eclipse快捷操作(如何更加便捷的使用eclipse来编程:持续更新)

热门文章

  1. 轻松了解模型评价指标
  2. 资源 | 有没有必要把机器学习算法自己实现一遍?
  3. Sublime Text安装与配置教程
  4. 数据结构与算法python—10.二叉树题目leetcode总结
  5. Python字符串中常用的方法
  6. 设计艺术学院院长 读《未来产品的设计》这本书
  7. Scala:数据类型和变量
  8. 计算机领域国际会议分类及排名
  9. sar分辨率公式_购买SAR卫星三个重要参数:分辨率、极化方式、入射角
  10. jmeter 登录用户并发压力测试案例_用jmeter进行多用户并发压力测试 [转]