Initial non-optimized support for automatically chunking responses

This commit is contained in:
Stephen Halter 2015-07-31 12:38:35 -07:00
parent 32c4f314b6
commit 3fb33119ee
1 changed files with 61 additions and 4 deletions

View File

@ -27,6 +27,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
Mode _mode;
private bool _responseStarted;
private bool _keepAlive;
private bool _autoChunk;
private readonly FrameRequestHeaders _requestHeaders = new FrameRequestHeaders();
private readonly FrameResponseHeaders _responseHeaders = new FrameResponseHeaders();
@ -253,6 +254,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{
FireOnStarting();
}
if (_autoChunk)
{
WriteChunkPrefix(numOctets: 0);
WriteChunkSuffix();
}
}
catch (Exception ex)
{
@ -265,11 +272,53 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
}
}
public void Write(ArraySegment<byte> data, Action<Exception, object> callback, object state)
{
ProduceStart(immediate: false);
SocketOutput.Write(data, callback, state);
if (_autoChunk)
{
WriteChunkPrefix(data.Count);
}
SocketOutput.Write(data, callback, state, immediate: !_autoChunk);
if (_autoChunk)
{
WriteChunkSuffix();
}
}
private void WriteChunkPrefix(int numOctets)
{
var numOctetBytes = CreateAsciiByteArraySegment(numOctets.ToString("x") + "\r\n");
SocketOutput.Write(numOctetBytes,
(error, _) =>
{
if (error != null)
{
Trace.WriteLine("WriteChunkPrefix" + error.ToString());
}
},
null,
immediate: false);
}
private static readonly ArraySegment<byte> _endChunkBytes = CreateAsciiByteArraySegment("\r\n");
private void WriteChunkSuffix()
{
SocketOutput.Write(_endChunkBytes,
(error, _) =>
{
if (error != null)
{
Trace.WriteLine("WriteChunkSuffix" + error.ToString());
}
},
null,
immediate: true);
}
public void Upgrade(IDictionary<string, object> options, Func<object, Task> callback)
@ -421,9 +470,17 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
}
}
if (hasTransferEncoding == false && hasContentLength == false)
if (_keepAlive && !hasTransferEncoding && !hasContentLength)
{
_keepAlive = false;
if (HttpVersion == "HTTP/1.1")
{
_autoChunk = true;
writer.Write("Transfer-Encoding: chunked\r\n");
}
else
{
_keepAlive = false;
}
}
if (_keepAlive == false && hasConnection == false && HttpVersion == "HTTP/1.1")
{