惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
爱范儿
爱范儿
罗磊的独立博客
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
Netflix TechBlog - Medium
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
U
Unit 42
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
H
Help Net Security
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理

博客园 - peace

MYSQL分页存储过程及事务处理 审批流设计方案的探究 WEB项目(B/S系统)打包安装(总结篇) 文件上传之断点续传方案 再次分享一个多选文件上传方案 SQL SERVER里的赋值机制闲聊 FLEX4.0开发流媒体视频播放器(总结篇) 告别ADO.NET实现应用系统无缝切换的烦恼(总结篇) SQL SERVER行转列应用小结 SQL SERVER函数——表值函数的处理 纠正网上流传的SQL取某一时间的当月第一天和最后一天的时间写法 SQL SERVER游标操作 告别.NET生成报表统计图的烦恼 发现联想手机P630型号的一个严重的系统Bug thinkpad T400型号安装server2003系统驱动共享 分享一个.NET版的多选文件上传操作示例 JS给页面标签添加事件(或超链接链接) 让默认焦点的按钮无虚框(又来无聊了) 利用ASP.NET日期控件制作“会议日程安排”(贴首页过把瘾)
一个简单的httpModule应用
peace · 2009-01-09 · via 博客园 - peace

     本来标题应该加上输出过滤的,想想还是不加好了,看了老赵的关于整站关键字过滤的文章,感觉还晕乎,以前也没怎么用过httpModule这东西,在网上看了下相关的文章,讲的还是比较多的,看到一篇关于输出过滤的文章,原文地址是http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html 基本还算能看明白,呵呵,我这个算是转载吧。

     原文的输出过滤主要是通过ReleaseRequestState这个事件来处理的,即执行完所有请求事件处理后发生,也就是请求处理全部结束后再进行过滤,这么一来截获的是整个page的html源文件了,然后对源文件内容进行特殊字符替换过滤处理(当然在替换前可以将原内容进行相关写入操作保存起来),捕获完成是以"</html>"为标志,因为最终在浏览器中呈现的html文件内容都是以"</html>"结尾的。把输出过滤的处理类贴下面(保留原作者注释同时也加了几句注释,另外注释掉的部分代码是将替换前的原替换前的html内容保存处理)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Reflection;
using System.Text.RegularExpressions;
using System.IO;
namespace httpModuleOutputFilter
{
public class OutputFilter : IHttpModule
    {
        
private HttpApplication _contextApplication;
        
public void Init(HttpApplication context)
        {
            _contextApplication 
= context;
            
//绑定事件,在对此请求处理过程全部结束后进行过滤操作
            context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);

        }

public void Dispose()
        {
            _contextApplication 
= null;
            _contextApplication.Dispose();
        }
/**/
        
/// <summary>
        
/// 对此HTTP请求处理的过程全部结束
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        void context_ReleaseRequestState(object sender, EventArgs e)
        {
            HttpApplication application 
= (HttpApplication)sender;//这里需要针对ASPX页面进行拦截
            string[] temp = application.Request.CurrentExecutionFilePath.Split('.');
            
if (temp.Length > 0 && temp[temp.Length - 1].ToLower() == "aspx")
            {
                
//装配过滤器
                application.Response.Filter = new RawFilter(application.Response.Filter);//绑定过滤器事件
                
//RawFilter filter = (RawFilter)application.Response.Filter;
                
//filter.OnRawDataRecordedEvent += new EventHandler<RawDataEventArgs>(filter_OnRawDataRecordedEvent);
            }
        }
/**/
        
/// <summary>
        
/// 当原始数据采集到以后,入库 
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        void filter_OnRawDataRecordedEvent(object sender, RawDataEventArgs e)
        {
            
string allcode = e.SourceCode;//allcode就是截获的替换前的整个page页面的html
            
//WapSite.SiteDataClass wapdata = new WapSite.SiteDataClass();
            
//wapdata.WriteRawDataLog(allcode);
        }

    }

/**//// <summary>
    
/// 定义原始数据EventArgs,便于在截获完整数据后,由事件传递数据
    
/// </summary>
    public class RawDataEventArgs : EventArgs
    {
        
private string sourceCode;public RawDataEventArgs(string SourceCode)
        {
            sourceCode 
= SourceCode;
        }
        
public string SourceCode
        {
            
get { return sourceCode; }
            
set { sourceCode = value; }
        }
    }
//自定义过滤器
    public class RawFilter : Stream
    {

        Stream responseStream;

long position;
        StringBuilder responseHtml;
/**//// <summary>
        
/// 当原始数据采集成功后激发。
        
/// </summary>
        public event EventHandler<RawDataEventArgs> OnRawDataRecordedEvent;public RawFilter(Stream inputStream)
        {
            responseStream 
= inputStream;
            responseHtml 
= new StringBuilder();
        }
//实现Stream 虚方法Filter Overrides

        
public override bool CanRead
        {
            
get
            {
                
return true;
            }
        }
public override bool CanSeek
        {
            
get
            {
                
return true;
            }
        }
public override bool CanWrite
        {
            
get
            {
                
return true;
            }
        }
        
public override void Close()
        {
            responseStream.Close();
        }
public override void Flush()
        {
            responseStream.Flush();
        }
public override long Length
        {
            
get
            {
                
return 0;
            }
        }
public override long Position
        {
            
get
            {
                
return position;
            }
            
set
            {
                position 
= value;
            }
        }
public override int Read(byte[] buffer, int offset, int count)
        {
            
return responseStream.Read(buffer, offset, count);
        }
public override long Seek(long offset, SeekOrigin origin)
        {
            
return responseStream.Seek(offset, origin);
        }
public override void SetLength(long length)
        {
            responseStream.SetLength(length);
        }
//关键的点,在HttpResponse 输入内容的时候,一定会调用此方法输入数据,所以要在此方法内截获数据
        public override void Write(byte[] buffer, int offset, int count)
        {
            
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);//采用正则,检查输入的是否有页面结束符</html>
            Regex eof = new Regex("</html>", RegexOptions.IgnoreCase);if (!eof.IsMatch(strBuffer))
            {
              
//页面没有输出完毕,继续追加内容
                responseHtml.Append(strBuffer);
            }
            
else
            {
              
//页面输出已经完毕,截获内容
                responseHtml.Append(strBuffer);
                
string finalHtml = responseHtml.ToString();//激发数据已经获取事件
                
//OnRawDataRecordedEvent(this, new RawDataEventArgs(finalHtml));//finalHtml就是源文件内容//继续传递要发出的内容写入流
                byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml.Replace("城管","**"));//测试 捕获的源文件内特殊字符容替换后输出

                responseStream.Write(data, 
0, data.Length);
            }
        }
    }
}

    上面就是一个httpModule的简单应用了,至于这个方案的其它方面我就不说了,也不好说,主要是大家能看得明白这个简单的httpModule应用就好,另外在web项目的里添加编译好的httpModule.dll引用,还有config里加一句<httpModules>
        <add name="OutputFilter" type="httpModuleOutputFilter.OutputFilter, httpModule" />
      </httpModules>

 测试demo下载地址 :httpModule示例下载

       转载的原文地址:查看原文