// used for buffered streaming internal async Task <ArraySegment <byte> > BufferMessageStreamAsync(Stream stream, BufferManager bufferManager, int maxBufferSize) { byte[] buffer = bufferManager.TakeBuffer(ConnectionOrientedTransportDefaults.ConnectionBufferSize); int offset = 0; int currentBufferSize = Math.Min(buffer.Length, maxBufferSize); while (offset < currentBufferSize) { int count = await stream.ReadAsync(buffer, offset, currentBufferSize - offset); if (count == 0) { stream.Dispose(); break; } offset += count; if (offset == currentBufferSize) { if (currentBufferSize >= maxBufferSize) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(maxBufferSize)); } currentBufferSize = Math.Min(currentBufferSize * 2, maxBufferSize); byte[] temp = bufferManager.TakeBuffer(currentBufferSize); Buffer.BlockCopy(buffer, 0, temp, 0, offset); bufferManager.ReturnBuffer(buffer); buffer = temp; } } return(new ArraySegment <byte>(buffer, 0, offset)); }
private Message DecodeMessage(ref ReadOnlySequence <byte> buffer) { int maxBufferSize = _connection.MaxBufferSize; var decoder = (ServerSessionDecoder)_connection.FramingDecoder; while (!_connection.EOF && buffer.Length > 0) { int bytesRead = decoder.Decode(buffer); if (bytesRead > 0) { if (!_connection.EnvelopeBuffer.IsEmpty) { var remainingEnvelopeBuffer = _connection.EnvelopeBuffer.Slice(_connection.EnvelopeOffset, _connection.EnvelopeSize - _connection.EnvelopeOffset); CopyBuffer(buffer, remainingEnvelopeBuffer, bytesRead); _connection.EnvelopeOffset += bytesRead; } buffer = buffer.Slice(bytesRead); } switch (decoder.CurrentState) { case ServerSessionDecoder.State.EnvelopeStart: int envelopeSize = decoder.EnvelopeSize; if (envelopeSize > maxBufferSize) { // TODO: Remove synchronous wait. This is needed because the buffer is passed by ref. _connection.SendFaultAsync(FramingEncodingString.MaxMessageSizeExceededFault, _connection.ServiceDispatcher.Binding.SendTimeout, TransportDefaults.MaxDrainSize).GetAwaiter().GetResult(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(maxBufferSize)); } _connection.EnvelopeBuffer = _connection.BufferManager.TakeBuffer(envelopeSize); _connection.EnvelopeSize = envelopeSize; _connection.EnvelopeOffset = 0; break; case ServerSessionDecoder.State.EnvelopeEnd: if (!_connection.EnvelopeBuffer.IsEmpty) { Message message = null; try { message = _connection.MessageEncoder.ReadMessage( new ArraySegment <byte>(_connection.EnvelopeBuffer.ToArray(), 0, _connection.EnvelopeSize), _connection.BufferManager, _connection.FramingDecoder.ContentType); } catch (XmlException xmlException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.MessageXmlProtocolError, xmlException)); } _connection.EnvelopeBuffer = null; return(message); } break; case ServerSessionDecoder.State.End: _connection.EOF = true; break; } } return(null); }
protected override Message DecodeMessage(byte[] buffer, ref int offset, ref int size, ref bool isAtEof, TimeSpan timeout) { while (!isAtEof && size > 0) { int bytesRead = decoder.Decode(buffer, offset, size); if (bytesRead > 0) { if (EnvelopeBuffer != null) { if (!object.ReferenceEquals(buffer, EnvelopeBuffer)) { System.Buffer.BlockCopy(buffer, offset, EnvelopeBuffer, EnvelopeOffset, bytesRead); } EnvelopeOffset += bytesRead; } offset += bytesRead; size -= bytesRead; } switch (decoder.CurrentState) { case ServerSessionDecoder.State.EnvelopeStart: int envelopeSize = decoder.EnvelopeSize; if (envelopeSize > maxBufferSize) { base.SendFault(FramingEncodingString.MaxMessageSizeExceededFault, timeout); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( MaxMessageSizeStream.CreateMaxReceivedMessageSizeExceededException(maxBufferSize)); } EnvelopeBuffer = bufferManager.TakeBuffer(envelopeSize); EnvelopeOffset = 0; EnvelopeSize = envelopeSize; break; case ServerSessionDecoder.State.EnvelopeEnd: if (EnvelopeBuffer != null) { Message message = null; try { message = messageEncoder.ReadMessage(new ArraySegment <byte>(EnvelopeBuffer, 0, EnvelopeSize), bufferManager, contentType); } catch (XmlException xmlException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.Format(SR.MessageXmlProtocolError), xmlException)); } EnvelopeBuffer = null; return(message); } break; case ServerSessionDecoder.State.End: isAtEof = true; break; } } return(null); }