diff --git a/src/Microsoft.AspNet.Server.Kestrel/Filter/LibuvStream.cs b/src/Microsoft.AspNet.Server.Kestrel/Filter/LibuvStream.cs index 4f63195760..d61c0eafbc 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Filter/LibuvStream.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Filter/LibuvStream.cs @@ -85,7 +85,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Filter private Task ReadAsync(ArraySegment buffer) { - return _input.ReadAsync(buffer); + return _input.ReadAsync(buffer.Array, buffer.Offset, buffer.Count); } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs index 7e75fcb1bb..11a15e249b 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/MessageBody.cs @@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http var firstLoop = true; do { - result = SkipAsyncImplementation(cancellationToken); + result = ReadAsyncImplementation(default(ArraySegment), cancellationToken); if (!result.IsCompleted) { if (firstLoop && Interlocked.Exchange(ref _send100Continue, 0) == 1) @@ -68,8 +68,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http public abstract Task ReadAsyncImplementation(ArraySegment buffer, CancellationToken cancellationToken); - public abstract Task SkipAsyncImplementation(CancellationToken cancellationToken); - public static MessageBody For( string httpVersion, IDictionary headers, @@ -138,11 +136,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http public override Task ReadAsyncImplementation(ArraySegment buffer, CancellationToken cancellationToken) { - return _context.SocketInput.ReadAsync(buffer); - } - public override Task SkipAsyncImplementation(CancellationToken cancellationToken) - { - return _context.SocketInput.SkipAsync(4096); + return _context.SocketInput.ReadAsync(buffer.Array, buffer.Offset, buffer.Array == null ? 8192 : buffer.Count); } } @@ -163,35 +157,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { var input = _context.SocketInput; - var limit = Math.Min(buffer.Count, _inputLength); + var limit = buffer.Array == null ? _inputLength : Math.Min(buffer.Count, _inputLength); if (limit == 0) { return 0; } - var limitedBuffer = new ArraySegment(buffer.Array, buffer.Offset, limit); - var actual = await _context.SocketInput.ReadAsync(limitedBuffer); - _inputLength -= actual; - - if (actual == 0) - { - throw new InvalidDataException("Unexpected end of request content"); - } - - return actual; - } - - public override async Task SkipAsyncImplementation(CancellationToken cancellationToken) - { - var input = _context.SocketInput; - - var limit = Math.Min(4096, _inputLength); - if (limit == 0) - { - return 0; - } - - var actual = await _context.SocketInput.SkipAsync(limit); + var actual = await _context.SocketInput.ReadAsync(buffer.Array, buffer.Offset, limit); _inputLength -= actual; if (actual == 0) @@ -244,7 +216,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } while (_mode == Mode.ChunkData) { - var limit = Math.Min(buffer.Count, _inputLength); + var limit = buffer.Array == null ? _inputLength : Math.Min(buffer.Count, _inputLength); if (limit != 0) { await input; @@ -291,78 +263,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return 0; } - public override async Task SkipAsyncImplementation(CancellationToken cancellationToken) - { - var input = _context.SocketInput; - - while (_mode != Mode.Complete) - { - while (_mode == Mode.ChunkPrefix) - { - var chunkSize = 0; - if (!TakeChunkedLine(input, ref chunkSize)) - { - await input; - } - else if (chunkSize == 0) - { - _mode = Mode.Complete; - } - else - { - _mode = Mode.ChunkData; - } - _inputLength = chunkSize; - } - while (_mode == Mode.ChunkData) - { - var limit = Math.Min(4096, _inputLength); - if (limit != 0) - { - await input; - } - - var begin = input.ConsumingStart(); - int actual; - var end = begin.Skip(limit, out actual); - _inputLength -= actual; - input.ConsumingComplete(end, end); - - if (_inputLength == 0) - { - _mode = Mode.ChunkSuffix; - } - if (actual != 0) - { - return actual; - } - } - while (_mode == Mode.ChunkSuffix) - { - var scan = input.ConsumingStart(); - var consumed = scan; - var ch1 = scan.Take(); - var ch2 = scan.Take(); - if (ch1 == -1 || ch2 == -1) - { - input.ConsumingComplete(consumed, scan); - await input; - } - else if (ch1 == '\r' && ch2 == '\n') - { - input.ConsumingComplete(scan, scan); - _mode = Mode.ChunkPrefix; - } - else - { - throw new NotImplementedException("INVALID REQUEST FORMAT"); - } - } - } - - return 0; - } - private static bool TakeChunkedLine(SocketInput baton, ref int chunkSizeOut) { var scan = baton.ConsumingStart(); diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/SocketInputExtensions.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/SocketInputExtensions.cs index 70a491565d..c36d88155d 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/SocketInputExtensions.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/SocketInputExtensions.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { public static class SocketInputExtensions { - public static async Task ReadAsync(this SocketInput input, ArraySegment buffer) + public static async Task ReadAsync(this SocketInput input, byte[] buffer, int offset, int count) { while (true) { @@ -16,29 +16,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http var begin = input.ConsumingStart(); int actual; - var end = begin.CopyTo(buffer.Array, buffer.Offset, buffer.Count, out actual); - input.ConsumingComplete(end, end); - - if (actual != 0) - { - return actual; - } - if (input.RemoteIntakeFin) - { - return 0; - } - } - } - - public static async Task SkipAsync(this SocketInput input, int limit) - { - while (true) - { - await input; - - var begin = input.ConsumingStart(); - int actual; - var end = begin.Skip(limit, out actual); + var end = begin.CopyTo(buffer, offset, count, out actual); input.ConsumingComplete(end, end); if (actual != 0) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs index c14534a176..ddb12bff7f 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs @@ -600,18 +600,27 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure if (remaining <= following) { actual = count; - Buffer.BlockCopy(block.Array, index, array, offset, remaining); + if (array != null) + { + Buffer.BlockCopy(block.Array, index, array, offset, remaining); + } return new MemoryPoolIterator2(block, index + remaining); } else if (block.Next == null) { actual = count - remaining + following; - Buffer.BlockCopy(block.Array, index, array, offset, following); + if (array != null) + { + Buffer.BlockCopy(block.Array, index, array, offset, following); + } return new MemoryPoolIterator2(block, index + following); } else { - Buffer.BlockCopy(block.Array, index, array, offset, following); + if (array != null) + { + Buffer.BlockCopy(block.Array, index, array, offset, following); + } offset += following; remaining -= following; block = block.Next; @@ -619,37 +628,5 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure } } } - public MemoryPoolIterator2 Skip(int limit, out int actual) - { - if (IsDefault) - { - actual = 0; - return this; - } - - var block = _block; - var index = _index; - var remaining = limit; - while (true) - { - var following = block.End - index; - if (remaining <= following) - { - actual = limit; - return new MemoryPoolIterator2(block, index + remaining); - } - else if (block.Next == null) - { - actual = limit - remaining + following; - return new MemoryPoolIterator2(block, index + following); - } - else - { - remaining -= following; - block = block.Next; - index = block.Start; - } - } - } } }