private static void HandleClientResponse(EavesdropperRequestEventArgs requestArgs, Stream clientStream) { WebResponse webResponse = null; try { webResponse = requestArgs.Request.GetResponse(); } catch (WebException e) { webResponse = e.Response; } if (webResponse == null) return; using (WebResponse response = webResponse) { if (IsCacheDisabled) response.Headers["Cache-Control"] = "no-cache, no-store"; byte[] responsePayload = null; using (var responseStream = response.GetResponseStream()) using (var responseBufferStream = new MemoryStream()) { responseStream.CopyTo(responseBufferStream); responsePayload = responseBufferStream.ToArray(); } var responseArgs = new EavesdropperResponseEventArgs(response); responseArgs.Payload = responsePayload; OnEavesdropperResponse(responseArgs); if (!responseArgs.Cancel) { string responseCommand = response.Headers.ToString(); var hResponse = (response as HttpWebResponse); if (hResponse != null && !responseArgs.IsResponseOK) { responseCommand = $"HTTP/{hResponse.ProtocolVersion} {(int)hResponse.StatusCode} " + $"{hResponse.StatusDescription}\r\n{responseCommand}"; } else responseCommand = "HTTP/1.1 200 OK\r\n" + responseCommand; string responseCookies = FormatResponseCookies(response); if (!string.IsNullOrWhiteSpace(responseCookies)) { string innerCookies = responseCommand.GetChild("Set-Cookie: ", '\r'); responseCommand = responseCommand .Replace("Set-Cookie: " + innerCookies + "\r\n", responseCookies); } if (responseCommand.Contains("Content-Length")) { string contentLengthChild = responseCommand.GetChild("Content-Length: ", '\r'); responseCommand = responseCommand.Replace( contentLengthChild + "\r", (responseArgs.Payload?.Length ?? 0) + "\r"); } byte[] responseCommandPayload = Encoding.ASCII.GetBytes(responseCommand); clientStream.Write(responseCommandPayload, 0, responseCommandPayload.Length); if (responseArgs.Payload != null) { clientStream.Write(responseArgs.Payload, 0, responseArgs.Payload.Length); } } } }
private static void OnEavesdropperRequest(EavesdropperRequestEventArgs e) { EavesdropperRequest?.Invoke(null, e); }
private static void HandleClientRequest(Socket socket) { Stream clientStream = null; try { byte[] postRequestPayload = null; clientStream = new NetworkStream(socket, true); byte[] requestCommandPayload = ReadRequestStreamData(clientStream, ref postRequestPayload); if (requestCommandPayload.Length < 1) return; string requestCommand = Encoding.ASCII.GetString(requestCommandPayload); if (requestCommand.StartsWith("CONNECT")) { string target = requestCommand.GetChild( "CONNECT ", ' ').Split(':')[0]; socket.Send(_fakeOkResponse); string host = requestCommand.GetChild("Host: ", '\r'); clientStream = GetSecureClientStream(host, clientStream); requestCommandPayload = ReadRequestStreamData(clientStream, ref postRequestPayload); if (requestCommandPayload.Length < 1) return; requestCommand = Encoding.ASCII.GetString(requestCommandPayload); if (!(clientStream is SslStream)) requestCommand = "GET http://" + target + requestCommand; } HttpWebRequest request = CreateWebRequest(requestCommand); var requestArgs = new EavesdropperRequestEventArgs(request); requestArgs.Payload = postRequestPayload; if (IsCacheDisabled) request.Headers["Cache-Control"] = "no-cache, no-store"; OnEavesdropperRequest(requestArgs); if (requestArgs.Cancel) return; if (requestArgs.ResponsePayload != null) { clientStream.Write(requestArgs.ResponsePayload, 0, requestArgs.ResponsePayload.Length); return; } if (requestArgs.Payload != null && requestArgs.Payload.Length > 0) { using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(requestArgs.Payload, 0, requestArgs.Payload.Length); } } HandleClientResponse(requestArgs, clientStream); } finally { clientStream?.Dispose(); } }