cefsharp 拦截所有请求 解决chunked导致数据接收不完整的问题

拦截请求需要实现两个接口

  1. IRequestHandler 对请求进行自定义处理
  2. IResponseFilter 对response进行处理
    cef官方文档

实现了IRequestHandler 以后需要给浏览器绑定
例:

broswer.RequestHandler = new CEFRequestHandler();

tips:

  1. 在request中的GetResourceResponseFilter方法进行检测
public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
    var url = new Uri(request.Url);
    if (url.AbsoluteUri.Contains("http://www.baidu.com"))
    {
        //自定义的IResponseFilter,这里是按照官方文档的示例
        var filter = CEFFilterManger.CreateFilter(request.Identifier.ToString());
        return filter;
    }
    return null;
}

IResponseFilter

public abstract class CEFResponseHandle : IResponseFilter
    {
        public string URI { get; set; }
        public List<byte> dataAll = new List<byte>();

        public string DataStr
        {
            get
            {
                return Encoding.UTF8.GetString(dataAll.ToArray());
            }
        }

       
        public void Dispose()
        {
        }

        public abstract void Invoke();

        public FilterStatus Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
        {
            try
            {

                if (dataIn == null || dataIn.Length == 0)
                {
                    dataInRead = 0;
                    dataOutWritten = 0;

                    //string resultResponse = System.Text.Encoding.UTF8.GetString(dataAll.ToArray());

                    //try
                    //{
                    //    JsonOper.ToObject<Dictionary<string, object>>(DataStr);
                    //}
                    //catch (Exception e)
                    //{
                    //    return FilterStatus.NeedMoreData;
                    //}

                    return FilterStatus.Done;
                }
                //解决Transfer-Encoding: chunked数据不全的问题
                if (dataIn.Length > dataOut.Length)
                {
                    var data = new byte[dataOut.Length];
                    dataIn.Seek(0, SeekOrigin.Begin);
                    dataIn.Read(data, 0, data.Length);
                    dataOut.Write(data, 0, data.Length);

                    dataInRead = dataOut.Length;
                    dataOutWritten = dataOut.Length;

                    dataAll.AddRange(data);
                }
                else
                {
                    dataInRead = dataIn.Length;
                    dataOutWritten = Math.Min(dataInRead, dataOut.Length);

                    dataIn.CopyTo(dataOut);
                    dataIn.Seek(0, SeekOrigin.Begin);
                    byte[] bs = new byte[dataIn.Length];
                    dataIn.Read(bs, 0, bs.Length);
                    dataAll.AddRange(bs);

                    dataInRead = dataIn.Length;
                    dataOutWritten = dataIn.Length;
                }

                return FilterStatus.NeedMoreData;
            }
            catch (Exception ex)
            {
                dataInRead = dataIn.Length;
                dataOutWritten = dataIn.Length;

                return FilterStatus.Done;
            }
        }


        public bool InitFilter()
        {
            return true;
        }
    }
posted @ 2020-04-24 16:50  Hey,Coder!  阅读(2285)  评论(0编辑  收藏  举报