Expand feature support for OWIN->K.

This commit is contained in:
Chris Ross 2014-06-19 13:42:01 -07:00
parent df730a47a9
commit f5173e44ae
5 changed files with 125 additions and 39 deletions

View File

@ -25,6 +25,7 @@
<Compile Include="OwinEnvironment.cs" />
<Compile Include="OwinExtensions.cs" />
<Compile Include="OwinFeatureCollection.cs" />
<Compile Include="Utilities.cs" />
</ItemGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
</Project>

View File

@ -37,8 +37,8 @@ namespace Microsoft.AspNet.Owin
{ 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 => RemoveQuestionMark(feature.QueryString),
(feature, value) => feature.QueryString = AddQuestionMark(Convert.ToString(value))) },
{ OwinConstants.RequestQueryString, new FeatureMap<IHttpRequestFeature>(feature => Utilities.RemoveQuestionMark(feature.QueryString),
(feature, value) => feature.QueryString = Utilities.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) },
@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Owin
{ 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)) },
{ OwinConstants.Security.User, new FeatureMap<IHttpAuthenticationFeature>(feature => feature.User, (feature, value) => feature.User = Utilities.MakeClaimsPrincipal((IPrincipal)value)) },
};
if (context.Request.IsSecure)
@ -230,36 +230,6 @@ 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

@ -8,10 +8,13 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
using Microsoft.AspNet.FeatureModel;
namespace Microsoft.AspNet.Owin
@ -25,6 +28,8 @@ namespace Microsoft.AspNet.Owin
IHttpConnectionFeature,
IHttpSendFileFeature,
IHttpClientCertificateFeature,
IHttpRequestLifetimeFeature,
IHttpAuthenticationFeature,
IOwinEnvironmentFeature
{
public IDictionary<string, object> Environment { get; set; }
@ -81,8 +86,8 @@ namespace Microsoft.AspNet.Owin
string IHttpRequestFeature.QueryString
{
get { return Prop<string>(OwinConstants.RequestQueryString); }
set { Prop(OwinConstants.RequestQueryString, value); }
get { return Utilities.AddQuestionMark(Prop<string>(OwinConstants.RequestQueryString)); }
set { Prop(OwinConstants.RequestQueryString, Utilities.RemoveQuestionMark(value)); }
}
IDictionary<string, string[]> IHttpRequestFeature.Headers
@ -203,11 +208,38 @@ namespace Microsoft.AspNet.Owin
set { Prop(OwinConstants.CommonKeys.ClientCertificate, value); }
}
Task<X509Certificate> IHttpClientCertificateFeature.GetClientCertificateAsync(CancellationToken cancellationToken)
async Task<X509Certificate> IHttpClientCertificateFeature.GetClientCertificateAsync(CancellationToken cancellationToken)
{
var loadAsync = Prop<Func<Task>>(OwinConstants.CommonKeys.LoadClientCertAsync);
if (loadAsync != null)
{
await loadAsync();
}
return Prop<X509Certificate>(OwinConstants.CommonKeys.ClientCertificate);
}
CancellationToken IHttpRequestLifetimeFeature.OnRequestAborted
{
get { return Prop<CancellationToken>(OwinConstants.CallCancelled); }
}
void IHttpRequestLifetimeFeature.Abort()
{
throw new NotImplementedException();
}
ClaimsPrincipal IHttpAuthenticationFeature.User
{
get { return Utilities.MakeClaimsPrincipal(Prop<IPrincipal>(OwinConstants.Security.User)); }
set { Prop(OwinConstants.Security.User, value); }
}
IAuthenticationHandler IHttpAuthenticationFeature.Handler
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public int Revision
{
get { return 0; } // Not modifiable
@ -249,6 +281,8 @@ namespace Microsoft.AspNet.Owin
typeof(IHttpResponseFeature),
typeof(IHttpConnectionFeature),
typeof(IOwinEnvironmentFeature),
typeof(IHttpRequestLifetimeFeature),
typeof(IHttpAuthenticationFeature),
};
if (SupportsSendFile)
{

View File

@ -0,0 +1,45 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Security.Claims;
using System.Security.Principal;
namespace Microsoft.AspNet.Owin
{
internal static class Utilities
{
internal static string RemoveQuestionMark(string queryString)
{
if (!string.IsNullOrEmpty(queryString))
{
if (queryString[0] == '?')
{
return queryString.Substring(1);
}
}
return queryString;
}
internal static string AddQuestionMark(string queryString)
{
if (!string.IsNullOrEmpty(queryString))
{
return '?' + queryString;
}
return queryString;
}
internal static ClaimsPrincipal MakeClaimsPrincipal(IPrincipal principal)
{
if (principal == null)
{
return null;
}
if (principal is ClaimsPrincipal)
{
return principal as ClaimsPrincipal;
}
return new ClaimsPrincipal(principal);
}
}
}

View File

@ -16,17 +16,53 @@ namespace Microsoft.AspNet.Owin
object value;
return features.TryGetValue(typeof(T), out value) ? (T)value : default(T);
}
private T Get<T>(IDictionary<string, object> env, string key)
{
object value;
return env.TryGetValue(key, out value) ? (T)value : default(T);
}
[Fact]
public void OwinHttpEnvironmentCanBeCreated()
{
var env = new Dictionary<string, object>
{
{"owin.RequestMethod", "POST"}
{ "owin.RequestMethod", "POST" },
{ "owin.RequestPath", "/path" },
{ "owin.RequestPathBase", "/pathBase" },
{ "owin.RequestQueryString", "name=value" },
};
var features = new FeatureObject(new OwinFeatureCollection(env));
Assert.Equal(Get<IHttpRequestFeature>(features).Method, "POST");
var requestFeature = Get<IHttpRequestFeature>(features);
Assert.Equal(requestFeature.Method, "POST");
Assert.Equal(requestFeature.Path, "/path");
Assert.Equal(requestFeature.PathBase, "/pathBase");
Assert.Equal(requestFeature.QueryString, "?name=value");
}
[Fact]
public void OwinHttpEnvironmentCanBeModified()
{
var env = new Dictionary<string, object>
{
{ "owin.RequestMethod", "POST" },
{ "owin.RequestPath", "/path" },
{ "owin.RequestPathBase", "/pathBase" },
{ "owin.RequestQueryString", "name=value" },
};
var features = new FeatureObject(new OwinFeatureCollection(env));
var requestFeature = Get<IHttpRequestFeature>(features);
requestFeature.Method = "GET";
requestFeature.Path = "/path2";
requestFeature.PathBase = "/pathBase2";
requestFeature.QueryString = "?name=value2";
Assert.Equal("GET", Get<string>(env, "owin.RequestMethod"));
Assert.Equal("/path2", Get<string>(env, "owin.RequestPath"));
Assert.Equal("/pathBase2", Get<string>(env, "owin.RequestPathBase"));
Assert.Equal("name=value2", Get<string>(env, "owin.RequestQueryString"));
}
[Fact]