Adding ContentLength to HttpRequest

Partially addresses #15
This commit is contained in:
Pranav K 2014-03-10 18:00:54 -07:00
parent 2dfdfafaa6
commit 9ac0a8c703
6 changed files with 122 additions and 20 deletions

View File

@ -83,6 +83,11 @@ namespace Microsoft.AspNet.Abstractions
/// <returns>The collection of Cookies for this request.</returns>
public abstract IReadableStringCollection Cookies { get; }
/// <summary>
/// Gets or sets the Content-Length header
/// </summary>
public abstract long? ContentLength { get; set; }
/// <summary>
/// Gets or sets the Content-Type header.
/// </summary>

View File

@ -1,8 +1,10 @@
using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Abstractions.Infrastructure;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.PipelineCore.Collections;
@ -58,7 +60,6 @@ namespace Microsoft.AspNet.PipelineCore
get { return _canHasCookies.Fetch(_features) ?? _canHasCookies.Update(_features, new DefaultCanHasRequestCookies(_features)); }
}
public override HttpContext HttpContext { get { return _context; } }
public override PathString PathBase
@ -79,6 +80,18 @@ namespace Microsoft.AspNet.PipelineCore
set { HttpRequestInformation.QueryString = value.Value; }
}
public override long? ContentLength
{
get
{
return ParsingHelpers.GetContentLength(Headers);
}
set
{
ParsingHelpers.SetContentLength(Headers, value);
}
}
public override Stream Body
{
get { return HttpRequestInformation.Body; }

View File

@ -51,26 +51,11 @@ namespace Microsoft.AspNet.PipelineCore
{
get
{
long value;
string rawValue = Headers.Get(Constants.Headers.ContentLength);
if (!string.IsNullOrWhiteSpace(rawValue) && long.TryParse(rawValue, out value))
{
return value;
}
return null;
return ParsingHelpers.GetContentLength(Headers);
}
set
{
if (value.HasValue)
{
HttpResponseInformation.Headers[Constants.Headers.ContentLength] =
new[] { value.Value.ToString(CultureInfo.InvariantCulture) };
}
else
{
HttpResponseInformation.Headers.Remove(Constants.Headers.ContentLength);
}
ParsingHelpers.SetContentLength(Headers, value);
}
}

View File

@ -1,8 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Abstractions.Infrastructure;
using Microsoft.AspNet.PipelineCore.Collections;
namespace Microsoft.AspNet.PipelineCore.Infrastructure
@ -804,8 +806,8 @@ namespace Microsoft.AspNet.PipelineCore.Infrastructure
var accumulator = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
ParseDelimited(queryString, AmpersandAndSemicolon, AppendItemCallback, accumulator);
return accumulator.ToDictionary(
item => item.Key,
item => item.Value.ToArray(),
item => item.Key,
item => item.Value.ToArray(),
StringComparer.OrdinalIgnoreCase);
}
@ -856,5 +858,31 @@ namespace Microsoft.AspNet.PipelineCore.Infrastructure
// var localPort = request.Get<string>(OwinConstants.CommonKeys.LocalPort);
// return string.IsNullOrWhiteSpace(localPort) ? localIpAddress : (localIpAddress + ":" + localPort);
//}
public static long? GetContentLength(IHeaderDictionary headers)
{
const NumberStyles styles = NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite;
long value;
string rawValue = headers.Get(Constants.Headers.ContentLength);
if (!string.IsNullOrWhiteSpace(rawValue) &&
long.TryParse(rawValue, styles, CultureInfo.InvariantCulture, out value))
{
return value;
}
return null;
}
public static void SetContentLength(IHeaderDictionary headers, long? value)
{
if (value.HasValue)
{
headers[Constants.Headers.ContentLength] = value.Value.ToString(CultureInfo.InvariantCulture);
}
else
{
headers.Remove(Constants.Headers.ContentLength);
}
}
}
}

View File

@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpFeature;
using Moq;
using Xunit;
using Xunit.Extensions;
namespace Microsoft.AspNet.PipelineCore.Tests
{
public class DefaultHttpRequestTests
{
[Theory]
[InlineData(0)]
[InlineData(9001)]
[InlineData(65535)]
public void GetContentLength_ReturnsParsedHeader(long value)
{
// Arrange
var request = GetRequest(value.ToString(CultureInfo.InvariantCulture));
// Act and Assert
Assert.Equal(value, request.ContentLength);
}
[Fact]
public void GetContentLength_ReturnsNullIfHeaderDoesNotExist()
{
// Arrange
var request = GetRequest(contentLength: null);
// Act and Assert
Assert.Null(request.ContentLength);
}
[Theory]
[InlineData("cant-parse-this")]
[InlineData("-1000")]
[InlineData("1000.00")]
[InlineData("100/5")]
public void GetContentLength_ReturnsNullIfHeaderCannotBeParsed(string contentLength)
{
// Arrange
var request = GetRequest(contentLength);
// Act and Assert
Assert.Null(request.ContentLength);
}
private static DefaultHttpRequest GetRequest(string contentLength = null)
{
var features = new Mock<IFeatureCollection>();
var mockRequestInfo = new Mock<IHttpRequestInformation>();
var headers = new Dictionary<string, string[]>();
if (contentLength != null)
{
headers.Add("Content-Length", new[] { contentLength });
}
mockRequestInfo.SetupGet(r => r.Headers)
.Returns(headers);
object requestInfo = mockRequestInfo.Object;
features.Setup(f => f.TryGetValue(typeof(IHttpRequestInformation), out requestInfo))
.Returns(true);
var context = new DefaultHttpContext(features.Object);
var request = new DefaultHttpRequest(context, features.Object);
return request;
}
}
}

View File

@ -16,6 +16,7 @@
"Microsoft.Owin.Testing": "2.1.0",
"Moq": "4.2.1312.1622",
"xunit": "1.9.2",
"xunit.extensions": "1.9.2",
"Microsoft.Net.Http": "2.2.13",
"System.Net.Http": ""
}