From 779115b1ad0e3199c6d7ca0e9ed344d6f9f00c91 Mon Sep 17 00:00:00 2001 From: Chris R Date: Tue, 17 Jan 2017 13:27:21 -0800 Subject: [PATCH] #407 Add ContentLength to IHeaderDictionary --- .../IHeaderDictionary.cs | 5 +++ .../exceptions.net45.json | 14 ++++++++ .../exceptions.netcore.json | 14 ++++++++ .../HeaderDictionary.cs | 29 +++++++++++++++ .../Internal/DefaultHttpRequest.cs | 10 ++---- .../Internal/DefaultHttpResponse.cs | 10 ++---- .../Internal/ParsingHelpers.cs | 36 ------------------- .../DictionaryStringValuesWrapper.cs | 35 ++++++++++++++++++ 8 files changed, 101 insertions(+), 52 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Http.Features/exceptions.net45.json create mode 100644 src/Microsoft.AspNetCore.Http.Features/exceptions.netcore.json diff --git a/src/Microsoft.AspNetCore.Http.Features/IHeaderDictionary.cs b/src/Microsoft.AspNetCore.Http.Features/IHeaderDictionary.cs index 674e2bda..dfde3f33 100644 --- a/src/Microsoft.AspNetCore.Http.Features/IHeaderDictionary.cs +++ b/src/Microsoft.AspNetCore.Http.Features/IHeaderDictionary.cs @@ -17,5 +17,10 @@ public interface IHeaderDictionary : IDictionary /// /// The stored value, or StringValues.Empty if the key is not present. new StringValues this[string key] { get; set; } + + /// + /// Strongly typed access to the Content-Length header. Implementations must keep this in sync with the string representation. + /// + long? ContentLength { get; set; } } } diff --git a/src/Microsoft.AspNetCore.Http.Features/exceptions.net45.json b/src/Microsoft.AspNetCore.Http.Features/exceptions.net45.json new file mode 100644 index 00000000..e312fab8 --- /dev/null +++ b/src/Microsoft.AspNetCore.Http.Features/exceptions.net45.json @@ -0,0 +1,14 @@ +[ + { + "OldTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewMemberId": "System.Nullable get_ContentLength()", + "Kind": "Addition" + }, + { + "OldTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewMemberId": "System.Void set_ContentLength(System.Nullable value)", + "Kind": "Addition" + } +] \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Http.Features/exceptions.netcore.json b/src/Microsoft.AspNetCore.Http.Features/exceptions.netcore.json new file mode 100644 index 00000000..e312fab8 --- /dev/null +++ b/src/Microsoft.AspNetCore.Http.Features/exceptions.netcore.json @@ -0,0 +1,14 @@ +[ + { + "OldTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewMemberId": "System.Nullable get_ContentLength()", + "Kind": "Addition" + }, + { + "OldTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewTypeId": "public interface Microsoft.AspNetCore.Http.IHeaderDictionary : System.Collections.Generic.IDictionary", + "NewMemberId": "System.Void set_ContentLength(System.Nullable value)", + "Kind": "Addition" + } +] \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Http/HeaderDictionary.cs b/src/Microsoft.AspNetCore.Http/HeaderDictionary.cs index 6fc02201..5e52b128 100644 --- a/src/Microsoft.AspNetCore.Http/HeaderDictionary.cs +++ b/src/Microsoft.AspNetCore.Http/HeaderDictionary.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Http { @@ -97,6 +98,34 @@ StringValues IDictionary.this[string key] set { this[key] = value; } } + public long? ContentLength + { + get + { + long value; + var rawValue = this[HeaderNames.ContentLength]; + if (rawValue.Count == 1 && + !string.IsNullOrWhiteSpace(rawValue[0]) && + HeaderUtilities.TryParseInt64(new StringSegment(rawValue[0]).Trim(), out value)) + { + return value; + } + + return null; + } + set + { + if (value.HasValue) + { + this[HeaderNames.ContentLength] = HeaderUtilities.FormatInt64(value.Value); + } + else + { + this.Remove(HeaderNames.ContentLength); + } + } + } + /// /// Gets the number of elements contained in the ;. /// diff --git a/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpRequest.cs b/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpRequest.cs index c20164ad..f216475d 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpRequest.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpRequest.cs @@ -72,14 +72,8 @@ public override QueryString QueryString public override long? ContentLength { - get - { - return ParsingHelpers.GetContentLength(Headers); - } - set - { - ParsingHelpers.SetContentLength(Headers, value); - } + get { return Headers.ContentLength; } + set { Headers.ContentLength = value; } } public override Stream Body diff --git a/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpResponse.cs b/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpResponse.cs index e4cdf241..3ca05035 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpResponse.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/DefaultHttpResponse.cs @@ -63,14 +63,8 @@ public override Stream Body public override long? ContentLength { - get - { - return ParsingHelpers.GetContentLength(Headers); - } - set - { - ParsingHelpers.SetContentLength(Headers, value); - } + get { return Headers.ContentLength; } + set { Headers.ContentLength = value; } } public override string ContentType diff --git a/src/Microsoft.AspNetCore.Http/Internal/ParsingHelpers.cs b/src/Microsoft.AspNetCore.Http/Internal/ParsingHelpers.cs index 57b1a7a9..1f4d7130 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/ParsingHelpers.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/ParsingHelpers.cs @@ -403,41 +403,5 @@ private static string DeQuote(string value) return value; } - - public static long? GetContentLength(IHeaderDictionary headers) - { - if (headers == null) - { - throw new ArgumentNullException(nameof(headers)); - } - - long value; - var rawValue = headers[HeaderNames.ContentLength]; - if (rawValue.Count == 1 && - !string.IsNullOrWhiteSpace(rawValue[0]) && - HeaderUtilities.TryParseInt64(new StringSegment(rawValue[0]).Trim(), out value)) - { - return value; - } - - return null; - } - - public static void SetContentLength(IHeaderDictionary headers, long? value) - { - if (headers == null) - { - throw new ArgumentNullException(nameof(headers)); - } - - if (value.HasValue) - { - headers[HeaderNames.ContentLength] = HeaderUtilities.FormatInt64(value.Value); - } - else - { - headers.Remove(HeaderNames.ContentLength); - } - } } } diff --git a/src/Microsoft.AspNetCore.Owin/DictionaryStringValuesWrapper.cs b/src/Microsoft.AspNetCore.Owin/DictionaryStringValuesWrapper.cs index 2517f556..d88b2b95 100644 --- a/src/Microsoft.AspNetCore.Owin/DictionaryStringValuesWrapper.cs +++ b/src/Microsoft.AspNetCore.Owin/DictionaryStringValuesWrapper.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Owin { @@ -42,6 +43,40 @@ StringValues IDictionary.this[string key] set { Inner[key] = value; } } + public long? ContentLength + { + get + { + long value; + + string[] rawValue; + if (!Inner.TryGetValue(HeaderNames.ContentLength, out rawValue)) + { + return null; + } + + if (rawValue.Length == 1 && + !string.IsNullOrWhiteSpace(rawValue[0]) && + HeaderUtilities.TryParseInt64(new StringSegment(rawValue[0]).Trim(), out value)) + { + return value; + } + + return null; + } + set + { + if (value.HasValue) + { + Inner[HeaderNames.ContentLength] = (StringValues)HeaderUtilities.FormatInt64(value.Value); + } + else + { + Inner.Remove(HeaderNames.ContentLength); + } + } + } + int ICollection>.Count => Inner.Count; bool ICollection>.IsReadOnly => Inner.IsReadOnly;