예제 #1
0
        // 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));
        }
예제 #2
0
            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);
            }
예제 #3
0
                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);
                }