Exemplo n.º 1
0
            /// <summary>收到客户端发来的数据。子类可通过重载该方法来修改数据</summary>
            /// <param name="e"></param>
            /// <returns>修改后的数据</returns>
            protected override void OnReceiveRemote(ReceivedEventArgs e)
            {
                var pxy         = Host as HttpProxy;
                var parseHeader = pxy.EnableCache || pxy.GetHandler(EventKind.OnResponse) != null;
                var parseBody   = pxy.EnableCache || pxy.GetHandler(EventKind.OnResponseBody) != null;

                var entity = UnFinishedResponse;
                var stream = e.Packet.GetStream() as Stream;

                if (parseHeader || parseBody)
                {
                    #region 解析响应头
                    // 解析头部
                    if (entity == null)
                    {
                        #region 未完成响应为空,可能是第一个响应包,也可能是后续数据包
                        // 如果当前未完成响应为空,说明这是第一个数据包,可能包含头部
                        entity = HttpHeader.Read(stream, HttpHeaderReadMode.Response);
                        if (entity == null)
                        {
                            var he = new HttpProxyEventArgs(Response, stream);
                            if (pxy.RaiseEvent(this, EventKind.OnResponseBody, he))
                            {
                                return;
                            }
                            //e.Stream = he.Stream;
                            e.Packet = he.Stream.ReadBytes();

                            // 如果现在正在缓存之中,那么也罢这些非头部数据一并拷贝到缓存里面
                            if (cacheItem != null)
                            {
                                var ms = e.Packet.GetStream();
                                var p  = ms.Position;
                                ms.CopyTo(cacheItem.Stream);
                                var count = ms.Position = p;
                                ms.Position = p;
                                //WriteDebugLog("[{0}] {1} 缓存数据[{2}]", ID, Request.RawUrl, count);
                            }

                            base.OnReceiveRemote(e);
                            return;
                        }

                        if (!entity.IsFinish)
                        {
                            UnFinishedResponse = entity;
                        }
                        else
                        {
                            Response = entity;
                        }
                        #endregion
                    }
                    else if (!entity.IsFinish)
                    {
                        #region 未完成响应,继续读取头部
                        // 如果请求未完成,说明现在的数据内容还是头部
                        entity.ReadHeaders(stream);
                        if (entity.IsFinish)
                        {
                            Response           = entity;
                            UnFinishedResponse = null;
                        }
                        #endregion
                    }
                    else
                    {
                        #region 未完成响应的头部已完成?似乎不大可能
                        // 否则,头部已完成,现在就是内容
                        var he = new HttpProxyEventArgs(Response, stream);
                        if (pxy.RaiseEvent(this, EventKind.OnResponseBody, he))
                        {
                            return;
                        }
                        base.OnReceiveRemote(e);
                        //e.Stream = he.Stream;
                        e.Packet = he.Stream.ReadBytes();

                        // 如果现在正在缓存之中,那么也罢这些非头部数据一并拷贝到缓存里面
                        if (cacheItem != null)
                        {
                            var ms = e.Packet.GetStream();
                            var p  = ms.Position;
                            ms.CopyTo(cacheItem.Stream);
                            var count = ms.Position = p;
                            ms.Position = p;
                            //WriteDebugLog("[{0}] {1} 缓存数据[{2}]", ID, Request.RawUrl, count);
                        }

                        return;

                        #endregion
                    }
                    #endregion

                    // 请求头不完整,不发送,等下一部分到来
                    if (!entity.IsFinish)
                    {
                        return;
                    }

                    {
                        var he = new HttpProxyEventArgs(entity, stream);
                        if (pxy.RaiseEvent(this, EventKind.OnResponse, he))
                        {
                            return;
                        }
                        stream = he.Stream;
                    }

                    // 写入头部扩展
                    entity.Headers["Powered-By-Proxy"] = pxy.Name;
                    entity.Headers["RequestTime"]      = RequestTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
                    entity.Headers["TotalTime"]        = (DateTime.Now - RequestTime).ToString();
                }

                #region 缓存
                if (pxy.EnableCache)
                {
                    SetCache(Response, e);
                }
                #endregion

                #region 重构响应包
                if (entity != null)
                {
                    var ms = new MemoryStream();
                    entity.Write(ms);

                    if (parseBody && stream.Position < stream.Length)
                    {
                        var he = new HttpProxyEventArgs(Response, stream);
                        if (pxy.RaiseEvent(this, EventKind.OnResponseBody, he))
                        {
                            return;
                        }
                        stream = he.Stream;
                    }

                    stream.CopyTo(ms);
                    ms.Position = 0;

                    //stream = ms;
                    //e.Stream = ms;
                    e.Packet = ms.ToArray();
                }

                if (cacheItem != null)
                {
                    var ms = e.Packet.GetStream();
                    var p  = ms.Position;
                    ms.CopyTo(cacheItem.Stream);
                    var count = ms.Position = p;
                    ms.Position = p;
                    //WriteDebugLog("[{0}] {1} 增加缓存[{2}]", ID, Request.RawUrl, count);
                }
                #endregion

                base.OnReceiveRemote(e);
            }
