且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我如何安全地随机填充添加到所有的ASP.NET AJAX HTTPS的反应?

更新时间:2023-11-21 16:27:04

那么你可以创建一个过滤器将它发送到客户端之前修改响应。你所要做的就是创建一个IHttpModule的拦截和ASP.NET请求管道。您可以设置过滤器流,这将缓冲你的反应,并在结束时,ASP.NET管道将称之为关闭的方法,这时候你可以修改缓冲区,并发送回客户端。

Well you can create a filter to modify response before sending it to client. All you have to do is create a IHttpModule and intercept ASP.NET request pipeline. You can set Filter Stream, which will buffer your response, and at the end, ASP.NET pipeline will call "Close" method, that time you can modify buffer and send back to client.

要提高性能,还可以拦截写入方法和写入,而不是缓冲整个响应更好的逻辑。但我把它留给你。

To improve performance, you can also intercept Write method and write better logic instead of buffering whole response. But I will leave it on you.

首先设置你的web.config的,

First configure your web.config as,

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <add name="RandomPaddingModule"
             type="Namespace.RandomPaddingModule, AssemblyName"/>
    </modules>
</system.webServer>

和增加以下code

public class RandomPaddingModule : IHttpModule{

    public void Dispose()
    {
    }

    public void Init(HttpApplication context)
    {
        // Apply filter immediately
        context.BeginRequest += (s, e) =>
        {
            context.Response.Filter = 
               new RanndomPaddingStream(context.Response.Filter,
                   context.Context);

        };
    }

}


public class AtomPreCompilerStream : ResponseFilterStream
{

    private HttpContext context;

    public RanndomPaddingStream(Stream s, HttpContext c)
        : base(s)
    {
        this.context = c;
    }

    // process buffer before sending it to client...
    protected override byte[] ProcessBuffer(byte[] p)
    {

         if(string.Equals(
               context.Response.ContentType,
               "application/json", 
               StringComparison.OrdinalIgnoreCase)){
             // do some padding....
         }

         return p;
    }
}

public class ResponseFilterStream: Stream
{
    /// <summary>
    /// The original stream
    /// </summary>
    Stream _stream;


    /// <summary>
    /// Stream that original content is read into
    /// and then passed to TransformStream function
    /// </summary>
    MemoryStream _cacheStream = new MemoryStream(5000);

    public byte[] Buffer
    {
        get
        {
            return _cacheStream.ToArray();
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseStream"></param>
    public AtomPreCompilerFilterStream(Stream responseStream)
    {
        _stream = responseStream;
    }


    /// <summary>
    /// 
    /// </summary>
    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return true; }
    }
    /// <summary>
    /// 
    /// </summary>
    public override bool CanWrite
    {
        get { return true; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override long Length
    {
        get { return 0; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override long Position
    {
        get { return _cacheStream .Position; }
        set { _cacheStream .Position = value; }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="offset"></param>
    /// <param name="direction"></param>
    /// <returns></returns>
    public override long Seek(long offset, System.IO.SeekOrigin direction)
    {
        return _cacheStream.Seek(offset, direction);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="length"></param>
    public override void SetLength(long length)
    {
        _cacheStream .SetLength(length);
    }

    /// <summary>
    /// 
    /// </summary>
    public override void Close()
    {
        byte[] data = ProcessBuffer(_cacheStream.ToArray());
        _stream.Write(data, 0, data.Length);
        _stream.Close();
    }

    protected virtual byte[] ProcessBuffer(byte[] p)
    {
        return p;
    }

    /// <summary>
    /// Override flush by writing out the cached stream data
    /// </summary>
    public override void Flush()
    {

        // default flush behavior
        //_stream.Flush();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="offset"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    public override int Read(byte[] buffer, int offset, int count)
    {
        return _cacheStream.Read(buffer, offset, count);
    }


    /// <summary>
    /// Overriden to capture output written by ASP.NET and captured
    /// into a cached stream that is written out later when Flush()
    /// is called.
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="offset"></param>
    /// <param name="count"></param>
    public override void Write(byte[] buffer, int offset, int count)
    {
        _cacheStream.Write(buffer, offset, count);
        //_stream.Write(buffer, offset, count);

    }

}