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

Xmas combo #519

Closed
wants to merge 25 commits into from
Closed
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 @@ -74,11 +74,7 @@ public override void SetLength(long value)

public override void Write(byte[] buffer, int offset, int count)
{
var inputBuffer = _socketInput.IncomingStart(count);

Buffer.BlockCopy(buffer, offset, inputBuffer.Data.Array, inputBuffer.Data.Offset, count);

_socketInput.IncomingComplete(count, error: null);
_socketInput.IncomingData(buffer, offset, count);
}

public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token)
Expand All @@ -90,7 +86,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati
protected override void Dispose(bool disposing)
{
// Close _socketInput with a fake zero-length write that will result in a zero-length read.
_socketInput.IncomingComplete(0, error: null);
_socketInput.IncomingData(null, 0, 0);
base.Dispose(disposing);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ public void ProducingComplete(MemoryPoolIterator2 end)

var returnBlock = block;
block = block.Next;
returnBlock.Pool?.Return(returnBlock);
returnBlock.Pool.Return(returnBlock);
}

_outputStream.Write(end.Block.Array, end.Block.Data.Offset, end.Index - end.Block.Data.Offset);
end.Block.Pool?.Return(end.Block);
end.Block.Pool.Return(end.Block);
}
}
}
6 changes: 3 additions & 3 deletions src/Microsoft.AspNet.Server.Kestrel/Http/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ private static Libuv.uv_buf_t AllocCallback(UvStreamHandle handle, int suggested

private Libuv.uv_buf_t OnAlloc(UvStreamHandle handle, int suggestedSize)
{
var result = _rawSocketInput.IncomingStart(2048);
var result = _rawSocketInput.IncomingRawStart();

return handle.Libuv.buf_init(
result.DataPtr,
result.Data.Count);
result.Pin + result.End,
result.BlockEndOffset - result.End);
}

private static void ReadCallback(UvStreamHandle handle, int status, object state)
Expand Down
98 changes: 56 additions & 42 deletions src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -40,11 +41,11 @@ public abstract partial class Frame : FrameContext, IFrameControl
private static readonly byte[] _bytesDate = Encoding.ASCII.GetBytes("Date: ");
private static readonly byte[] _bytesEndHeaders = Encoding.ASCII.GetBytes("\r\n\r\n");

private static readonly Vector<byte> _vectorCRs = new Vector<byte>((byte)'\r');
private static readonly Vector<byte> _vectorColons = new Vector<byte>((byte)':');
private static readonly Vector<byte> _vectorSpaces = new Vector<byte>((byte)' ');
private static readonly Vector<byte> _vectorQuestionMarks = new Vector<byte>((byte)'?');
private static readonly Vector<byte> _vectorPercentages = new Vector<byte>((byte)'%');
private static Vector<byte> _vectorCRs = new Vector<byte>((byte)'\r');
private static Vector<byte> _vectorColons = new Vector<byte>((byte)':');
private static Vector<byte> _vectorSpaces = new Vector<byte>((byte)' ');
private static Vector<byte> _vectorQuestionMarks = new Vector<byte>((byte)'?');
private static Vector<byte> _vectorPercentages = new Vector<byte>((byte)'%');

private readonly object _onStartingSync = new Object();
private readonly object _onCompletedSync = new Object();
Expand Down Expand Up @@ -427,7 +428,7 @@ public void Write(ArraySegment<byte> data)
}
else
{
SocketOutput.Write(data, immediate: true);
SocketOutput.Write(data, immediate: !SocketInput.IsCompleted);
}
}

Expand All @@ -448,7 +449,7 @@ public Task WriteAsync(ArraySegment<byte> data, CancellationToken cancellationTo
}
else
{
return SocketOutput.WriteAsync(data, immediate: true, cancellationToken: cancellationToken);
return SocketOutput.WriteAsync(data, immediate: !SocketInput.IsCompleted, cancellationToken: cancellationToken);
}
}