Exemplo n.º 2
0
        /// <summary>触发事件</summary>
        /// <param name="session"></param>
        /// <param name="kind"></param>
        /// <param name="he"></param>
        /// <returns>返回是否取消操作</returns>
        Boolean RaiseEvent(Session session, EventKind kind, HttpProxyEventArgs he)
        {
            GetHandler(kind)?.Invoke(session, he);

            return(he.Cancel);
        }
Exemplo n.º 3
0
            /// <summary>收到客户端发来的数据。子类可通过重载该方法来修改数据</summary>
            /// <remarks>
            /// 如果数据包包括头部和主体,可以分开处理。
            /// 最麻烦的就是数据包不是一个完整的头部,还落了一部分在后面的包上。
            /// </remarks>
            /// <param name="e"></param>
            protected override void OnReceive(ReceivedEventArgs e)
            {
                if (e.Packet.Total == 0)
                {
                    base.OnReceive(e);
                    return;
                }

                var pxy = Host as HttpProxy;

                #region 解析请求头
                // 解析请求头。
                var stream = e.Packet.GetStream() as Stream;
                // 当前正在处理的未完整的头部,浏览器可能把请求头分成几块发过来
                var entity = UnFinishedRequest;
                // 如果当前请求为空,说明这是第一个数据包,可能包含头部
                if (entity == null)
                {
                    // 读取并分析头部
                    entity = HttpHeader.Read(stream, HttpHeaderReadMode.Request);
                    if (entity == null)
                    {
                        // 分析失败?这个可能不是Http请求头
                        var he = new HttpProxyEventArgs(Request, stream);
                        if (pxy.RaiseEvent(this, EventKind.OnRequestBody, he))
                        {
                            return;
                        }
                        //e.Stream = he.Stream;
                        e.Packet = he.Stream.ReadBytes();

                        base.OnReceive(e);

                        return;
                    }

                    // 根据完成情况保存到不同的本地变量中
                    if (!entity.IsFinish)
                    {
                        UnFinishedRequest = entity;
                    }
                    else
                    {
                        Request = entity;
                    }
                }
                else if (!entity.IsFinish)
                {
                    // 如果请求未完成,说明现在的数据内容还是头部
                    entity.ReadHeaders(stream);
                    if (entity.IsFinish)
                    {
                        Request           = entity;
                        UnFinishedRequest = null;
                    }
                }
                else
                {
                    // 否则,头部已完成,现在就是内容,直接转发
                    var he = new HttpProxyEventArgs(Request, stream);
                    if (pxy.RaiseEvent(this, EventKind.OnRequestBody, he))
                    {
                        return;
                    }
                    //e.Stream = he.Stream;
                    e.Packet = he.Stream.ReadBytes();

                    base.OnReceive(e);

                    return;
                }

                // 请求头不完整,不发送,等下一部分到来
                if (!entity.IsFinish)
                {
                    return;
                }
                #endregion

                WriteLog("{0}", entity.Url);

                #region 重构请求包
                // 现在所在位置是一个全新的请求
                var rs = OnRequest(entity, e);
                {
                    var he = new HttpProxyEventArgs(Request, stream)
                    {
                        Cancel = !rs
                    };
                    rs = !pxy.RaiseEvent(this, EventKind.OnRequest, he);
                }
                if (!rs)
                {
                    return;
                }

                // 如果流中还有数据,可能是请求体,也要拷贝
                if (stream.Position < stream.Length)
                {
                    var he = new HttpProxyEventArgs(Request, stream);
                    if (pxy.RaiseEvent(this, EventKind.OnRequestBody, he))
                    {
                        return;
                    }
                    stream = he.Stream;
                }

                // 重新构造请求
                var ms = new MemoryStream();
                entity.Write(ms);
                stream.CopyTo(ms);
                ms.Position = 0;

                //e.Stream = ms;
                e.Packet = ms.ToArray();
                #endregion

                base.OnReceive(e);
            }