void targetSendBackLoop(object o) { ManagedProxyStream stream = o as ManagedProxyStream; TimeSpan sleepTime = TimeSpan.FromMilliseconds(200); try { while (this.running) { // if no data available, wait for a while if (stream.TargetClient.Connected && stream.TargetClient.Available == 0) { Thread.Sleep(sleepTime); } // if data coming else { byte[] data; // receive data using (var t = new MemoryStream()) { var buf = new byte[stream.TargetClient.ReceiveBufferSize]; lock (stream.IOLock) { do { var bytes = stream.TargetStream.Read(buf, 0, buf.Length); t.Write(buf, 0, bytes); } while (stream.TargetClient.Available > 0); stream.LastUsed = DateTime.Now; } data = t.ToArray(); } // pack as ManagedEvent var e = new ManagedProxyEvent(); e.Data = data; e.Sender = SenderType.Target; e.EventType = ProxyEventType.IncomingMessage; //parse the endpoint string str = Encoding.UTF8.GetString(data); e.Text = str; // try to parse as http try { HttpResponse res = new HttpResponse(); res.Parse(e.Text); e.ParsedHttpResponse = res; } // if not http message catch { e.EventType = ProxyEventType.Unknown; } finally { byte[] tosend = e.Data; if (ReceiveMessageFromTargetCallback != null) { byte[] replacedResponse = ReceiveMessageFromTargetCallback(e); if (replacedResponse != null) { tosend = replacedResponse; } } if (tosend == null) { // OACR do not allow throwing exception in a final clause Trace.Fail("tosend is null"); } lock (stream) { stream.SourceStream.Write(tosend, 0, tosend.Length); } } } } } catch (Exception) { } }
private void ReceiveLoop(object o) { TimeSpan idleTime = TimeSpan.FromMilliseconds(0); TimeSpan sleepTime = TimeSpan.FromMilliseconds(200); Stream s; Stream targetS; System.Threading.Thread targetSideThread = new Thread(new ParameterizedThreadStart(targetSendBackLoop)); X509Certificate2 currentTargetClientCert = null; lock (clientCertLocker) { currentTargetClientCert = clientCert; } using (TcpClient targetServerCon = new TcpClient(targetServerIP, targetServerPort)) { using (var c = o as TcpClient) { if (this.useSSL) { SslStream ssl2 = connectToTargetSSLPort(targetServerCon); targetS = ssl2; SslStream ssl = new SslStream(c.GetStream(), false, this.proxySideUserCertificateValidationCallback, this.proxySideServerCertificateSelectionCallback, this.encryptionPolicy); ssl.AuthenticateAsServer(this.serverCert, false, System.Security.Authentication.SslProtocols.Tls, false); s = ssl; } else { s = c.GetStream(); targetS = targetServerCon.GetStream(); } // cache stream var ms = new ManagedProxyStream(); this.clientStreams.Add(ms); ms.SourceClient = c; ms.TargetClient = targetServerCon; ms.SourceStream = s; ms.TargetStream = targetS; if (SSLConnectedCallback != null) { SSLConnectedCallback(ms); } targetSideThread.Start(ms); using (s) { while (this.running) { // if no data available, wait for a while if (c.Available == 0) { Thread.Sleep(sleepTime); idleTime += sleepTime; } // if data coming else { idleTime = TimeSpan.FromMilliseconds(0); byte[] data; // receive data using (var t = new MemoryStream()) { var buf = new byte[c.ReceiveBufferSize]; lock (ms.IOLock) { do { var bytes = s.Read(buf, 0, buf.Length); t.Write(buf, 0, bytes); System.Threading.Thread.Sleep(50); } while (c.Available > 0); ms.LastUsed = DateTime.Now; } data = t.ToArray(); } // pack as ManagedEvent var e = new ManagedProxyEvent(); e.Data = data; e.Sender = SenderType.Source; e.EventType = ProxyEventType.IncomingMessage; lock (clientCertLocker) { if (0 != string.Compare(clientCert.Thumbprint.ToLower(), currentTargetClientCert.Thumbprint.ToLower())) { currentTargetClientCert = clientCert; ms.TargetClient.Close(); TcpClient targetCon = new TcpClient(targetServerIP, targetServerPort); SslStream ssl2 = connectToTargetSSLPort(targetCon); targetS = ssl2; ms.TargetClient = targetCon; ms.TargetStream = ssl2; targetSideThread = new Thread(new ParameterizedThreadStart(targetSendBackLoop)); if (SSLConnectedCallback != null) { SSLConnectedCallback(ms); } targetSideThread.Start(ms); } } //parse the endpoint string str = Encoding.UTF8.GetString(data); e.Text = str; // try to parse as http try { HttpRequest req = new HttpRequest(); req.Parse(e.Text); e.ParsedHttpRequest = req; } // if not http message catch { e.EventType = ProxyEventType.Unknown; } finally { byte[] tosend = e.Data; if (ReceiveMessageFromSourceCallback != null) { tosend = ReceiveMessageFromSourceCallback(e); } if (tosend != null) { if (!ms.TargetClient.Connected) { ms.TargetClient = new TcpClient(targetServerIP, targetServerPort); if (useSSL) { ms.TargetStream = connectToTargetSSLPort(ms.TargetClient); } targetSideThread = new Thread(new ParameterizedThreadStart(targetSendBackLoop)); targetSideThread.Start(ms); } ms.TargetStream.Write(tosend, 0, tosend.Length); } } } } } } } }