/// <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); }
/// <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); }
/// <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); }