Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Empty buffer when null buffer #439

Merged
merged 2 commits into from
Dec 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Filter
{
public class StreamSocketOutput : ISocketOutput
{
private static readonly byte[] _nullBuffer = new byte[0];

private readonly Stream _outputStream;
private readonly MemoryPool2 _memory;
private MemoryPoolBlock2 _producingBlock;
Expand All @@ -24,13 +26,13 @@ public StreamSocketOutput(Stream outputStream, MemoryPool2 memory)

void ISocketOutput.Write(ArraySegment<byte> buffer, bool immediate)
{
_outputStream.Write(buffer.Array, buffer.Offset, buffer.Count);
_outputStream.Write(buffer.Array ?? _nullBuffer, buffer.Offset, buffer.Count);
}

Task ISocketOutput.WriteAsync(ArraySegment<byte> buffer, bool immediate, CancellationToken cancellationToken)
{
// TODO: Use _outputStream.WriteAsync
_outputStream.Write(buffer.Array, buffer.Offset, buffer.Count);
_outputStream.Write(buffer.Array ?? _nullBuffer, buffer.Offset, buffer.Count);
return TaskUtilities.CompletedTask;
}

Expand Down
106 changes: 106 additions & 0 deletions test/Microsoft.AspNet.Server.KestrelTests/StreamSocketOutputTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;
using Microsoft.AspNet.Server.Kestrel.Filter;
using Microsoft.AspNet.Server.Kestrel.Http;
using Xunit;

namespace Microsoft.AspNet.Server.KestrelTests
{
public class StreamSocketOutputTests
{
[Fact]
public void DoesNotThrowForNullBuffers()
{
// This test was added because SslStream throws if passed null buffers with (count == 0)
// Which happens if ProduceEnd is called in Frame without _responseStarted == true
// As it calls ProduceStart with write immediate == true
// This happens in WebSocket Upgrade over SSL

ISocketOutput socketOutput = new StreamSocketOutput(new ThrowsOnNullWriteStream(), null);

// Should not throw
socketOutput.Write(default(ArraySegment<byte>), true);

Assert.True(true);
}

private class ThrowsOnNullWriteStream : Stream
{
public override bool CanRead
{
get
{
throw new NotImplementedException();
}
}

public override bool CanSeek
{
get
{
throw new NotImplementedException();
}
}

public override bool CanWrite
{
get
{
throw new NotImplementedException();
}
}

public override long Length
{
get
{
throw new NotImplementedException();
}
}

public override long Position
{
get
{
throw new NotImplementedException();
}

set
{
throw new NotImplementedException();
}
}

public override void Flush()
{
throw new NotImplementedException();
}

public override int Read(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}

public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}

public override void SetLength(long value)
{
throw new NotImplementedException();
}

public override void Write(byte[] buffer, int offset, int count)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
}
}
}
}