Expand All @@ -466,39 +467,40 @@ public async Task WriteAsyncAwaited(ArraySegment<byte> data, CancellationToken c
}
else
{
await SocketOutput.WriteAsync(data, immediate: true, cancellationToken: cancellationToken);
await SocketOutput.WriteAsync(data, immediate: !SocketInput.IsCompleted, cancellationToken: cancellationToken);
}
}

private void WriteChunked(ArraySegment<byte> data)
{
SocketOutput.Write(BeginChunkBytes(data.Count), immediate: false);
var tenByteBuffer = ArrayPool<byte>.Shared.Rent(10);
SocketOutput.Write(BeginChunkBytes(data.Count, tenByteBuffer), immediate: false);
ArrayPool<byte>.Shared.Return(tenByteBuffer);
SocketOutput.Write(data, immediate: false);
SocketOutput.Write(_endChunkBytes, immediate: true);
}

private async Task WriteChunkedAsync(ArraySegment<byte> data, CancellationToken cancellationToken)
{
await SocketOutput.WriteAsync(BeginChunkBytes(data.Count), immediate: false, cancellationToken: cancellationToken);
var tenByteBuffer = ArrayPool<byte>.Shared.Rent(10);
await SocketOutput.WriteAsync(BeginChunkBytes(data.Count, tenByteBuffer), immediate: false, cancellationToken: cancellationToken);
ArrayPool<byte>.Shared.Return(tenByteBuffer);
await SocketOutput.WriteAsync(data, immediate: false, cancellationToken: cancellationToken);
await SocketOutput.WriteAsync(_endChunkBytes, immediate: true, cancellationToken: cancellationToken);
}

public static ArraySegment<byte> BeginChunkBytes(int dataCount)
public static ArraySegment<byte> BeginChunkBytes(int dataCount, byte[] tenByteBuffer)
{
var bytes = new byte[10]
{
_hex[((dataCount >> 0x1c) & 0x0f)],
_hex[((dataCount >> 0x18) & 0x0f)],
_hex[((dataCount >> 0x14) & 0x0f)],
_hex[((dataCount >> 0x10) & 0x0f)],
_hex[((dataCount >> 0x0c) & 0x0f)],
_hex[((dataCount >> 0x08) & 0x0f)],
_hex[((dataCount >> 0x04) & 0x0f)],
_hex[((dataCount >> 0x00) & 0x0f)],
(byte)'\r',
(byte)'\n',
};
tenByteBuffer[0] = _hex[((dataCount >> 0x1c) & 0x0f)];
tenByteBuffer[1] = _hex[((dataCount >> 0x18) & 0x0f)];
tenByteBuffer[2] = _hex[((dataCount >> 0x14) & 0x0f)];
tenByteBuffer[3] = _hex[((dataCount >> 0x10) & 0x0f)];
tenByteBuffer[4] = _hex[((dataCount >> 0x0c) & 0x0f)];
tenByteBuffer[5] = _hex[((dataCount >> 0x08) & 0x0f)];
tenByteBuffer[6] = _hex[((dataCount >> 0x04) & 0x0f)];
tenByteBuffer[7] = _hex[((dataCount >> 0x00) & 0x0f)];
tenByteBuffer[8] = (byte)'\r';
tenByteBuffer[9] = (byte)'\n';

// Determine the most-significant non-zero nibble
int total, shift;
Expand All @@ -510,7 +512,7 @@ public static ArraySegment<byte> BeginChunkBytes(int dataCount)
total |= (dataCount > 0x000f) ? 0x04 : 0x00;

var offset = 7 - (total >> 2);
return new ArraySegment<byte>(bytes, offset, 10 - offset);
return new ArraySegment<byte>(tenByteBuffer, offset, 10 - offset);
}

private void WriteChunkedResponseSuffix()
Expand All @@ -533,7 +535,7 @@ public void ProduceContinue()
RequestHeaders.TryGetValue("Expect", out expect) &&
(expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
{
SocketOutput.Write(_continueBytes);
SocketOutput.Write(_continueBytes, immediate: true);
}
}

Expand Down Expand Up @@ -613,7 +615,7 @@ protected Task ProduceEnd()

