Skip to content
This repository was archived by the owner on Mar 19, 2019. It is now read-only.

Commit 119945c

Browse files
committed
Cache the ContentLength header value
1 parent 56bd85a commit 119945c

File tree

5 files changed

+57
-250
lines changed

5 files changed

+57
-250
lines changed

src/Microsoft.AspNetCore.Server.HttpSys/FeatureContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ internal FeatureContext(RequestContext requestContext, bool enableResponseCachin
7272
_enableResponseCaching = enableResponseCaching;
7373

7474
// Pre-initialize any fields that are not lazy at the lower level.
75-
_requestHeaders = new HeaderDictionary(Request.Headers);
75+
_requestHeaders = Request.Headers;
7676
_httpMethod = Request.Method;
7777
_path = Request.Path;
7878
_pathBase = Request.PathBase;
@@ -82,7 +82,7 @@ internal FeatureContext(RequestContext requestContext, bool enableResponseCachin
8282
_user = _requestContext.User;
8383

8484
_responseStream = new ResponseStream(requestContext.Response.Body, OnStart);
85-
_responseHeaders = new HeaderDictionary(Response.Headers);
85+
_responseHeaders = Response.Headers;
8686
}
8787

8888
internal IFeatureCollection Features => _features;

src/Microsoft.AspNetCore.Server.HttpSys/HeaderDictionary.cs

Lines changed: 0 additions & 204 deletions
This file was deleted.

src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/HeaderCollection.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
using System;
55
using System.Collections;
66
using System.Collections.Generic;
7+
using Microsoft.AspNetCore.Http;
78
using Microsoft.Extensions.Primitives;
9+
using Microsoft.Net.Http.Headers;
810

911
namespace Microsoft.AspNetCore.Server.HttpSys
1012
{
11-
internal class HeaderCollection : IDictionary<string, StringValues>
13+
internal class HeaderCollection : IHeaderDictionary
1214
{
15+
private long? _contentLength;
16+
private StringValues _contentLengthText;
17+
1318
public HeaderCollection()
1419
: this(new Dictionary<string, StringValues>(4, StringComparer.OrdinalIgnoreCase))
1520
{
@@ -75,6 +80,52 @@ public ICollection<StringValues> Values
7580
get { return Store.Values; }
7681
}
7782

83+
public long? ContentLength
84+
{
85+
get
86+
{
87+
long value;
88+
var rawValue = this[HttpKnownHeaderNames.ContentLength];
89+
90+
if (_contentLengthText.Equals(rawValue))
91+
{
92+
return _contentLength;
93+
}
94+
95+
if (rawValue.Count == 1 &&
96+
!string.IsNullOrWhiteSpace(rawValue[0]) &&
97+
HeaderUtilities.TryParseInt64(new StringSegment(rawValue[0]).Trim(), out value))
98+
{
99+
_contentLengthText = rawValue;
100+
_contentLength = value;
101+
return value;
102+
}
103+
104+
return null;
105+
}
106+
set
107+
{
108+
ThrowIfReadOnly();
109+
110+
if (value.HasValue)
111+
{
112+
if (value.Value < 0)
113+
{
114+
throw new ArgumentOutOfRangeException("value", value.Value, "Cannot be negative.");
115+
}
116+
_contentLengthText = HeaderUtilities.FormatInt64(value.Value);
117+
this[HttpKnownHeaderNames.ContentLength] = _contentLengthText;
118+
_contentLength = value;
119+
}
120+
else
121+
{
122+
Remove(HttpKnownHeaderNames.ContentLength);
123+
_contentLengthText = StringValues.Empty;
124+
_contentLength = null;
125+
}
126+
}
127+
}
128+
78129
public void Add(KeyValuePair<string, StringValues> item)
79130
{
80131
ThrowIfReadOnly();

src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/Response.cs

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -147,48 +147,8 @@ internal long ExpectedBodyLength
147147
// Header accessors
148148
public long? ContentLength
149149
{
150-
get
151-
{
152-
string contentLengthString = Headers[HttpKnownHeaderNames.ContentLength];
153-
long contentLength;
154-
if (!string.IsNullOrWhiteSpace(contentLengthString))
155-
{
156-
contentLengthString = contentLengthString.Trim();
157-
if (string.Equals(Constants.Zero, contentLengthString, StringComparison.Ordinal))
158-
{
159-
return 0;
160-
}
161-
else if (long.TryParse(contentLengthString, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out contentLength))
162-
{
163-
return contentLength;
164-
}
165-
}
166-
return null;
167-
}
168-
set
169-
{
170-
CheckResponseStarted();
171-
if (!value.HasValue)
172-
{
173-
Headers.Remove(HttpKnownHeaderNames.ContentLength);
174-
}
175-
else
176-
{
177-
if (value.Value < 0)
178-
{
179-
throw new ArgumentOutOfRangeException("value", value.Value, "Cannot be negative.");
180-
}
181-
182-
if (value.Value == 0)
183-
{
184-
Headers[HttpKnownHeaderNames.ContentLength] = Constants.Zero;
185-
}
186-
else
187-
{
188-
Headers[HttpKnownHeaderNames.ContentLength] = value.Value.ToString(CultureInfo.InvariantCulture);
189-
}
190-
}
191-
}
150+
get { return Headers.ContentLength; }
151+
set { Headers.ContentLength = value; }
192152
}
193153

194154
/// <summary>

test/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests/RequestTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public async Task Request_FieldsCanBeSet_Set()
8383
Assert.Equal("TEST", requestInfo.Method);
8484
requestInfo.Body = new MemoryStream();
8585
Assert.IsType<MemoryStream>(requestInfo.Body);
86-
var customHeaders = new HeaderDictionary(new HeaderCollection());
86+
var customHeaders = new HeaderCollection();
8787
requestInfo.Headers = customHeaders;
8888
Assert.Same(customHeaders, requestInfo.Headers);
8989
requestInfo.Scheme = "abcd";

0 commit comments

Comments
 (0)