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="OwinEnvironment.cs" />
<Compile Include="OwinExtensions.cs" /> <Compile Include="OwinExtensions.cs" />
<Compile Include="OwinFeatureCollection.cs" /> <Compile Include="OwinFeatureCollection.cs" />
<Compile Include="Utilities.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" /> <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.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.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.RequestPath, new FeatureMap<IHttpRequestFeature>(feature => feature.Path, (feature, value) => feature.Path = Convert.ToString(value)) },
{ OwinConstants.RequestQueryString, new FeatureMap<IHttpRequestFeature>(feature => RemoveQuestionMark(feature.QueryString), { OwinConstants.RequestQueryString, new FeatureMap<IHttpRequestFeature>(feature => Utilities.RemoveQuestionMark(feature.QueryString),
(feature, value) => feature.QueryString = AddQuestionMark(Convert.ToString(value))) }, (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.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) }, { 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.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) if (context.Request.IsSecure)
@ -230,36 +230,6 @@ namespace Microsoft.AspNet.Owin
throw new NotImplementedException(); 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 class FeatureMap
{ {
public FeatureMap(Type featureInterface, Func<object, object> getter) public FeatureMap(Type featureInterface, Func<object, object> getter)

View File

@ -8,10 +8,13 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.HttpFeature; using Microsoft.AspNet.HttpFeature;
using Microsoft.AspNet.HttpFeature.Security;
using Microsoft.AspNet.FeatureModel; using Microsoft.AspNet.FeatureModel;
namespace Microsoft.AspNet.Owin namespace Microsoft.AspNet.Owin
@ -25,6 +28,8 @@ namespace Microsoft.AspNet.Owin
IHttpConnectionFeature, IHttpConnectionFeature,
IHttpSendFileFeature, IHttpSendFileFeature,
IHttpClientCertificateFeature, IHttpClientCertificateFeature,
IHttpRequestLifetimeFeature,
IHttpAuthenticationFeature,
IOwinEnvironmentFeature IOwinEnvironmentFeature
{ {
public IDictionary<string, object> Environment { get; set; } public IDictionary<string, object> Environment { get; set; }
@ -81,8 +86,8 @@ namespace Microsoft.AspNet.Owin
string IHttpRequestFeature.QueryString string IHttpRequestFeature.QueryString
{ {
get { return Prop<string>(OwinConstants.RequestQueryString); } get { return Utilities.AddQuestionMark(Prop<string>(OwinConstants.RequestQueryString)); }
set { Prop(OwinConstants.RequestQueryString, value); } set { Prop(OwinConstants.RequestQueryString, Utilities.RemoveQuestionMark(value)); }
} }
IDictionary<string, string[]> IHttpRequestFeature.Headers IDictionary<string, string[]> IHttpRequestFeature.Headers
@ -203,11 +208,38 @@ namespace Microsoft.AspNet.Owin
set { Prop(OwinConstants.CommonKeys.ClientCertificate, value); } 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(); 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 public int Revision
{ {
get { return 0; } // Not modifiable get { return 0; } // Not modifiable
@ -249,6 +281,8 @@ namespace Microsoft.AspNet.Owin
typeof(IHttpResponseFeature), typeof(IHttpResponseFeature),
typeof(IHttpConnectionFeature), typeof(IHttpConnectionFeature),
typeof(IOwinEnvironmentFeature), typeof(IOwinEnvironmentFeature),
typeof(IHttpRequestLifetimeFeature),
typeof(IHttpAuthenticationFeature),
}; };
if (SupportsSendFile) 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; object value;
return features.TryGetValue(typeof(T), out value) ? (T)value : default(T); 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] [Fact]
public void OwinHttpEnvironmentCanBeCreated() public void OwinHttpEnvironmentCanBeCreated()
{ {
var env = new Dictionary<string, object> 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)); 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] [Fact]