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

Commit 371b2ad

Browse files
committed
Precompute Http Version bytes
1 parent f074943 commit 371b2ad

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public partial class Frame : FrameContext, IFrameControl
3232
private static readonly byte[] _bytesConnectionClose = Encoding.ASCII.GetBytes("Connection: close\r\n\r\n");
3333
private static readonly byte[] _bytesConnectionKeepAlive = Encoding.ASCII.GetBytes("Connection: keep-alive\r\n\r\n");
3434
private static readonly byte[] _bytesTransferEncodingChunked = Encoding.ASCII.GetBytes("Transfer-Encoding: chunked\r\n");
35+
private static readonly byte[] _bytesHttpVersion1_0 = Encoding.ASCII.GetBytes("HTTP/1.0 ");
36+
private static readonly byte[] _bytesHttpVersion1_1 = Encoding.ASCII.GetBytes("HTTP/1.1 ");
3537
private static readonly byte[] _bytesContentLengthZero = Encoding.ASCII.GetBytes("Content-Length: 0\r\n");
3638
private static readonly byte[] _bytesSpace = Encoding.ASCII.GetBytes(" ");
3739

@@ -53,6 +55,8 @@ public partial class Frame : FrameContext, IFrameControl
5355
private bool _keepAlive;
5456
private bool _autoChunk;
5557
private Exception _applicationException;
58+
59+
private HttpVersionType _httpVersion;
5660

5761
private readonly IPEndPoint _localEndPoint;
5862
private readonly IPEndPoint _remoteEndPoint;
@@ -78,7 +82,36 @@ public Frame(ConnectionContext context,
7882
public string RequestUri { get; set; }
7983
public string Path { get; set; }
8084
public string QueryString { get; set; }
81-
public string HttpVersion { get; set; }
85+
public string HttpVersion
86+
{
87+
get
88+
{
89+
if (_httpVersion == HttpVersionType.Http1_1)
90+
{
91+
return "HTTP/1.1";
92+
}
93+
if (_httpVersion == HttpVersionType.Http1_0)
94+
{
95+
return "HTTP/1.0";
96+
}
97+
return "";
98+
}
99+
set
100+
{
101+
if (value == "HTTP/1.1")
102+
{
103+
_httpVersion = HttpVersionType.Http1_1;
104+
}
105+
else if (value == "HTTP/1.0")
106+
{
107+
_httpVersion = HttpVersionType.Http1_0;
108+
}
109+
else
110+
{
111+
_httpVersion = HttpVersionType.Unknown;
112+
}
113+
}
114+
}
82115
public IHeaderDictionary RequestHeaders { get; set; }
83116
public MessageBody MessageBody { get; set; }
84117
public Stream RequestBody { get; set; }
@@ -113,7 +146,7 @@ public void Reset()
113146
RequestUri = null;
114147
Path = null;
115148
QueryString = null;
116-
HttpVersion = null;
149+
_httpVersion = HttpVersionType.Unknown;
117150
RequestHeaders = _requestHeaders;
118151
MessageBody = null;
119152
RequestBody = null;
@@ -454,7 +487,7 @@ public void ProduceContinue()
454487
if (_responseStarted) return;
455488

456489
StringValues expect;
457-
if (HttpVersion.Equals("HTTP/1.1") &&
490+
if (_httpVersion == HttpVersionType.Http1_1 &&
458491
RequestHeaders.TryGetValue("Expect", out expect) &&
459492
(expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
460493
{
@@ -575,8 +608,8 @@ private Task CreateResponseHeader(
575608
{
576609
var blockRemaining = memoryBlock.Data.Count;
577610

578-
OutputAsciiBlock(HttpVersion, memoryBlock, SocketOutput);
579-
OutputAsciiBlock(_bytesSpace, memoryBlock, SocketOutput);
611+
OutputAsciiBlock(_httpVersion == HttpVersionType.Http1_1 ? _bytesHttpVersion1_1 : _bytesHttpVersion1_0, memoryBlock, SocketOutput);
612+
580613
OutputAsciiBlock(statusBytes, memoryBlock, SocketOutput);
581614

582615
foreach (var header in _responseHeaders.AsOutputEnumerable())
@@ -610,7 +643,7 @@ private Task CreateResponseHeader(
610643
}
611644
else
612645
{
613-
if (HttpVersion == "HTTP/1.1")
646+
if (_httpVersion == HttpVersionType.Http1_1)
614647
{
615648
_autoChunk = true;
616649
OutputAsciiBlock(_bytesTransferEncodingChunked, memoryBlock, SocketOutput);
@@ -622,11 +655,11 @@ private Task CreateResponseHeader(
622655
}
623656
}
624657

625-
if (_keepAlive == false && _responseHeaders.HasConnection == false && HttpVersion == "HTTP/1.1")
658+
if (_keepAlive == false && _responseHeaders.HasConnection == false && _httpVersion == HttpVersionType.Http1_1)
626659
{
627660
OutputAsciiBlock(_bytesConnectionClose, memoryBlock, SocketOutput);
628661
}
629-
else if (_keepAlive && _responseHeaders.HasConnection == false && HttpVersion == "HTTP/1.0")
662+
else if (_keepAlive && _responseHeaders.HasConnection == false && _httpVersion == HttpVersionType.Http1_0)
630663
{
631664
OutputAsciiBlock(_bytesConnectionKeepAlive, memoryBlock, SocketOutput);
632665
}
@@ -849,5 +882,12 @@ private void ReportApplicationError(Exception ex)
849882
_applicationException = ex;
850883
Log.ApplicationError(ex);
851884
}
885+
886+
private enum HttpVersionType
887+
{
888+
Unknown = -1,
889+
Http1_0 = 0,
890+
Http1_1 = 1
891+
}
852892
}
853893
}

src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
1212
{
1313
public abstract class FrameHeaders : IHeaderDictionary
1414
{
15+
protected Dictionary<string, StringValues> MaybeUnknown;
16+
17+
protected Dictionary<string, StringValues> Unknown => MaybeUnknown ?? (MaybeUnknown = new Dictionary<string, StringValues>(StringComparer.OrdinalIgnoreCase));
18+
1519
public bool HasConnection { get; protected set; }
1620

1721
public bool HasTransferEncoding { get; protected set; }
1822

1923
public bool HasContentLength { get; protected set; }
2024

21-
protected Dictionary<string, StringValues> MaybeUnknown;
22-
23-
protected Dictionary<string, StringValues> Unknown => MaybeUnknown ?? (MaybeUnknown = new Dictionary<string, StringValues>(StringComparer.OrdinalIgnoreCase));
24-
2525
StringValues IHeaderDictionary.this[string key]
2626
{
2727
get

0 commit comments

Comments
 (0)