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> /// <returns>The collection of Cookies for this request.</returns>
public abstract IReadableStringCollection Cookies { get; } public abstract IReadableStringCollection Cookies { get; }
/// <summary>
/// Gets or sets the Content-Length header
/// </summary>
public abstract long? ContentLength { get; set; }
/// <summary> /// <summary>
/// Gets or sets the Content-Type header. /// Gets or sets the Content-Type header.
/// </summary> /// </summary>

View File

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

View File

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

View File

@ -1,8 +1,10 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.AspNet.Abstractions; using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Abstractions.Infrastructure;
using Microsoft.AspNet.PipelineCore.Collections; using Microsoft.AspNet.PipelineCore.Collections;
namespace Microsoft.AspNet.PipelineCore.Infrastructure namespace Microsoft.AspNet.PipelineCore.Infrastructure
@ -856,5 +858,31 @@ namespace Microsoft.AspNet.PipelineCore.Infrastructure
// var localPort = request.Get<string>(OwinConstants.CommonKeys.LocalPort); // var localPort = request.Get<string>(OwinConstants.CommonKeys.LocalPort);
// return string.IsNullOrWhiteSpace(localPort) ? localIpAddress : (localIpAddress + ":" + 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", "Microsoft.Owin.Testing": "2.1.0",
"Moq": "4.2.1312.1622", "Moq": "4.2.1312.1622",
"xunit": "1.9.2", "xunit": "1.9.2",
"xunit.extensions": "1.9.2",
"Microsoft.Net.Http": "2.2.13", "Microsoft.Net.Http": "2.2.13",
"System.Net.Http": "" "System.Net.Http": ""
} }