public int ForwardChunkedDataToPeerChunked( MyBinaryReader inputStreamReader, BinaryWriter outputStreamWriter, Encoding contentCharsetEncoding, byte[] serverNewlineBytes, SniffedDataChunk sniffedDataChunk, bool isProcessed) // <-- relevant for sslstrip and injectFile { int noBytesTransferred = 0; int noEffectivelyTransferredBytes = 0; int announcedChunkSize = 0; int chunkCounter = 0; string previousChunkLen = "00"; while (true) { chunkCounter += 1; // Read chunk size string chunkLenStr = inputStreamReader.ReadLine(false); // Jump out of the loop if it is the last data packet if (string.IsNullOrEmpty(chunkLenStr)) { Logging.Instance.LogMessage(this.requestObj.Id, this.requestObj.ProxyProtocol, Loglevel.Debug, "TcpClientRaw.ForwardChunkedDataToPeer2(): WOOPS! chunkLenStr isNullOrEmpty!!!"); break; } announcedChunkSize = int.Parse(chunkLenStr, System.Globalization.NumberStyles.HexNumber); // If announced chunk size is invalid/<0 jump out of the loop if (announcedChunkSize < 0) { Logging.Instance.LogMessage(this.requestObj.Id, this.requestObj.ProxyProtocol, Loglevel.Debug, "TcpClientRaw.ForwardChunkedDataToPeer2(): WOOPS! Invalid chunk size!!!"); break; } // Receive announced data chunk from server Logging.Instance.LogMessage(this.requestObj.Id, this.requestObj.ProxyProtocol, Loglevel.Debug, "TcpClientRaw.ForwardChunkedDataToPeer2(): ChunkNo={0}: previousChunkLen=0x{1} ChunkLength=0x{2}", chunkCounter, previousChunkLen, chunkLenStr); noEffectivelyTransferredBytes = this.RelayChunk2(inputStreamReader, outputStreamWriter, announcedChunkSize, contentCharsetEncoding, serverNewlineBytes, isProcessed); noBytesTransferred += noEffectivelyTransferredBytes; Logging.Instance.LogMessage(this.requestObj.Id, this.requestObj.ProxyProtocol, Loglevel.Debug, "TcpClientRaw.ForwardChunkedDataToPeer2(): blockSize > 0: ChunkNo={0} chunkLenStr.Length={1}, Content=|0x{2}|", chunkCounter, chunkLenStr.Length, chunkLenStr); previousChunkLen = chunkLenStr; // If chunk size is zero jump out of the loop if (announcedChunkSize == 0 || chunkLenStr == "0") { break; } } return(noBytesTransferred); }
private int RelayChunk2(MyBinaryReader inputStreamReader, BinaryWriter outputStreamWriter, int announcedChunkSize, Encoding contentCharsetEncoding, byte[] serverNewlineBytes, bool mustBeProcessed) { int totalBytesTransferred = 0; // Read all bytes from server stream byte[] binaryDataBlock = this.ReceiveChunk(announcedChunkSize, inputStreamReader); Logging.Instance.LogMessage(this.requestObj.Id, this.requestObj.ProxyProtocol, Loglevel.Debug, "TcpClientRaw.RelayChunk2(): ChunkSize:{0}, binaryDataBlock.Length:{1}", announcedChunkSize, binaryDataBlock.Length); if (announcedChunkSize != binaryDataBlock.Length) { throw new Exception("The announced content length and the amount of received data are not the same"); } // Encode received bytes to the announced format // string dataBlockString = contentCharsetEncoding.GetString(binaryDataBlock); DataChunk serverDataChunk = new DataChunk(binaryDataBlock, binaryDataBlock.Length, contentCharsetEncoding); // If response can be processed : do so. if (mustBeProcessed == true) { Lib.PluginCalls.ServerDataTransfer(this.requestObj, serverDataChunk); } // Send chunk size to recepient string chunkSizeHexStringTmp = serverDataChunk.ContentDataLength.ToString("x"); byte[] chunkSizeDeclaration = contentCharsetEncoding.GetBytes(chunkSizeHexStringTmp); outputStreamWriter.Write(chunkSizeDeclaration, 0, chunkSizeDeclaration.Length); outputStreamWriter.Write(serverNewlineBytes, 0, serverNewlineBytes.Length); // Send data packet to recipient outputStreamWriter.Write(serverDataChunk.ContentData, 0, serverDataChunk.ContentDataLength); // Send trailing newline to finish chunk transmission inputStreamReader.ReadLine(); outputStreamWriter.Write(serverNewlineBytes, 0, serverNewlineBytes.Length); outputStreamWriter.Flush(); Logging.Instance.LogMessage(this.requestObj.Id, this.requestObj.ProxyProtocol, Loglevel.Debug, "TcpClientRaw.RelayChunk2(): Transferred {0}/{1} bytes from SERVER -> CLIENT: ", announcedChunkSize, serverDataChunk.ContentDataLength); return(totalBytesTransferred); }