Remove CallCancelled property. Fix Owin query string. Add Owin user. Add Owin tests.

This commit is contained in:
Chris Ross 2014-06-18 15:50:14 -07:00
parent cd906e306e
commit 2ae3a24a16
4 changed files with 155 additions and 219 deletions

View File

@ -120,12 +120,5 @@ namespace Microsoft.AspNet.Http
/// </summary>
/// <returns>The owin.RequestBody Stream.</returns>
public abstract Stream Body { get; set; }
/// <summary>
/// Gets or sets the cancellation token for the request.
/// </summary>
/// <returns>The cancellation token for the request.</returns>
public abstract CancellationToken CallCanceled { get; set; }
}
}

View File

@ -8,11 +8,14 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
namespace Microsoft.AspNet.Owin
{
@ -28,12 +31,14 @@ namespace Microsoft.AspNet.Owin
_context = context;
_entries = new Dictionary<string, FeatureMap>()
{
{ OwinConstants.CallCancelled, new FeatureMap<IHttpRequestLifetimeFeature>(feature => feature.OnRequestAborted) },
{ OwinConstants.RequestProtocol, new FeatureMap<IHttpRequestFeature>(feature => feature.Protocol, (feature, value) => feature.Protocol = Convert.ToString(value)) },
{ OwinConstants.RequestScheme, new FeatureMap<IHttpRequestFeature>(feature => feature.Scheme, (feature, value) => feature.Scheme = Convert.ToString(value)) },
{ OwinConstants.RequestMethod, new FeatureMap<IHttpRequestFeature>(feature => feature.Method, (feature, value) => feature.Method = Convert.ToString(value)) },
{ OwinConstants.RequestPathBase, new FeatureMap<IHttpRequestFeature>(feature => feature.PathBase, (feature, value) => feature.PathBase = Convert.ToString(value)) },
{ OwinConstants.RequestPath, new FeatureMap<IHttpRequestFeature>(feature => feature.Path, (feature, value) => feature.Path = Convert.ToString(value)) },
{ OwinConstants.RequestQueryString, new FeatureMap<IHttpRequestFeature>(feature => feature.QueryString, (feature, value) => feature.QueryString = Convert.ToString(value)) },
{ OwinConstants.RequestQueryString, new FeatureMap<IHttpRequestFeature>(feature => RemoveQuestionMark(feature.QueryString),
(feature, value) => feature.QueryString = AddQuestionMark(Convert.ToString(value))) },
{ OwinConstants.RequestHeaders, new FeatureMap<IHttpRequestFeature>(feature => feature.Headers, (feature, value) => feature.Headers = (IDictionary<string, string[]>)value) },
{ OwinConstants.RequestBody, new FeatureMap<IHttpRequestFeature>(feature => feature.Body, (feature, value) => feature.Body = (Stream)value) },
@ -56,6 +61,8 @@ namespace Microsoft.AspNet.Owin
{ OwinConstants.CommonKeys.IsLocal, new FeatureMap<IHttpConnectionFeature>(feature => feature.IsLocal, (feature, value) => feature.IsLocal = Convert.ToBoolean(value)) },
{ OwinConstants.SendFiles.SendAsync, new FeatureMap<IHttpSendFileFeature>(feature => new SendFileFunc(feature.SendFileAsync)) },
{ OwinConstants.Security.User, new FeatureMap<IHttpAuthenticationFeature>(feature => feature.User, (feature, value) => feature.User = MakeClaimsPrincipal((IPrincipal)value)) },
};
if (context.Request.IsSecure)
@ -222,6 +229,36 @@ namespace Microsoft.AspNet.Owin
throw new NotImplementedException();
}
private string RemoveQuestionMark(string queryString)
{
if (!string.IsNullOrEmpty(queryString))
{
if (queryString[0] == '?')
{
return queryString.Substring(1);
}
}
return queryString;
}
private string AddQuestionMark(string queryString)
{
if (!string.IsNullOrEmpty(queryString))
{
return '?' + queryString;
}
return queryString;
}
private ClaimsPrincipal MakeClaimsPrincipal(IPrincipal principal)
{
if (principal is ClaimsPrincipal)
{
return principal as ClaimsPrincipal;
}
return new ClaimsPrincipal(principal);
}
public class FeatureMap
{
public FeatureMap(Type featureInterface, Func<object, object> getter)

View File

@ -149,18 +149,5 @@ namespace Microsoft.AspNet.PipelineCore
{
get { return RequestCookiesFeature.Cookies; }
}
public override System.Threading.CancellationToken CallCanceled
{
get
{
// TODO: Which feature exposes this?
return CancellationToken.None;
}
set
{
throw new NotImplementedException();
}
}
}
}

View File

@ -4,13 +4,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.WebSockets;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Security;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
using Microsoft.AspNet.PipelineCore;
using Xunit;
namespace Microsoft.AspNet.Owin
@ -26,230 +27,148 @@ namespace Microsoft.AspNet.Owin
[Fact]
public void OwinEnvironmentCanBeCreated()
{
MoqHttpContext context = new MoqHttpContext();
HttpContext context = CreateContext();
context.Request.Method = "SomeMethod";
context.User = new ClaimsPrincipal(new ClaimsIdentity("Foo"));
context.Request.Body = Stream.Null;
context.Request.Headers["CustomRequestHeader"] = "CustomRequestValue";
context.Request.Path = new PathString("/path");
context.Request.PathBase = new PathString("/pathBase");
context.Request.Protocol = "http/1.0";
context.Request.QueryString = new QueryString("?key=value");
context.Request.Scheme = "http";
context.Response.Body = Stream.Null;
context.Response.Headers["CustomResponseHeader"] = "CustomResponseValue";
context.Response.StatusCode = 201;
IDictionary<string, object> env = new OwinEnvironment(context);
Assert.Equal("SomeMethod", Get<string>(env, "owin.RequestMethod"));
Assert.Equal("Foo", Get<ClaimsPrincipal>(env, "server.User").Identity.AuthenticationType);
Assert.Same(Stream.Null, Get<Stream>(env, "owin.RequestBody"));
var requestHeaders = Get<IDictionary<string, string[]>>(env, "owin.RequestHeaders");
Assert.NotNull(requestHeaders);
Assert.Equal("CustomRequestValue", requestHeaders["CustomRequestHeader"].First());
Assert.Equal("/path", Get<string>(env, "owin.RequestPath"));
Assert.Equal("/pathBase", Get<string>(env, "owin.RequestPathBase"));
Assert.Equal("http/1.0", Get<string>(env, "owin.RequestProtocol"));
Assert.Equal("key=value", Get<string>(env, "owin.RequestQueryString"));
Assert.Equal("http", Get<string>(env, "owin.RequestScheme"));
Assert.Same(Stream.Null, Get<Stream>(env, "owin.ResponseBody"));
var responseHeaders = Get<IDictionary<string, string[]>>(env, "owin.ResponseHeaders");
Assert.NotNull(responseHeaders);
Assert.Equal("CustomResponseValue", responseHeaders["CustomResponseHeader"].First());
Assert.Equal(201, Get<int>(env, "owin.ResponseStatusCode"));
}
[Fact]
public void OwinEnvironmentCanBeModified()
{
HttpContext context = CreateContext();
IDictionary<string, object> env = new OwinEnvironment(context);
Assert.Equal("SomeMethod", Get<string>(env, "owin.RequestMethod"));
env["owin.RequestMethod"] = "SomeOtherMethod";
Assert.Equal("SomeOtherMethod", context.Request.Method);
env["owin.RequestMethod"] = "SomeMethod";
env["server.User"] = new ClaimsPrincipal(new ClaimsIdentity("Foo"));
env["owin.RequestBody"] = Stream.Null;
var requestHeaders = Get<IDictionary<string, string[]>>(env, "owin.RequestHeaders");
Assert.NotNull(requestHeaders);
requestHeaders["CustomRequestHeader"] = new[] { "CustomRequestValue" };
env["owin.RequestPath"] = "/path";
env["owin.RequestPathBase"] = "/pathBase";
env["owin.RequestProtocol"] = "http/1.0";
env["owin.RequestQueryString"] = "key=value";
env["owin.RequestScheme"] = "http";
env["owin.ResponseBody"] = Stream.Null;
var responseHeaders = Get<IDictionary<string, string[]>>(env, "owin.ResponseHeaders");
Assert.NotNull(responseHeaders);
responseHeaders["CustomResponseHeader"] = new[] { "CustomResponseValue" };
env["owin.ResponseStatusCode"] = 201;
Assert.Equal("SomeMethod", context.Request.Method);
Assert.Equal("Foo", context.User.Identity.AuthenticationType);
Assert.Same(Stream.Null, context.Request.Body);
Assert.Equal("CustomRequestValue", context.Request.Headers["CustomRequestHeader"]);
Assert.Equal("/path", context.Request.Path.Value);
Assert.Equal("/pathBase", context.Request.PathBase.Value);
Assert.Equal("http/1.0", context.Request.Protocol);
Assert.Equal("?key=value", context.Request.QueryString.Value);
Assert.Equal("http", context.Request.Scheme);
Assert.Same(Stream.Null, context.Response.Body);
Assert.Equal("CustomResponseValue", context.Response.Headers["CustomResponseHeader"]);
Assert.Equal(201, context.Response.StatusCode);
}
private class MoqHttpContext : HttpContext
private HttpContext CreateContext()
{
private HttpRequest _request;
private IDictionary<object, object> _items;
var features = new FeatureCollection();
features.Add(typeof(IHttpRequestFeature), new MoqHttpRequestFeature());
features.Add(typeof(IHttpResponseFeature), new MoqHttpResponseFeature());
features.Add(typeof(IHttpAuthenticationFeature), new MoqHttpAuthenticationFeature());
features.Add(typeof(IHttpRequestLifetimeFeature), new MoqHttpRequestLifetimeFeature());
return new DefaultHttpContext(features);
}
public MoqHttpContext()
private class MoqHttpRequestFeature : IHttpRequestFeature
{
public MoqHttpRequestFeature()
{
_request = new MoqHttpRequest();
_items = new Dictionary<object, object>();
Headers = new Dictionary<string, string[]>();
}
public override HttpRequest Request
public string Method { get; set; }
public string Scheme { get; set; }
public string Protocol { get; set; }
public Stream Body { get; set; }
public string PathBase { get; set; }
public string Path { get; set; }
public string QueryString { get; set; }
public IDictionary<string, string[]> Headers { get; set; }
}
private class MoqHttpResponseFeature : IHttpResponseFeature
{
public MoqHttpResponseFeature()
{
get { return _request; }
Headers = new Dictionary<string, string[]>();
}
public override HttpResponse Response
{
get { throw new NotImplementedException(); }
}
public Stream Body { get; set; }
public override ClaimsPrincipal User
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public int StatusCode { get; set; }
public override IDictionary<object, object> Items
{
get { return _items; }
}
public string ReasonPhrase { get; set; }
public override IServiceProvider ApplicationServices
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public IDictionary<string, string[]> Headers { get; set; }
public override IServiceProvider RequestServices
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override void Dispose()
{
throw new NotImplementedException();
}
public override object GetFeature(Type type)
{
return Request;
}
public override void SetFeature(Type type, object instance)
{
throw new NotImplementedException();
}
public override IEnumerable<AuthenticationDescription> GetAuthenticationTypes()
{
throw new NotImplementedException();
}
public override IEnumerable<AuthenticationResult> Authenticate(IList<string> authenticationTypes)
{
throw new NotImplementedException();
}
public override Task<IEnumerable<AuthenticationResult>> AuthenticateAsync(IList<string> authenticationTypes)
{
throw new NotImplementedException();
}
public override CancellationToken OnRequestAborted
{
get { throw new NotImplementedException(); }
}
public override bool IsWebSocketRequest
{
get { throw new NotImplementedException(); }
}
public override IList<string> WebSocketRequestedProtocols
{
get { throw new NotImplementedException(); }
}
public override void Abort()
{
throw new NotImplementedException();
}
public override Task<WebSocket> AcceptWebSocketAsync(string subProtocol)
public void OnSendingHeaders(Action<object> callback, object state)
{
throw new NotImplementedException();
}
}
private class MoqHttpRequest : HttpRequest, IHttpRequestFeature
private class MoqHttpAuthenticationFeature : IHttpAuthenticationFeature
{
public override HttpContext HttpContext
{
get { throw new NotImplementedException(); }
}
public ClaimsPrincipal User { get; set; }
public override string Method
{
get;
set;
}
public IAuthenticationHandler Handler { get; set; }
}
public override string Scheme
{
get;
set;
}
private class MoqHttpRequestLifetimeFeature : IHttpRequestLifetimeFeature
{
public CancellationToken OnRequestAborted { get; private set; }
public override bool IsSecure
{
get { return false; }
}
public override HostString Host
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override PathString PathBase
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override PathString Path
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override QueryString QueryString
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override IReadableStringCollection Query
{
get { throw new NotImplementedException(); }
}
public override Task<IReadableStringCollection> GetFormAsync()
public void Abort()
{
throw new NotImplementedException();
}
public override string Protocol
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override IHeaderDictionary Headers
{
get { throw new NotImplementedException(); }
}
public override IReadableStringCollection Cookies
{
get { throw new NotImplementedException(); }
}
public override long? ContentLength
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override Stream Body
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override CancellationToken CallCanceled
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
string IHttpRequestFeature.PathBase
{
get;
set;
}
string IHttpRequestFeature.Path
{
get;
set;
}
string IHttpRequestFeature.QueryString
{
get;
set;
}
IDictionary<string, string[]> IHttpRequestFeature.Headers
{
get;
set;
}
}
}
}