public void Dispose() { try { InUse = false; if (socket != null) { if (socket.Connected) { socket.Shutdown(SocketShutdown.Both); } socket.Close(); } if (st != null) { st.Close(); st.Dispose(); } if (PacketPending != null) { PacketPending.Dispose(); } BufferStream.Dispose(); } catch (Exception err) { Node.LogAppendLine(err); } }
private static Stream GetStream(string url, IWebProxy proxy) { BufferManager bufferManager = BufferManager.Instance; for (int i = 0; i < 10; i++) { var bufferStream = new BufferStream(bufferManager); try { var request = (HttpWebRequest)WebRequest.Create(url); request.AllowAutoRedirect = true; request.Proxy = proxy; request.Headers.Add("Pragma", "no-cache"); request.Headers.Add("Cache-Control", "no-cache"); request.Timeout = 1000 * 60 * 5; request.ReadWriteTimeout = 1000 * 60 * 5; using (WebResponse response = request.GetResponse()) { if (response.ContentLength > 1024 * 1024 * 32) { throw new Exception("too large"); } using (Stream stream = response.GetResponseStream()) using (var safeBuffer = bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { bufferStream.Write(safeBuffer.Value, 0, length); if (bufferStream.Length > 1024 * 1024 * 32) { throw new Exception("too large"); } } } if (response.ContentLength != -1 && bufferStream.Length != response.ContentLength) { continue; } bufferStream.Seek(0, SeekOrigin.Begin); return(bufferStream); } } catch (Exception) { bufferStream.Dispose(); } } throw new Exception(string.Format("not found: {0}", url)); }
public void Dispose() { if (BufferStream != null) { BufferStream.Dispose(); BufferStream = null; } if (BinaryWriter != null) { BinaryWriter.Close(); BinaryWriter = null; } BlockRecycler = null; _readAheadBuffer = null; _writeBuffer = null; //_logger = null; HeaderData = null; }
private Stream GetStream(string url) { var bufferStream = new BufferStream(_bufferManager); try { using (var client = new HttpClient()) { using (var stream = client.GetStreamAsync(url).Result) { if (stream.Length > 1024 * 1024 * 32) { throw new Exception("too large"); } using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { bufferStream.Write(safeBuffer.Value, 0, length); if (bufferStream.Length > 1024 * 1024 * 32) { throw new Exception("too large"); } } } bufferStream.Seek(0, SeekOrigin.Begin); return(bufferStream); } } } catch (Exception) { bufferStream.Dispose(); throw; } }
private (int, WaitQueue <ResponseInfo>) Send <TArgument>(AmoebaRequestType type, TArgument argument) { int id = this.CreateId(); var queue = new WaitQueue <ResponseInfo>(); _queueMap.Add(id, queue); using (var writer = new ItemStreamWriter(_bufferManager)) { writer.Write((uint)type); writer.Write((uint)id); Stream valueStream = null; if (argument != null) { try { valueStream = new BufferStream(_bufferManager); JsonUtils.Save(valueStream, argument); } catch (Exception) { if (valueStream != null) { valueStream.Dispose(); valueStream = null; } throw; } } _messagingManager.Send(new UniteStream(writer.GetStream(), valueStream)); } return(id, queue); }
public override Stream Receive(TimeSpan timeout, Information options) { if (_disposed) { throw new ObjectDisposedException(this.GetType().FullName); } if (!_connect) { throw new ConnectionException(); } lock (_receiveLock) { try { _receiveStopwatch.Restart(); Restart :; int length = 0; { byte[] lengthbuffer = new byte[4]; var time = BaseConnection.CheckTimeout(_receiveStopwatch.Elapsed, timeout); time = (time < _receiveTimeSpan) ? time : _receiveTimeSpan; _cap.Receive(lengthbuffer, time); _receivedByteCount.Add(4); length = NetworkConverter.ToInt32(lengthbuffer); } if (length == 0) { Thread.Sleep(100); goto Restart; } else if (length > _maxReceiveCount) { throw new ConnectionException(); } BufferStream bufferStream = null; try { bufferStream = new BufferStream(_bufferManager); byte[] receiveBuffer = null; try { receiveBuffer = _bufferManager.TakeBuffer(1024 * 4); do { int receiveLength = Math.Min(receiveBuffer.Length, length); if (_bandwidthLimit != null) { receiveLength = _bandwidthLimit.GetInBandwidth(this, receiveLength); if (receiveLength < 0) { throw new ConnectionException(); } } var time = BaseConnection.CheckTimeout(_receiveStopwatch.Elapsed, timeout); time = (time < _receiveTimeSpan) ? time : _receiveTimeSpan; _cap.Receive(receiveBuffer, 0, receiveLength, time); _receivedByteCount.Add(receiveLength); bufferStream.Write(receiveBuffer, 0, receiveLength); length -= receiveLength; } while (length > 0); } finally { _bufferManager.ReturnBuffer(receiveBuffer); } } catch (Exception e) { if (bufferStream != null) { bufferStream.Dispose(); } throw e; } bufferStream.Seek(0, SeekOrigin.Begin); return(bufferStream); } catch (ConnectionException e) { throw e; } catch (Exception e) { throw new ConnectionException(e.Message, e); } } }
private static Stream ToStream <T>(ItemBase <T> item) where T : ItemBase <T> { Stream stream = null; try { stream = new RangeStream(item.Export(_bufferManager)); List <KeyValuePair <byte, Stream> > list = new List <KeyValuePair <byte, Stream> >(); try { stream.Seek(0, SeekOrigin.Begin); BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true)) { byte[] compressBuffer = null; try { compressBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = stream.Read(compressBuffer, 0, compressBuffer.Length)) > 0) { deflateStream.Write(compressBuffer, 0, i); } } finally { if (compressBuffer != null) { _bufferManager.ReturnBuffer(compressBuffer); } } } deflateBufferStream.Seek(0, SeekOrigin.Begin); list.Add(new KeyValuePair <byte, Stream>((byte)ConvertCompressionAlgorithm.Deflate, deflateBufferStream)); } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } } } catch (Exception) { } list.Add(new KeyValuePair <byte, Stream>((byte)ConvertCompressionAlgorithm.None, stream)); list.Sort((x, y) => { int c = x.Value.Length.CompareTo(y.Value.Length); if (c != 0) { return(c); } return(x.Key.CompareTo(y.Key)); }); #if DEBUG if (list[0].Value.Length != stream.Length) { Debug.WriteLine("AmoebaConverter ToStream : {0}→{1} {2}", NetworkConverter.ToSizeString(stream.Length), NetworkConverter.ToSizeString(list[0].Value.Length), NetworkConverter.ToSizeString(list[0].Value.Length - stream.Length)); } #endif for (int i = 1; i < list.Count; i++) { list[i].Value.Dispose(); } BufferStream headerStream = new BufferStream(_bufferManager); headerStream.WriteByte((byte)list[0].Key); var dataStream = new UniteStream(headerStream, list[0].Value); MemoryStream crcStream = new MemoryStream(Crc32_Castagnoli.ComputeHash(dataStream)); return(new UniteStream(dataStream, crcStream)); } catch (Exception ex) { if (stream != null) { stream.Dispose(); } throw new ArgumentException(ex.Message, ex); } }
protected override int ProcessIncoming(NetContext context, Connection connection, Stream incoming) { if (incoming.Length < 2) { return(0); // can't read that; frame takes at minimum two bytes } byte[] buffer = null; try { buffer = context.GetBuffer(); int read; // read as much as possible up to 14 bytes; that gives us space for 2 bytes frame header, 8 bytes length, and 4 bytes mask read = NetContext.TryFill(incoming, buffer, 14); int headerLength; var frame = WebSocketsFrame.TryParseFrameHeader(buffer, read, out headerLength); if (frame == null) { return(0); } int payloadLen = frame.PayloadLength; #if VERBOSE Debug.WriteLine("Parsed header from: " + BitConverter.ToString(buffer, 0, headerLength)); #endif if (incoming.Length < headerLength + payloadLen) { return(0); // not enough data to read the payload } if (payloadLen != 0) { Stream payload = null; try { payload = new BufferStream(context, context.Handler.MaxIncomingQuota); if (read != headerLength) { incoming.Position -= (read - headerLength); // we got it wrong... } Copy(incoming, payload, buffer, frame.Mask, payloadLen); if (payloadLen != payload.Length) { throw new InvalidOperationException("I munged the data"); } frame.Payload = payload; payload = null; } finally { if (payload != null) { payload.Dispose(); } } } foreach (var final in ApplyExtensions(context, connection, frame, true)) { ProcessFrame(context, connection, final); } return(headerLength + payloadLen); } finally { context.Recycle(buffer); } }
private static Stream Compress(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } try { var dic = new Dictionary <byte, Stream>(); try { stream.Seek(0, SeekOrigin.Begin); BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (var deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true)) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { deflateStream.Write(safeBuffer.Value, 0, length); } } deflateBufferStream.Seek(0, SeekOrigin.Begin); dic.Add((byte)ConvertCompressionAlgorithm.Deflate, deflateBufferStream); } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } } } catch (Exception) { } dic.Add((byte)ConvertCompressionAlgorithm.None, stream); var list = dic.ToList(); list.Sort((x, y) => { int c = x.Value.Length.CompareTo(y.Value.Length); if (c != 0) { return(c); } return(x.Key.CompareTo(y.Key)); }); for (int i = 1; i < list.Count; i++) { list[i].Value.Dispose(); } var headerStream = new BufferStream(_bufferManager); Varint.SetUInt64(headerStream, list[0].Key); return(new UniteStream(headerStream, list[0].Value)); } catch (Exception ex) { if (stream != null) { stream.Dispose(); } throw new ArgumentException(ex.Message, ex); } }
private static Stream Decrypt(Stream stream, IExchangeDecrypt privateKey) { if (stream == null) { throw new ArgumentNullException("stream"); } if (privateKey == null) { throw new ArgumentNullException("privateKey"); } try { byte type = (byte)stream.ReadByte(); if (type == (byte)ConvertCryptoAlgorithm.Aes256) { byte[] cryptoKey; { byte[] lengthBuffer = new byte[4]; if (stream.Read(lengthBuffer, 0, lengthBuffer.Length) != lengthBuffer.Length) { throw new ArgumentException(); } int length = NetworkConverter.ToInt32(lengthBuffer); byte[] encryptedBuffer = new byte[length]; if (stream.Read(encryptedBuffer, 0, encryptedBuffer.Length) != encryptedBuffer.Length) { throw new ArgumentException(); } cryptoKey = Exchange.Decrypt(privateKey, encryptedBuffer); } BufferStream outStream = null; try { outStream = new BufferStream(_bufferManager); using (Stream dataStream = new WrapperStream(stream, true)) { var iv = new byte[32]; dataStream.Read(iv, 0, iv.Length); using (var rijndael = new RijndaelManaged() { KeySize = 256, BlockSize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) using (var inStream = new RangeStream(dataStream, dataStream.Position, dataStream.Length - dataStream.Position)) using (CryptoStream cs = new CryptoStream(inStream, rijndael.CreateDecryptor(cryptoKey, iv), CryptoStreamMode.Read)) { byte[] buffer = null; try { buffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = cs.Read(buffer, 0, buffer.Length)) > 0) { outStream.Write(buffer, 0, i); } } finally { _bufferManager.ReturnBuffer(buffer); } } } outStream.Seek(0, SeekOrigin.Begin); } catch (Exception) { if (outStream != null) { outStream.Dispose(); } throw; } return(outStream); } throw new NotSupportedException(); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }
private static Stream Encrypt(Stream stream, IExchangeEncrypt publicKey) { if (stream == null) { throw new ArgumentNullException("stream"); } if (publicKey == null) { throw new ArgumentNullException("publicKey"); } try { BufferStream outStream = null; try { outStream = new BufferStream(_bufferManager); outStream.WriteByte((byte)ConvertCryptoAlgorithm.Aes256); byte[] cryptoKey = new byte[32]; _random.GetBytes(cryptoKey); { var encryptedBuffer = Exchange.Encrypt(publicKey, cryptoKey); outStream.Write(NetworkConverter.GetBytes((int)encryptedBuffer.Length), 0, 4); outStream.Write(encryptedBuffer, 0, encryptedBuffer.Length); } byte[] iv = new byte[32]; _random.GetBytes(iv); outStream.Write(iv, 0, iv.Length); using (Stream inStream = new WrapperStream(stream, true)) { using (var rijndael = new RijndaelManaged() { KeySize = 256, BlockSize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) using (CryptoStream cs = new CryptoStream(inStream, rijndael.CreateEncryptor(cryptoKey, iv), CryptoStreamMode.Read)) { byte[] buffer = null; try { buffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = cs.Read(buffer, 0, buffer.Length)) > 0) { outStream.Write(buffer, 0, i); } } finally { if (buffer != null) { _bufferManager.ReturnBuffer(buffer); } } } } outStream.Seek(0, SeekOrigin.Begin); } catch (Exception) { if (outStream != null) { outStream.Dispose(); } throw; } return(outStream); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }
private static Stream Decrypt(Stream stream, ExchangePrivateKey privateKey) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (privateKey == null) { throw new ArgumentNullException(nameof(privateKey)); } try { int type = (int)Varint.GetUInt64(stream); if (type == (int)ConvertCryptoAlgorithm.Aes256) { byte[] cryptoKey; { int length = (int)Varint.GetUInt64(stream); var encryptedBuffer = new byte[length]; if (stream.Read(encryptedBuffer, 0, encryptedBuffer.Length) != encryptedBuffer.Length) { throw new ArgumentException(); } cryptoKey = Exchange.Decrypt(privateKey, encryptedBuffer); } var iv = new byte[32]; stream.Read(iv, 0, iv.Length); BufferStream outStream = null; try { outStream = new BufferStream(_bufferManager); using (var aes = Aes.Create()) { aes.KeySize = 256; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (var inStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true)) using (var cs = new CryptoStream(inStream, aes.CreateDecryptor(cryptoKey, iv), CryptoStreamMode.Read)) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = cs.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { outStream.Write(safeBuffer.Value, 0, length); } } } outStream.Seek(0, SeekOrigin.Begin); } catch (Exception) { if (outStream != null) { outStream.Dispose(); } throw; } return(outStream); } else { throw new NotSupportedException(); } } catch (Exception e) { throw new ArgumentException(e.Message, e); } finally { if (stream != null) { stream.Dispose(); } } }
public override System.IO.Stream Receive(TimeSpan timeout, Information options) { if (_disposed) { throw new ObjectDisposedException(this.GetType().FullName); } if (!_connect) { throw new ConnectionException(); } lock (_receiveLock) { Stream stream = null; try { stream = _connection.Receive(timeout, options); byte version = (byte)stream.ReadByte(); Stream dataStream = null; try { dataStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position); if (version == (byte)0) { return(dataStream); } else if (version == (byte)1) { BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(dataStream, CompressionMode.Decompress, true)) { byte[] decompressBuffer = null; try { decompressBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = deflateStream.Read(decompressBuffer, 0, decompressBuffer.Length)) > 0) { deflateBufferStream.Write(decompressBuffer, 0, i); if (deflateBufferStream.Length > _maxReceiveCount) { throw new ConnectionException(); } } } finally { if (decompressBuffer != null) { _bufferManager.ReturnBuffer(decompressBuffer); } } } } catch (Exception e) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } throw e; } #if DEBUG Debug.WriteLine("Receive : {0}→{1} {2}", NetworkConverter.ToSizeString(stream.Length), NetworkConverter.ToSizeString(deflateBufferStream.Length), NetworkConverter.ToSizeString(stream.Length - deflateBufferStream.Length)); #endif deflateBufferStream.Seek(0, SeekOrigin.Begin); dataStream.Dispose(); return(deflateBufferStream); } else { throw new ArgumentException("ArgumentException"); } } catch (ConnectionException e) { if (dataStream != null) { dataStream.Dispose(); } throw e; } catch (Exception e) { if (dataStream != null) { dataStream.Dispose(); } throw new ConnectionException(e.Message, e); } } catch (ConnectionException e) { if (stream != null) { stream.Dispose(); } throw e; } catch (Exception e) { if (stream != null) { stream.Dispose(); } throw new ConnectionException(e.Message, e); } } }
IEnumerable<WebSocketsFrame> IExtension.ApplyOutgoing(NetContext context, WebSocketConnection connection, WebSocketsFrame frame) { if (!frame.IsControlFrame && frame.PayloadLength > parent.compressMessagesLargerThanBytes) { if (frame.Reserved1) { throw new InvalidOperationException("Reserved1 flag is already set; extension conflict?"); } int headerBytes = 0; if (outbound == null) { outbound = new ZStream(); const int BITS = 12; // 4096 byte outbound buffer (instead of full 32k=15) outbound.deflateInit(zlibConst.Z_BEST_COMPRESSION, BITS); headerBytes = 2; } BufferStream tmp = null; var payload = frame.Payload; payload.Position = 0; byte[] inBuffer = null, outBuffer = null; try { inBuffer = context.GetBuffer(); outBuffer = context.GetBuffer(); tmp = new BufferStream(context, 0); outbound.next_out = outBuffer; outbound.next_in = inBuffer; int remaining = frame.PayloadLength; while (remaining > 0) { int readCount = payload.Read(inBuffer, 0, inBuffer.Length); if (readCount <= 0) break; remaining -= readCount; outbound.next_in_index = 0; outbound.avail_in = readCount; do { outbound.next_out_index = 0; outbound.avail_out = outBuffer.Length; long priorOut = outbound.total_out; int err = outbound.deflate(remaining == 0 ? zlibConst.Z_SYNC_FLUSH : zlibConst.Z_NO_FLUSH); if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END) throw new ZStreamException("deflating: " + outbound.msg); int outCount = (int)(outbound.total_out - priorOut); if (outCount > 0) { if (headerBytes == 0) { tmp.Write(outBuffer, 0, outCount); } else { if (outCount < headerBytes) { throw new InvalidOperationException("Failed to write entire header"); } // check the generated header meets our expectations // CMF is very specific - CM must be 8, and CINFO must be <=7 (for 32k window) if ((outBuffer[0] & 15) != 8) { throw new InvalidOperationException("Zlib CM header was incorrect"); } if ((outBuffer[0] & 128) != 0) // if msb set, is > 7 - invalid { throw new InvalidOperationException("Zlib CINFO header was incorrect"); } // FLG is less important; FCHECK is irrelevent, FLEVEL doesn't matter; but // FDICT must be zero, to ensure that we aren't expecting a an initialization dictionary if ((outBuffer[1] & 32) != 0) { throw new InvalidOperationException("Zlib FLG.FDICT header was set (must not be)"); } // skip the header, and write anything else outCount -= headerBytes; if (outCount > 0) { tmp.Write(outBuffer, headerBytes, outCount); } headerBytes = 0; // all written now } } } while (outbound.avail_in > 0 || outbound.avail_out == 0); } if (remaining != 0) throw new EndOfStreamException(); if (headerBytes != 0) throw new InvalidOperationException("Zlib header was not written"); // verify the last 4 bytes, then drop them tmp.Position = tmp.Length - 4; NetContext.Fill(tmp, outBuffer, 4); if (!(outBuffer[0] == 0x00 && outBuffer[1] == 0x00 && outBuffer[2] == 0xFF && outBuffer[3] == 0xFF)) { throw new InvalidOperationException("expectation failed: 0000FFFF in the tail"); } if (parent.disableContextTakeover && tmp.Length >= frame.PayloadLength) { // compressing it didn't do anything useful; since we're going to discard // the compression context, we might as well stick with the original data payload.Position = 0; payload = null; // so that it doesn't get disposed } else { // set our final output tmp.Position = 0; tmp.SetLength(tmp.Length - 4); long bytesSaved = frame.PayloadLength - tmp.Length; frame.Payload = tmp; frame.PayloadLength = (int)tmp.Length; frame.Reserved1 = true; tmp = payload as BufferStream; parent.RegisterOutboundBytesSaved(bytesSaved); } } #if DEBUG catch (Exception ex) { Debug.WriteLine(ex); throw; } #endif finally { if (outbound != null) { outbound.next_out = null; outbound.next_in = null; } if (tmp != null) tmp.Dispose(); if (inBuffer != null) context.Recycle(inBuffer); if (outBuffer != null) context.Recycle(outBuffer); if (parent.disableContextTakeover) ClearContext(false, true); } } yield return frame; }
private static Stream ToStream <T>(int version, ItemBase <T> item) where T : ItemBase <T> { Stream stream = null; try { stream = new RangeStream(item.Export(_bufferManager)); var dic = new Dictionary <byte, Stream>(); try { stream.Seek(0, SeekOrigin.Begin); BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (var deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true)) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { deflateStream.Write(safeBuffer.Value, 0, length); } } deflateBufferStream.Seek(0, SeekOrigin.Begin); dic.Add((byte)ConvertCompressionAlgorithm.Deflate, deflateBufferStream); } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } } } catch (Exception) { } dic.Add((byte)ConvertCompressionAlgorithm.None, stream); var list = dic.ToList(); list.Sort((x, y) => { int c = x.Value.Length.CompareTo(y.Value.Length); if (c != 0) { return(c); } return(x.Key.CompareTo(y.Key)); }); for (int i = 1; i < list.Count; i++) { list[i].Value.Dispose(); } var headerStream = new BufferStream(_bufferManager); VintUtils.SetUInt64(headerStream, (uint)version); VintUtils.SetUInt64(headerStream, list[0].Key); var dataStream = new UniteStream(headerStream, list[0].Value); var crcStream = new MemoryStream(Crc32_Castagnoli.ComputeHash(new WrapperStream(dataStream, true))); return(new UniteStream(dataStream, crcStream)); } catch (Exception ex) { if (stream != null) { stream.Dispose(); } throw new ArgumentException(ex.Message, ex); } }
private static Stream Compress(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } var targetStream = new RangeStream(stream, true); List <KeyValuePair <byte, Stream> > list = new List <KeyValuePair <byte, Stream> >(); try { targetStream.Seek(0, SeekOrigin.Begin); BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true)) { byte[] compressBuffer = null; try { compressBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = targetStream.Read(compressBuffer, 0, compressBuffer.Length)) > 0) { deflateStream.Write(compressBuffer, 0, i); } } finally { if (compressBuffer != null) { _bufferManager.ReturnBuffer(compressBuffer); } } } deflateBufferStream.Seek(0, SeekOrigin.Begin); list.Add(new KeyValuePair <byte, Stream>((byte)ConvertCompressionAlgorithm.Deflate, deflateBufferStream)); } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } } } catch (Exception) { } list.Add(new KeyValuePair <byte, Stream>((byte)ConvertCompressionAlgorithm.None, targetStream)); list.Sort((x, y) => { int c = x.Value.Length.CompareTo(y.Value.Length); if (c != 0) { return(c); } return(x.Key.CompareTo(y.Key)); }); #if DEBUG if (list[0].Value.Length != targetStream.Length) { Debug.WriteLine("ContentConverter Compress {3} : {0}→{1} {2}", NetworkConverter.ToSizeString(targetStream.Length), NetworkConverter.ToSizeString(list[0].Value.Length), NetworkConverter.ToSizeString(list[0].Value.Length - targetStream.Length), (ConvertCompressionAlgorithm)list[0].Key); } #endif for (int i = 1; i < list.Count; i++) { list[i].Value.Dispose(); } BufferStream metadataStream = new BufferStream(_bufferManager); metadataStream.WriteByte((byte)list[0].Key); return(new UniteStream(metadataStream, list[0].Value)); }
IEnumerable <WebSocketsFrame> IExtension.ApplyIncoming(NetContext context, WebSocketConnection connection, WebSocketsFrame frame) { if (frame.Reserved1 && !frame.IsControlFrame) { BufferStream tmp = null; var payload = frame.Payload; payload.Position = 0; byte[] inBuffer = null, outBuffer = null; try { outBuffer = context.GetBuffer(); inBuffer = context.GetBuffer(); tmp = new BufferStream(context, 0); if (inbound == null) { inbound = new ZStream(); inbound.inflateInit(); // fake a zlib header with: // CMF: // CM = 8 (deflate) // CINFO = 7 (32k window) // FLG: // FCHECK: 26 (checksum of other bits) // FDICT: 0 (no dictionary) // FLEVEL: 3 (maximum) inBuffer[0] = 120; inBuffer[1] = 218; inbound.next_in = inBuffer; int chk = Inflate(tmp, outBuffer, 2); if (chk != 0) { throw new InvalidOperationException("Spoofed zlib header suggested data"); } } inbound.next_in = inBuffer; int remaining = frame.PayloadLength; //bool first = true; while (remaining > 0) { int readCount = payload.Read(inBuffer, 0, inBuffer.Length); if (readCount <= 0) { break; } remaining -= readCount; //if (first) //{ // kill the BFINAL flag from the first block, if set; we don't want zlib // // trying to verify the ADLER checksum; unfortunately, a frame can contain // // multiple blocks, and a *later* block could have BFINAL set. That sucks. // inBuffer[0] &= 254; // first = false; //} Inflate(tmp, outBuffer, readCount); } if (remaining != 0) { throw new EndOfStreamException(); } // spoof the missing 4 bytes from the tail inBuffer[0] = inBuffer[1] = 0x00; inBuffer[2] = inBuffer[3] = 0xFF; Inflate(tmp, outBuffer, 4); // set our final output tmp.Position = 0; frame.Payload = tmp; long bytesSaved = tmp.Length - frame.PayloadLength; frame.PayloadLength = (int)tmp.Length; frame.Reserved1 = false; tmp = payload as BufferStream; parent.RegisterInboundBytesSaved(bytesSaved); } #if DEBUG catch (Exception ex) { Debug.WriteLine(ex); throw; } #endif finally { if (inbound != null) { inbound.next_out = null; inbound.next_in = null; } if (tmp != null) { tmp.Dispose(); } if (inBuffer != null) { context.Recycle(inBuffer); } if (outBuffer != null) { context.Recycle(outBuffer); } if (parent.disableContextTakeover) { ClearContext(true, false); } } } yield return(frame); }
IEnumerable <WebSocketsFrame> IExtension.ApplyOutgoing(NetContext context, WebSocketConnection connection, WebSocketsFrame frame) { if (!frame.IsControlFrame && frame.PayloadLength > parent.compressMessagesLargerThanBytes) { if (frame.Reserved1) { throw new InvalidOperationException("Reserved1 flag is already set; extension conflict?"); } int headerBytes = 0; if (outbound == null) { outbound = new ZStream(); const int BITS = 12; // 4096 byte outbound buffer (instead of full 32k=15) outbound.deflateInit(zlibConst.Z_BEST_COMPRESSION, BITS); headerBytes = 2; } BufferStream tmp = null; var payload = frame.Payload; payload.Position = 0; byte[] inBuffer = null, outBuffer = null; try { inBuffer = context.GetBuffer(); outBuffer = context.GetBuffer(); tmp = new BufferStream(context, 0); outbound.next_out = outBuffer; outbound.next_in = inBuffer; int remaining = frame.PayloadLength; while (remaining > 0) { int readCount = payload.Read(inBuffer, 0, inBuffer.Length); if (readCount <= 0) { break; } remaining -= readCount; outbound.next_in_index = 0; outbound.avail_in = readCount; do { outbound.next_out_index = 0; outbound.avail_out = outBuffer.Length; long priorOut = outbound.total_out; int err = outbound.deflate(remaining == 0 ? zlibConst.Z_SYNC_FLUSH : zlibConst.Z_NO_FLUSH); if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END) { throw new ZStreamException("deflating: " + outbound.msg); } int outCount = (int)(outbound.total_out - priorOut); if (outCount > 0) { if (headerBytes == 0) { tmp.Write(outBuffer, 0, outCount); } else { if (outCount < headerBytes) { throw new InvalidOperationException("Failed to write entire header"); } // check the generated header meets our expectations // CMF is very specific - CM must be 8, and CINFO must be <=7 (for 32k window) if ((outBuffer[0] & 15) != 8) { throw new InvalidOperationException("Zlib CM header was incorrect"); } if ((outBuffer[0] & 128) != 0) // if msb set, is > 7 - invalid { throw new InvalidOperationException("Zlib CINFO header was incorrect"); } // FLG is less important; FCHECK is irrelevent, FLEVEL doesn't matter; but // FDICT must be zero, to ensure that we aren't expecting a an initialization dictionary if ((outBuffer[1] & 32) != 0) { throw new InvalidOperationException("Zlib FLG.FDICT header was set (must not be)"); } // skip the header, and write anything else outCount -= headerBytes; if (outCount > 0) { tmp.Write(outBuffer, headerBytes, outCount); } headerBytes = 0; // all written now } } } while (outbound.avail_in > 0 || outbound.avail_out == 0); } if (remaining != 0) { throw new EndOfStreamException(); } if (headerBytes != 0) { throw new InvalidOperationException("Zlib header was not written"); } // verify the last 4 bytes, then drop them tmp.Position = tmp.Length - 4; NetContext.Fill(tmp, outBuffer, 4); if (!(outBuffer[0] == 0x00 && outBuffer[1] == 0x00 && outBuffer[2] == 0xFF && outBuffer[3] == 0xFF)) { throw new InvalidOperationException("expectation failed: 0000FFFF in the tail"); } if (parent.disableContextTakeover && tmp.Length >= frame.PayloadLength) { // compressing it didn't do anything useful; since we're going to discard // the compression context, we might as well stick with the original data payload.Position = 0; payload = null; // so that it doesn't get disposed } else { // set our final output tmp.Position = 0; tmp.SetLength(tmp.Length - 4); long bytesSaved = frame.PayloadLength - tmp.Length; frame.Payload = tmp; frame.PayloadLength = (int)tmp.Length; frame.Reserved1 = true; tmp = payload as BufferStream; parent.RegisterOutboundBytesSaved(bytesSaved); } } #if DEBUG catch (Exception ex) { Debug.WriteLine(ex); throw; } #endif finally { if (outbound != null) { outbound.next_out = null; outbound.next_in = null; } if (tmp != null) { tmp.Dispose(); } if (inBuffer != null) { context.Recycle(inBuffer); } if (outBuffer != null) { context.Recycle(outBuffer); } if (parent.disableContextTakeover) { ClearContext(false, true); } } } yield return(frame); }
private void MessagingManager_ReceiveEvent <TService>(TService serviceManager, Stream requestStream, Action <Stream> sendAction, Action exitAction) where TService : StateManagerBase, IService { using (var reader = new ItemStreamReader(new WrapperStream(requestStream, true), _bufferManager)) { var type = (AmoebaRequestType)reader.GetUInt32(); int id = (int)reader.GetUInt32(); if (type == AmoebaRequestType.Exit) { SendResponse(AmoebaResponseType.Result, id, (object)null); exitAction(); } else if (type == AmoebaRequestType.Cancel) { if (_tasks.TryGetValue(id, out var responseTask)) { responseTask.Stop(); } } else { var responseTask = ResponseTask.Create((token) => { try { switch (type) { case AmoebaRequestType.GetState: { SendResponse(AmoebaResponseType.Result, id, serviceManager.State); break; } case AmoebaRequestType.Start: { serviceManager.Start(); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.Stop: { serviceManager.Stop(); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.GetReport: { SendResponse(AmoebaResponseType.Result, id, serviceManager.Report); break; } case AmoebaRequestType.GetNetworkConnectionReports: { SendResponse(AmoebaResponseType.Result, id, serviceManager.GetNetworkConnectionReports()); break; } case AmoebaRequestType.GetCacheContentReports: { SendResponse(AmoebaResponseType.Result, id, serviceManager.GetCacheContentReports()); break; } case AmoebaRequestType.GetDownloadContentReports: { SendResponse(AmoebaResponseType.Result, id, serviceManager.GetDownloadContentReports()); break; } case AmoebaRequestType.GetConfig: { SendResponse(AmoebaResponseType.Result, id, serviceManager.Config); break; } case AmoebaRequestType.SetConfig: { var config = JsonUtils.Load <ServiceConfig>(requestStream); serviceManager.SetConfig(config); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.SetCloudLocations: { var cloudLocations = JsonUtils.Load <Location[]>(requestStream); serviceManager.SetCloudLocations(cloudLocations); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.GetSize: { SendResponse(AmoebaResponseType.Result, id, serviceManager.Size); break; } case AmoebaRequestType.Resize: { long size = JsonUtils.Load <long>(requestStream); serviceManager.Resize(size); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.CheckBlocks: { try { serviceManager.CheckBlocks(new Progress <CheckBlocksProgressReport>((report) => { SendResponse(AmoebaResponseType.Output, id, report); }), token).Wait(); } catch (Exception) { } SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.AddContent: { var arguments = JsonUtils.Load <(string, DateTime)>(requestStream); var result = serviceManager.AddContent(arguments.Item1, arguments.Item2, token).Result; SendResponse(AmoebaResponseType.Result, id, result); break; } case AmoebaRequestType.RemoveContent: { string path = JsonUtils.Load <string>(requestStream); serviceManager.RemoveContent(path); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.Diffusion: { string path = JsonUtils.Load <string>(requestStream); serviceManager.Diffusion(path); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.AddDownload: { var arguments = JsonUtils.Load <(Metadata, string, long)>(requestStream); serviceManager.AddDownload(arguments.Item1, arguments.Item2, arguments.Item3); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.RemoveDownload: { var arguments = JsonUtils.Load <(Metadata, string)>(requestStream); serviceManager.RemoveDownload(arguments.Item1, arguments.Item2); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.ResetDownload: { var arguments = JsonUtils.Load <(Metadata, string)>(requestStream); serviceManager.ResetDownload(arguments.Item1, arguments.Item2); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.SetProfile: { var arguments = JsonUtils.Load <(Profile, DigitalSignature)>(requestStream); serviceManager.SetProfile(arguments.Item1, arguments.Item2, token).Wait(); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.SetStore: { var arguments = JsonUtils.Load <(Store, DigitalSignature)>(requestStream); serviceManager.SetStore(arguments.Item1, arguments.Item2, token).Wait(); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.SetMailMessage: { var arguments = JsonUtils.Load <(Signature, MailMessage, ExchangePublicKey, DigitalSignature)>(requestStream); serviceManager.SetMailMessage(arguments.Item1, arguments.Item2, arguments.Item3, arguments.Item4, token).Wait(); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.SetChatMessage: { var arguments = JsonUtils.Load <(Tag, ChatMessage, DigitalSignature, TimeSpan)>(requestStream); serviceManager.SetChatMessage(arguments.Item1, arguments.Item2, arguments.Item3, arguments.Item4, token).Wait(); SendResponse(AmoebaResponseType.Result, id, (object)null); break; } case AmoebaRequestType.GetProfile: { var signature = JsonUtils.Load <Signature>(requestStream); var result = serviceManager.GetProfile(signature, token).Result; SendResponse(AmoebaResponseType.Result, id, result); break; } case AmoebaRequestType.GetStore: { var signature = JsonUtils.Load <Signature>(requestStream); var result = serviceManager.GetStore(signature, token).Result; SendResponse(AmoebaResponseType.Result, id, result); break; } case AmoebaRequestType.GetMailMessages: { var arguments = JsonUtils.Load <(Signature, ExchangePrivateKey)>(requestStream); var result = serviceManager.GetMailMessages(arguments.Item1, arguments.Item2, token).Result; SendResponse(AmoebaResponseType.Result, id, result); break; } case AmoebaRequestType.GetChatMessages: { var tag = JsonUtils.Load <Tag>(requestStream); var result = serviceManager.GetChatMessages(tag, token).Result; SendResponse(AmoebaResponseType.Result, id, result); break; } } } catch (Exception e) { SendResponse(AmoebaResponseType.Error, id, e.Message); } finally { _tasks.Remove(id); } }); _tasks.Add(id, responseTask); responseTask.Start(); } } void SendResponse <T>(AmoebaResponseType type, int id, T value) { using (var writer = new ItemStreamWriter(_bufferManager)) { writer.Write((uint)type); writer.Write((uint)id); Stream valueStream = null; if (value != null) { try { valueStream = new BufferStream(_bufferManager); JsonUtils.Save(valueStream, value); } catch (Exception) { if (valueStream != null) { valueStream.Dispose(); valueStream = null; } return; } } sendAction(new UniteStream(writer.GetStream(), valueStream)); } } }
protected override int ProcessIncoming(NetContext context, Connection connection, Stream incoming) { if (incoming.Length < 2) return 0; // can't read that; frame takes at minimum two bytes byte[] buffer = null; try { buffer = context.GetBuffer(); int read; // read as much as possible up to 14 bytes; that gives us space for 2 bytes frame header, 8 bytes length, and 4 bytes mask read = NetContext.TryFill(incoming, buffer, 14); int headerLength; var frame = WebSocketsFrame.TryParseFrameHeader(buffer, read, out headerLength); if (frame == null) return 0; int payloadLen = frame.PayloadLength; #if VERBOSE Debug.WriteLine("Parsed header from: " + BitConverter.ToString(buffer, 0, headerLength)); #endif if (incoming.Length < headerLength + payloadLen) return 0; // not enough data to read the payload if (payloadLen != 0) { Stream payload = null; try { payload = new BufferStream(context, context.Handler.MaxIncomingQuota); if (read != headerLength) incoming.Position -= (read - headerLength); // we got it wrong... Copy(incoming, payload, buffer, frame.Mask, payloadLen); if (payloadLen != payload.Length) { throw new InvalidOperationException("I munged the data"); } frame.Payload = payload; payload = null; } finally { if (payload != null) payload.Dispose(); } } foreach (var final in ApplyExtensions(context, connection, frame, true)) { ProcessFrame(context, connection, final); } return headerLength + payloadLen; } finally { context.Recycle(buffer); } }
private static Stream Decompress(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } try { stream.Seek(0, SeekOrigin.Begin); int type = (int)Varint.GetUInt64(stream); if (type == (int)ConvertCompressionAlgorithm.None) { return(new RangeStream(stream)); } else if (type == (int)ConvertCompressionAlgorithm.Deflate) { BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = deflateStream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { deflateBufferStream.Write(safeBuffer.Value, 0, length); if (deflateBufferStream.Length > 1024 * 1024 * 256) { throw new Exception("too large"); } } } deflateBufferStream.Seek(0, SeekOrigin.Begin); return(deflateBufferStream); } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } throw; } } else { throw new ArgumentException("ArgumentException"); } } catch (Exception e) { if (stream != null) { stream.Dispose(); } throw new ArgumentException(e.Message, e); } }
public override void Send(System.IO.Stream stream, TimeSpan timeout, Information options) { if (_disposed) { throw new ObjectDisposedException(this.GetType().FullName); } if (!_connect) { throw new ConnectionException(); } if (stream == null) { throw new ArgumentNullException("stream"); } if (stream.Length == 0) { throw new ArgumentOutOfRangeException("stream"); } bool isCompress = true; if (options != null) { if (options.Contains("IsCompress")) { isCompress = (bool)options["IsCompress"]; } } lock (_sendLock) { using (RangeStream targetStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true)) { try { List <KeyValuePair <byte, Stream> > list = new List <KeyValuePair <byte, Stream> >(); if (isCompress) { if (_otherCompressAlgorithm.HasFlag(CompressAlgorithm.Deflate)) { BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true)) { byte[] compressBuffer = null; try { compressBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = targetStream.Read(compressBuffer, 0, compressBuffer.Length)) > 0) { deflateStream.Write(compressBuffer, 0, i); } } finally { if (compressBuffer != null) { _bufferManager.ReturnBuffer(compressBuffer); } } } deflateBufferStream.Seek(0, SeekOrigin.Begin); list.Add(new KeyValuePair <byte, Stream>((byte)1, deflateBufferStream)); } catch (Exception e) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } throw e; } } } list.Add(new KeyValuePair <byte, Stream>((byte)0, new WrapperStream(targetStream, true))); list.Sort((x, y) => { int c = x.Value.Length.CompareTo(y.Value.Length); if (c != 0) { return(c); } return(x.Key.CompareTo(y.Key)); }); #if DEBUG if (list[0].Value.Length != targetStream.Length) { Debug.WriteLine("Send : {0}→{1} {2}", NetworkConverter.ToSizeString(targetStream.Length), NetworkConverter.ToSizeString(list[0].Value.Length), NetworkConverter.ToSizeString(list[0].Value.Length - targetStream.Length)); } #endif for (int i = 1; i < list.Count; i++) { list[i].Value.Dispose(); } BufferStream headerStream = new BufferStream(_bufferManager); headerStream.WriteByte((byte)list[0].Key); using (var dataStream = new UniteStream(headerStream, list[0].Value)) { _connection.Send(dataStream, timeout, options); } } catch (ConnectionException e) { throw e; } catch (Exception e) { throw new ConnectionException(e.Message, e); } } } }
private static Stream Encrypt(Stream stream, ExchangePublicKey publicKey) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (publicKey == null) { throw new ArgumentNullException(nameof(publicKey)); } try { BufferStream outStream = null; try { outStream = new BufferStream(_bufferManager); Varint.SetUInt64(outStream, (uint)ConvertCryptoAlgorithm.Aes256); var cryptoKey = new byte[32]; var iv = new byte[32]; using (var random = RandomNumberGenerator.Create()) { random.GetBytes(cryptoKey); random.GetBytes(iv); } { var encryptedBuffer = Exchange.Encrypt(publicKey, cryptoKey); Varint.SetUInt64(outStream, (uint)encryptedBuffer.Length); outStream.Write(encryptedBuffer, 0, encryptedBuffer.Length); } outStream.Write(iv, 0, iv.Length); using (var aes = Aes.Create()) { aes.KeySize = 256; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (var inStream = new WrapperStream(stream, true)) using (var cs = new CryptoStream(inStream, aes.CreateEncryptor(cryptoKey, iv), CryptoStreamMode.Read)) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = cs.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { outStream.Write(safeBuffer.Value, 0, length); } } } outStream.Seek(0, SeekOrigin.Begin); } catch (Exception) { if (outStream != null) { outStream.Dispose(); } throw; } return(outStream); } catch (Exception e) { throw new ArgumentException(e.Message, e); } finally { if (stream != null) { stream.Dispose(); } } }
IEnumerable<WebSocketsFrame> IExtension.ApplyIncoming(NetContext context, WebSocketConnection connection, WebSocketsFrame frame) { if (frame.Reserved1 && !frame.IsControlFrame) { BufferStream tmp = null; var payload = frame.Payload; payload.Position = 0; byte[] inBuffer = null, outBuffer = null; try { outBuffer = context.GetBuffer(); inBuffer = context.GetBuffer(); tmp = new BufferStream(context, 0); if (inbound == null) { inbound = new ZStream(); inbound.inflateInit(); // fake a zlib header with: // CMF: // CM = 8 (deflate) // CINFO = 7 (32k window) // FLG: // FCHECK: 26 (checksum of other bits) // FDICT: 0 (no dictionary) // FLEVEL: 3 (maximum) inBuffer[0] = 120; inBuffer[1] = 218; inbound.next_in = inBuffer; int chk = Inflate(tmp, outBuffer, 2); if (chk != 0) throw new InvalidOperationException("Spoofed zlib header suggested data"); } inbound.next_in = inBuffer; int remaining = frame.PayloadLength; //bool first = true; while (remaining > 0) { int readCount = payload.Read(inBuffer, 0, inBuffer.Length); if (readCount <= 0) break; remaining -= readCount; //if (first) //{ // kill the BFINAL flag from the first block, if set; we don't want zlib // // trying to verify the ADLER checksum; unfortunately, a frame can contain // // multiple blocks, and a *later* block could have BFINAL set. That sucks. // inBuffer[0] &= 254; // first = false; //} Inflate(tmp, outBuffer, readCount); } if (remaining != 0) throw new EndOfStreamException(); // spoof the missing 4 bytes from the tail inBuffer[0] = inBuffer[1] = 0x00; inBuffer[2] = inBuffer[3] = 0xFF; Inflate(tmp, outBuffer, 4); // set our final output tmp.Position = 0; frame.Payload = tmp; long bytesSaved = tmp.Length - frame.PayloadLength; frame.PayloadLength = (int)tmp.Length; frame.Reserved1 = false; tmp = payload as BufferStream; parent.RegisterInboundBytesSaved(bytesSaved); } #if DEBUG catch (Exception ex) { Debug.WriteLine(ex); throw; } #endif finally { if (inbound != null) { inbound.next_out = null; inbound.next_in = null; } if (tmp != null) tmp.Dispose(); if (inBuffer != null) context.Recycle(inBuffer); if (outBuffer != null) context.Recycle(outBuffer); if (parent.disableContextTakeover) ClearContext(true, false); } } yield return frame; }
private static Stream Decompress(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } try { var targetStream = new RangeStream(stream, true); byte type = (byte)targetStream.ReadByte(); if (type == (byte)ConvertCompressionAlgorithm.None) { return(new RangeStream(targetStream)); } else if (type == (byte)ConvertCompressionAlgorithm.Deflate) { using (Stream dataStream = new WrapperStream(targetStream, true)) { BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(dataStream, CompressionMode.Decompress, true)) { byte[] decompressBuffer = null; try { decompressBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = deflateStream.Read(decompressBuffer, 0, decompressBuffer.Length)) > 0) { deflateBufferStream.Write(decompressBuffer, 0, i); } } finally { if (decompressBuffer != null) { _bufferManager.ReturnBuffer(decompressBuffer); } } } deflateBufferStream.Seek(0, SeekOrigin.Begin); #if DEBUG Debug.WriteLine("ContentConverter Decompress {3} : {0}→{1} {2}", NetworkConverter.ToSizeString(dataStream.Length), NetworkConverter.ToSizeString(deflateBufferStream.Length), NetworkConverter.ToSizeString(dataStream.Length - deflateBufferStream.Length), ConvertCompressionAlgorithm.Deflate); #endif return(deflateBufferStream); } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } } } } throw new ArgumentException("ArgumentException"); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }