在Module中使用自定义过滤器,来统一对站内所有请求响应的输出内容进行采集或更改。 因项目需要,对每一个访问网站的请求要做原始数据记录,其中要包括几个要素:
1.客户端的IP
2.客户端请求的页面路径
3.客户端发出的请求头
4.服务器返回的正文内容。
在代码设计前分析了一下,前三个都很好解决,对于截获服务器返回的正文,准备用HttpResponse 对象中的Output 和 OutputStream 属性输出信息来解决。
可是在正式编码的过程中,发现Output和OutputStream 并不是想像中可以直接把数据转出取回,耗费了近两天的时间,想尽了一切办法可还是仅仅可以追加内容并无法读取。
在网上查阅到,对于HttpResponse 对象,仅仅可以使用过滤器来对其中将要输出的内容进行修改。
这个过滤器要继承自Stream 类,并要实现其中的虚方法。看来之前企图使用HttpWriter,TextWriter,Stream,HttpStream 这些类来转出数据完全是错误的。
现在有信心来截获服务器返回内容了,说干就干吧!
1.首先要建立一个简易过滤器。
代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
/**////
/// 定义原始数据EventArgs,便于在截获完整数据后,由事件传递数据
///
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;
/**////
/// 当原始数据采集成功后激发。
///
public event EventHandler OnRawDataRecordedEvent;
public RawFilter(Stream inputStream)
{
responseStream = inputStream;
responseHtml = new StringBuilder();
}
//实现Stream 虚方法
Filter Overrides#region 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);
}
#endregion
//关键的点,在HttpResponse 输入内容的时候,一定会调用此方法输入数据,所以要在此方法内截获数据
public override void Write(byte[] buffer, int offset, int count)
{
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
//采用正则,检查输入的是否有页面结束符