private static void OnEavesdropperResponse(EavesdropperResponseEventArgs e) { EavesdropperResponseEventHandler handler = EavesdropperResponse; if (handler != null) { handler(e); } }
private static void RequestIntercepted(IAsyncResult ar) { bool doTerminate = false; bool shouldTerminate = false; try { _processingRequests++; using (Socket requestSocket = _listener.EndAcceptSocket(ar)) { if (IsRunning) { _listener.BeginAcceptSocket(RequestIntercepted, null); } // Intercept the HTTP/HTTPS command from the local machine. byte[] requestCommandBuffer = new byte[8192]; int length = requestSocket.Receive(requestCommandBuffer); if (length == 0) { return; } byte[] requestCommand = new byte[length]; Buffer.BlockCopy(requestCommandBuffer, 0, requestCommand, 0, length); // Create a WebRequest instance using the intercepted commands/headers. byte[] payload = null; HttpWebRequest request = GetRequest(requestCommand, ref payload); // Attempt to retrieve more data if available from the current stream. if (requestSocket.Available == request.ContentLength && payload == null) { payload = new byte[request.ContentLength]; requestSocket.Receive(payload); } // Notify the subscriber that a request has been constructed, and is ready to be sent. if (EavesdropperRequest != null) { var e = new EavesdropperRequestEventArgs(request); if (payload != null) { e.Payload = payload; } OnEavesdropperRequest(e); if (e.Cancel) { return; } payload = e.Payload; } switch (request.Method) { case "CONNECT": return; // Let's focus on HTTP for now. case "POST": // Send the request data to the server. { using (Stream requestStream = request.GetRequestStream()) requestStream.Write(payload, 0, payload.Length); break; } } using (var response = (HttpWebResponse)request.GetResponse()) { if (IsCacheDisabled) { response.Headers["Cache-Control"] = "no-cache, no-store"; } byte[] responseData = new byte[0]; using (Stream responseStream = response.GetResponseStream()) { int readDataLength = 0; byte[] responseDataBuffer = null; byte[] readData = new byte[response.ContentLength < 0 ? 8192 : response.ContentLength]; while ((readDataLength = responseStream.Read(readData, 0, readData.Length)) > 0) { responseDataBuffer = new byte[responseData.Length + readDataLength]; Buffer.BlockCopy(responseData, 0, responseDataBuffer, 0, responseData.Length); Buffer.BlockCopy(readData, 0, responseDataBuffer, responseData.Length, readDataLength); responseData = responseDataBuffer; } } // Notify the subscriber that a response has been intercepted, and is ready to be viewed. if (EavesdropperResponse != null) { var e = new EavesdropperResponseEventArgs(response); e.Payload = responseData; OnEavesdropperResponse(e); if (doTerminate = e.ShouldTerminate) { IsRunning = false; } if (e.Cancel) { return; } responseData = e.Payload; } // Reply with the server's response back to the client. byte[] commandResponse = GetCommandResponse(request, response, responseData.Length); requestSocket.Send(commandResponse); if (responseData != null && responseData.Length != 0) { requestSocket.Send(responseData); } shouldTerminate = doTerminate; } } } catch { } finally { --_processingRequests; if ((_processingRequests < 1 && !_listener.Active) || shouldTerminate) { if (_listener.Active) { _listener.Stop(); Port = 0; } NativeMethods.DisableProxy(); _processingRequests = 0; } } }
private static void OnEavesdropperResponse(EavesdropperResponseEventArgs e) { EavesdropperResponse?.Invoke(null, e); }
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 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); } } } }