private async Task ProduceEndAwaited()
{
await ProduceStart(immediate: true, appCompleted: true);
await ProduceStart(immediate: !SocketInput.IsCompleted, appCompleted: true);

WriteSuffix();
}
Expand All @@ -640,14 +642,13 @@ private Task CreateResponseHeader(
{
var begin = SocketOutput.ProducingStart();
var end = begin;
if (_keepAlive)
if (_keepAlive && _responseHeaders.HasConnection)
{
foreach (var connectionValue in _responseHeaders.HeaderConnection)
var connection = _responseHeaders.HeaderConnection.ToString();

if (connection.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1)
{
if (connectionValue.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1)
{
_keepAlive = false;
}
_keepAlive = false;
}
}

Expand Down Expand Up @@ -711,7 +712,7 @@ protected bool TakeStartLine(SocketInput input)
try
{
var begin = scan;
if (scan.Seek(_vectorSpaces) == -1)
if (scan.Seek(ref _vectorSpaces) == -1)
{
return false;
}
Expand All @@ -726,11 +727,11 @@ protected bool TakeStartLine(SocketInput input)
begin = scan;

var needDecode = false;
var chFound = scan.Seek(_vectorSpaces, _vectorQuestionMarks, _vectorPercentages);
var chFound = scan.Seek(ref _vectorSpaces, ref _vectorQuestionMarks, ref _vectorPercentages);
if (chFound == '%')
{
needDecode = true;
chFound = scan.Seek(_vectorSpaces, _vectorQuestionMarks);
chFound = scan.Seek(ref _vectorSpaces, ref _vectorQuestionMarks);
}

var pathBegin = begin;
Expand All @@ -740,7 +741,7 @@ protected bool TakeStartLine(SocketInput input)
if (chFound == '?')
{
begin = scan;
if (scan.Seek(_vectorSpaces) != ' ')
if (scan.Seek(ref _vectorSpaces) != ' ')
{
return false;
}
Expand All @@ -749,7 +750,7 @@ protected bool TakeStartLine(SocketInput input)

scan.Take();
begin = scan;
if (scan.Seek(_vectorCRs) == -1)
if (scan.Seek(ref _vectorCRs) == -1)
{
return false;
}
Expand Down Expand Up @@ -834,6 +835,7 @@ private bool RequestUrlStartsWithPathBase(string requestUrl, out bool caseMatche

public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders requestHeaders)
{
MemoryPoolIterator2 endName;
var scan = input.ConsumingStart();
var consumed = scan;
try
Expand All @@ -843,8 +845,15 @@ public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders req
while (!scan.IsEnd)
{
var beginName = scan;
scan.Seek(_vectorColons, _vectorCRs);
var endName = scan;
if (scan.Peek() == '\r' || scan.SeekCommonHeader())
{
endName = scan;
}
else
{
scan.Seek(ref _vectorColons, ref _vectorCRs);
endName = scan;
}

chFirst = scan.Take();
var beginValue = scan;
Expand Down Expand Up @@ -894,7 +903,7 @@ public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders req
var wrapping = false;
while (!scan.IsEnd)
{
if (scan.Seek(_vectorCRs) == -1)
if (scan.Seek(ref _vectorCRs) == -1)
{
// no "\r" in sight, burn used bytes and go back to await more data
return false;
Expand Down Expand Up @@ -922,7 +931,8 @@ public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders req
continue;
}

var name = beginName.GetArraySegment(endName);
byte[] rentedBuffer;
var name = beginName.GetArraySegment(endName, out rentedBuffer);
var value = beginValue.GetAsciiString(endValue);
if (wrapping)
{
Expand All @@ -931,6 +941,10 @@ public static bool TakeMessageHeaders(SocketInput input, FrameRequestHeaders req

consumed = scan;
requestHeaders.Append(name.Array, name.Offset, name.Count, value);
if (rentedBuffer != null)
{
ArrayPool<byte>.Shared.Return(rentedBuffer);
}
break;
}
}
Expand Down
Loading