コード例 #1
0
        public void Decode_decodes_base64_in_multiple_parts()
        {
            var data   = "This is a Test!";
            var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));

            var decoder = new SimpleBase64InplaceDecoder();
            var buffer  = Encoding.UTF8.GetBytes(base64);

            var first = new byte[10];

            Buffer.BlockCopy(buffer, 0, first, 0, first.Length);

            var length = decoder.Decode(first, first.Length, out int offset);
            var result = Encoding.UTF8.GetString(first, 0, length);

            var remaining = new byte[buffer.Length];

            if (offset != first.Length)
            {
                Buffer.BlockCopy(first, offset, remaining, 0, first.Length - offset);
            }

            offset = first.Length - offset;

            Buffer.BlockCopy(buffer, first.Length, remaining, offset, buffer.Length - 10);

            length = decoder.Decode(remaining, offset + buffer.Length - 10, out offset);

            result += Encoding.UTF8.GetString(remaining, 0, length);

            result.Should().Be(data);
        }
コード例 #2
0
        public void Decode_decodes_base64()
        {
            var data   = "This is a Test!";
            var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));

            var decoder = new SimpleBase64InplaceDecoder();
            var buffer  = Encoding.UTF8.GetBytes(base64);
            var length  = decoder.Decode(buffer, buffer.Length, out int offset);

            Encoding.UTF8.GetString(buffer, 0, length).Should().Be(data);
        }
コード例 #3
0
        public async Task <string> ExtractBodyAsync()
        {
            var temporaryId = Guid.NewGuid().ToString();

            _logger?.Verbose("Extracting body from legacy on-premise response. temporary-id={TemporaryId}", temporaryId);

            var streamPosition = 0;
            var offset         = 0;
            var overlap        = 0;

            while (true)
            {
                var length = await _sourceStream.ReadAsync(_buffer, offset, _buffer.Length - offset).ConfigureAwait(false);

                if (length == 0)
                {
                    // nothing more to read but overlapping bytes should be written finally
                    await WriteAsync(_buffer, 0, overlap).ConfigureAwait(false);

                    break;
                }

                streamPosition += length;

                length += offset;

                var position = Search(_buffer, length, _bodyStart);
                if (position != 0)
                {
                    _logger?.Verbose("Found body value start in legacy on-premise response. temporary-id={TemporaryId}, body-start={BodyStart}", temporaryId, streamPosition - length + position);

                    await WriteAsync(_buffer, 0, position).ConfigureAwait(false);

                    length -= position;
                    Buffer.BlockCopy(_buffer, position, _buffer, 0, length);
                    offset = 0;

                    var decoder = new SimpleBase64InplaceDecoder();
                    int decoded;

                    using (var stream = _postDataTemporaryStore.CreateResponseStream(temporaryId))
                    {
                        while (true)
                        {
                            length += offset;

                            position = Search(_buffer, length, _bodyEnd);
                            if (position != 0)
                            {
                                _logger?.Verbose("Found body value end in legacy on-premise response. temporary-id={TemporaryId}, body-end={BodyEnd}", temporaryId, streamPosition - length + position);

                                position -= _bodyEnd.Length;

                                decoded = decoder.Decode(_buffer, position, out offset);
                                if (offset != position)
                                {
                                    throw new InvalidOperationException("Unexpected end of base64 response.");
                                }

                                await stream.WriteAsync(_buffer, 0, decoded).ConfigureAwait(false);

                                await WriteAsync(_buffer, position, length - position).ConfigureAwait(false);

                                break;
                            }


                            decoded = decoder.Decode(_buffer, length, out offset);
                            await stream.WriteAsync(_buffer, 0, decoded).ConfigureAwait(false);

                            if (offset != length)
                            {
                                Buffer.BlockCopy(_buffer, offset, _buffer, 0, length - offset);
                            }

                            offset = length - offset;

                            length = await _sourceStream.ReadAsync(_buffer, offset, _buffer.Length - offset).ConfigureAwait(false);

                            if (length == 0)
                            {
                                throw new InvalidOperationException("Unexpected end of base64 response.");
                            }

                            streamPosition += length;
                        }
                    }

                    while (true)
                    {
                        length = await _sourceStream.ReadAsync(_buffer, 0, _buffer.Length).ConfigureAwait(false);

                        if (length == 0)
                        {
                            break;
                        }

                        await WriteAsync(_buffer, 0, length).ConfigureAwait(false);
                    }

                    break;
                }

                // keep some overlapping bytes
                overlap = Math.Max(length - _bodyStart.Length, 0);
                offset  = Math.Min(_bodyStart.Length, length);

                await WriteAsync(_buffer, 0, length - offset).ConfigureAwait(false);

                Buffer.BlockCopy(_buffer, overlap, _buffer, 0, offset);
            }

            // rewind
            Position = 0;

            return(temporaryId);
        }