protected void Clean() { if (trp.KeepAlive) { targetSocket = null; targetConnectionPool.ReuseSocket(crp, targetSocketInfo); } else { targetSocket = null; targetConnectionPool.RemoveSocket(crp, targetSocketInfo); } targetSocket = null; //clear both buffers crp = null; trp = null; try { clientSocket.BeginReceive(clientBuffer, 0, BiConnection.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(OnClientReceived), null); } catch (SocketException) { RetryOrDispose(true, false, false); } }
public bool ValidateTargetResponse(ClientRequestPacket crp, TargetResponsePacket trp) { string fullURL; if (crp.Port == 80) { fullURL = crp.Protocol + "://" + crp.Host + crp.RelativePath; } else { fullURL = crp.Protocol + "://" + crp.Host + ":" + crp.Port + crp.RelativePath; } string html = ReformHTML(trp); return(pacSetting.ValidateHtml(fullURL, html)); }
private string ReformHTML(TargetResponsePacket trp) { string contentEncoding = null; bool isChunked = false; bool isGzip = false; foreach (string s in trp.Headers) { if (s.StartsWith("Content-Type", StringComparison.OrdinalIgnoreCase)) { Match m = charsetRegex.Match(s); if (m.Success) { string charset = m.Groups["charset"].Value; } } else if (s.StartsWith("Content-Encoding", StringComparison.OrdinalIgnoreCase)) { if (s.IndexOf("gzip", StringComparison.OrdinalIgnoreCase) >= 0) { isGzip = true; } } else if (s.StartsWith("Transfer-Encoding", StringComparison.OrdinalIgnoreCase)) { if (s.IndexOf("chunked", StringComparison.OrdinalIgnoreCase) >= 0) { isChunked = true; } } } string html; byte[] content = trp.IncomingBuffer.ToArray(); MemoryStream ms = new MemoryStream(content, trp.ContentBeginOffset, content.Length - trp.ContentBeginOffset); byte[] array = ms.ToArray(); if (array.Length > 0) { HtmlHelper.GetHtml(ms.ToArray(), contentEncoding, isChunked, isGzip, out html); return(html); } else { return(null); } }
public void NotSuitableProxy() { if (targetSocket != null) { targetSocket.Close(); targetSocket = null; } if (targetSocketInfo != null) { targetConnectionPool.RemoveSocket(crp, targetSocketInfo); } trp = null; targetConnctionGuide.ReportNotSuitableSocketInfo(crp, targetSocketInfo); targetSocket = null; targetSocketInfo = null; ConnectTarget(); }
public void RetryOrDispose(bool clientFault, bool targetFault, bool forceDispose) { bool disposeClient = clientFault || forceDispose; bool disposeTarget = targetFault || forceDispose; // Console.WriteLine("{0} {1} {2} {3} {4} {5} {6} \n{7}", ((IPEndPoint)clientSocket.RemoteEndPoint).Port, // clientSocket == null ? 0 : ((IPEndPoint)clientSocket.LocalEndPoint).Port, // targetSocket == null ? 0 : ((IPEndPoint)targetSocket.LocalEndPoint).Port, // "disposed",clientFault,targetFault,forceDispose, // crp ==null? "-":crp.Headers[0]); if (disposeClient) { if (clientSocket != null) { clientSocket.Close(); } if (targetSocketInfo != null) { if (disposeTarget) { if (targetSocket != null) { targetSocket.Close(); targetConnectionPool.RemoveSocket(crp, targetSocketInfo); } targetSocket = null; targetSocketInfo = null; } else { if (targetSocket != null) { targetConnectionPool.ReuseSocket(crp, targetSocketInfo); } targetSocket = null; targetSocketInfo = null; } } } else if (disposeTarget) { if (targetSocket != null) { targetSocket.Close(); targetSocket = null; } if (targetSocketInfo != null) { targetConnectionPool.RemoveSocket(crp, targetSocketInfo); } trp = null; if (forceDispose) { targetSocket = null; targetSocketInfo = null; SendBack502(); } else if (targetSocketInfo != null && targetSocketInfo.ReUse) { targetSocket = null; targetSocketInfo = null; ConnectTarget(); } else { //fresh connection fails,report proxy fails if retry times >=2 if (retryTimes < 3) { retryTimes++; targetConnctionGuide.ReportErrorSocketInfo(crp, targetSocketInfo); targetSocket = null; targetSocketInfo = null; ConnectTarget(); } else { //abandom // Console.WriteLine("{0} {1} {2} {3} {4} {5} {6} \n{7}", ((IPEndPoint)clientSocket.RemoteEndPoint).Port, // clientSocket == null ? 0 : ((IPEndPoint)clientSocket.LocalEndPoint).Port, // targetSocket == null ? 0 : ((IPEndPoint)targetSocket.LocalEndPoint).Port, // "3 times dispose", clientFault, targetFault, forceDispose, // crp == null ? "-" : crp.Headers[0]); targetSocket = null; targetSocketInfo = null; SendBack502(); } } } }
protected void OnTargetReceived(IAsyncResult ar) { int len = 0; try { len = targetSocket.EndReceive(ar); } catch (SocketException) { RetryOrDispose(false, true, true); return; } //packet over //if (len <= 0 && trp != null && !trp.KeepAlive) // Console.WriteLine(len); if (len <= 0) { if (trp == null || trp.KeepAlive) { //reconnect or kill RetryOrDispose(false, true, false); return; } else { trp.ContentReceived = true; } } if (trp == null) { trp = new TargetResponsePacket(); } trp.AppendData(targetBuffer, 0, len); //shoot //if need validate, wait for the return of entire packet Console.WriteLine("{0} {1} {2}", len, trp.ContentLength, trp.IncomingBuffer.Length); if (targetResponseValidator.NeedValidate(crp)) { Console.WriteLine("Need Validate for {0} {1} {2} len = {3}", crp.Host, crp.RelativePath, ((IPEndPoint)targetSocket.RemoteEndPoint).Address, len); if (!trp.HeaderReceived || !trp.ContentReceived) { //continue receiving //header not complete. Console.WriteLine("continue receiving for {0} {1} {2}", crp.Host, crp.RelativePath, ((IPEndPoint)targetSocket.RemoteEndPoint).Address); try { targetSocket.BeginReceive(targetBuffer, 0, BUFFER_SIZE, SocketFlags.None, new AsyncCallback(OnTargetReceived), targetSocket); } catch (SocketException) { RetryOrDispose(false, true, false); return; } } else { //check if the response is 200ok if (trp.ResponseCode == "200" && trp.ContentType != null && trp.ContentType.Contains("text")) { //validate if (targetResponseValidator.ValidateTargetResponse(crp, trp)) { //shoot the entire packet Console.WriteLine("Validation OK for {0} {1} {2}", crp.Host, crp.RelativePath, ((IPEndPoint)targetSocket.RemoteEndPoint).Address); ForwardFullResponse(); } else { Console.WriteLine("Validation FFFF for {0} {1} {2}", crp.Host, crp.RelativePath, ((IPEndPoint)targetSocket.RemoteEndPoint).Address); NotSuitableProxy(); } } else { Console.WriteLine("Validation Skipped for {0} {1} {2}", crp.Host, crp.RelativePath, ((IPEndPoint)targetSocket.RemoteEndPoint).Address); ForwardFullResponse(); } } } else { Console.WriteLine("No need for {0} {1} {2}", crp.Host, crp.RelativePath, ((IPEndPoint)targetSocket.RemoteEndPoint).Address); //directly forward the response if (trp.HeaderReceived && !trp.HeaderShooted) { //shoot header; ForwardResponse(); } else if (trp.HeaderShooted) { if (trp.ContentBuffer != null && trp.ContentBuffer.Length > 0) { try { clientSocket.BeginSend(trp.ContentBuffer, 0, trp.ContentBuffer.Length, SocketFlags.None, new AsyncCallback(OnClientContentSent), clientSocket); } catch (SocketException) { RetryOrDispose(true, false, true); return; } } } else { //header not complete. try { targetSocket.BeginReceive(targetBuffer, 0, BUFFER_SIZE, SocketFlags.None, new AsyncCallback(OnTargetReceived), targetSocket); } catch (SocketException) { RetryOrDispose(false, true, true); return; } } } }