Initial commit

This commit is contained in:
Louis DeJardin 2013-12-19 11:38:05 -08:00
commit bdf69b0d0c
58 changed files with 2657 additions and 0 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
bin
obj
*.suo
*.user
_ReSharper.*
*.DS_Store
*.userprefs
*.pidb
*.vspx
*.psess
packages
target
artifacts
StyleCop.Cache
node_modules
*.snk
.nuget/NuGet.exe

52
AspNetAbstractions.sln Normal file
View File

@ -0,0 +1,52 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Abstractions", "src\Microsoft.AspNet.Abstractions\Microsoft.AspNet.Abstractions.csproj", "{4E1520B1-01F4-481B-96A2-24067EAA52FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.FeatureModel", "src\Microsoft.AspNet.FeatureModel\Microsoft.AspNet.FeatureModel.csproj", "{A780873E-09F9-4E44-AE06-AF00C4E88E1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.HttpEnvironment", "src\Microsoft.AspNet.HttpEnvironment\Microsoft.AspNet.HttpEnvironment.csproj", "{46D69EC9-7096-49D8-A184-A9BB5B2419A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.HttpFeature", "src\Microsoft.AspNet.HttpFeature\Microsoft.AspNet.HttpFeature.csproj", "{42309978-0661-41D8-8654-39453265C5F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.PipelineCore", "src\Microsoft.AspNet.PipelineCore\Microsoft.AspNet.PipelineCore.csproj", "{A4D3E280-8838-4614-9B99-4874C3CBDF82}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.PipelineCore.Tests", "src\Microsoft.AspNet.PipelineCore.Tests\Microsoft.AspNet.PipelineCore.Tests.csproj", "{86942914-0334-4352-87ED-B971281C74E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4E1520B1-01F4-481B-96A2-24067EAA52FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E1520B1-01F4-481B-96A2-24067EAA52FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E1520B1-01F4-481B-96A2-24067EAA52FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E1520B1-01F4-481B-96A2-24067EAA52FA}.Release|Any CPU.Build.0 = Release|Any CPU
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A780873E-09F9-4E44-AE06-AF00C4E88E1E}.Release|Any CPU.Build.0 = Release|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46D69EC9-7096-49D8-A184-A9BB5B2419A1}.Release|Any CPU.Build.0 = Release|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42309978-0661-41D8-8654-39453265C5F9}.Release|Any CPU.Build.0 = Release|Any CPU
{A4D3E280-8838-4614-9B99-4874C3CBDF82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4D3E280-8838-4614-9B99-4874C3CBDF82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4D3E280-8838-4614-9B99-4874C3CBDF82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4D3E280-8838-4614-9B99-4874C3CBDF82}.Release|Any CPU.Build.0 = Release|Any CPU
{86942914-0334-4352-87ED-B971281C74E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86942914-0334-4352-87ED-B971281C74E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86942914-0334-4352-87ED-B971281C74E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86942914-0334-4352-87ED-B971281C74E2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

66
Sakefile.shade Normal file
View File

@ -0,0 +1,66 @@
var PROJECT='AspNetAbstractions'
var VERSION='0.1.0'
var FULL_VERSION='${VERSION}'
var AUTHORS='${PROJECT} contributors'
var BASE_DIR='${Directory.GetCurrentDirectory()}'
var TARGET_DIR='${Path.Combine(BASE_DIR, "target")}'
var BUILD_DIR='${Path.Combine(TARGET_DIR, "build")}'
var TEST_DIR='${Path.Combine(TARGET_DIR, "test")}'
default SRC='.'
default BUILD_PROJECTS='${Files.Include(SRC+"/**/*.csproj")}'
default TEST_PROJECTS='${Files.Include(SRC+"/**/*.Tests.csproj")}'
use namespace='System.Xml.Linq'
-// include range of standard general targets. run "sake targets" to display
use-standard-lifecycle
-// include sets of standard work targets. features include 'nuget,xunit,nunit'
use-standard-goals features='nuget,xunit'
-// additional work targets are defined below
#nuget-prepare target='package-prepare' description='Compile primary project'
for each='var projectFile in BUILD_PROJECTS.Except(TEST_PROJECTS)'
var outputDirName='${Path.GetFileNameWithoutExtension(projectFile)}'
var outputDir='${Path.Combine(BUILD_DIR, outputDirName)}'
copy sourceDir='${Path.GetDirectoryName(projectFile)}' include='*.nuspec' overwrite='${true}'
var doc='${XDocument.Load(projectFile)}'
var ns='http://schemas.microsoft.com/developer/msbuild/2003'
var itemGroups='${doc.Elements(XName.Get("Project", ns)).Elements(XName.Get("ItemGroup", ns))}'
var compileItems='${itemGroups.Elements(XName.Get("Compile", ns))}'
var contentItems='${itemGroups.Elements(XName.Get("Content", ns))}'
var noneItems='${itemGroups.Elements(XName.Get("None", ns))}'
var razorItems='${contentItems.Union(noneItems).Where(x=>x.Attribute("Include").Value.EndsWith(".cshtml"))}'
for each='var compileElt in compileItems.Union(razorItems)'
var linkElt='${compileElt.Elements(XName.Get("Link", ns)).SingleOrDefault()}'
var sourceFile='${compileElt.Attribute("Include").Value}'
var targetFile='${linkElt == null ? sourceFile : linkElt.Value}'
var sourceFull='${Path.Combine(Path.GetDirectoryName(projectFile), sourceFile)}'
var targetFull='${Path.Combine(outputDir, "src", targetFile)}'
directory create='${Path.GetDirectoryName(targetFull)}'
-File.Copy(sourceFull, targetFull, true);
#nuget-package target='package' description='Create NuGet packages'
for each='var file in Files.Include(BUILD_DIR + "/**/*.nuspec")'
var baseName='${Path.GetFileNameWithoutExtension(file)}'
var nugetProperties='${new Dictionary<string,string> {
{"id", baseName},
{"authors", AUTHORS},
{"title", baseName},
{"description", baseName},
{"licenseUrl", "about:blank"},
{"projectUrl", "about:blank"},
{"tags", "Katana"},
}}'
var props='${string.Join(";", nugetProperties.Select(kv=>kv.Key+"="+kv.Value).ToArray())}'
nuget-pack nuspecFile='${file}' packageVersion='${FULL_VERSION}' outputDir='${TARGET_DIR}' extra='-NoPackageAnalysis -Properties "${props}"'

12
build.cmd Normal file
View File

@ -0,0 +1,12 @@
@echo off
cd %~dp0
IF EXIST .nuget\NuGet.exe goto part2
echo Downloading latest version of NuGet.exe...
mkdir .nuget
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "((new-object net.webclient).DownloadFile('https://nuget.org/nuget.exe', '.nuget\NuGet.exe'))"
:part2
set EnableNuGetPackageRestore=true
.nuget\NuGet.exe install Sake -version 0.2 -o packages
packages\Sake.0.2\tools\Sake.exe -I build -f Sakefile.shade %*

6
build.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh
export EnableNuGetPackageRestore=true
mono --runtime=v4.0 ".nuget/NuGet.exe" install Sake -pre -o packages
mono $(find packages/Sake.*/tools/Sake.exe|sort -r|head -n1) -f Sakefile.shade -I src/build "$@"

View File

@ -0,0 +1,10 @@
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpContextBase
{
// TODO - review IOwinContext for properties
public abstract HttpRequestBase Request { get; }
public abstract HttpResponseBase Response { get; }
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.IO;
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpRequestBase
{
// TODO - review IOwinRequest for properties
public abstract HttpContextBase HttpContext { get; }
public abstract Uri Uri { get; }
public abstract PathString PathBase { get; set; }
public abstract PathString Path { get; set; }
public abstract QueryString QueryString { get; set; }
public abstract Stream Body { get; set; }
}
}

View File

@ -0,0 +1,13 @@
using System.IO;
namespace Microsoft.AspNet.Abstractions
{
public abstract class HttpResponseBase
{
// TODO - review IOwinResponse for completeness
public abstract HttpContextBase HttpContext { get; }
public abstract int StatusCode { get; set; }
public abstract Stream Body { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
namespace Microsoft.AspNet.Abstractions
{
public interface IBuilder
{
IBuilder Use(object middleware, params object[] args);
IBuilder New();
RequestDelegate Build();
object GetFeature(Type type);
void SetFeature(Type type, object feature);
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4E1520B1-01F4-481B-96A2-24067EAA52FA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.Abstractions</RootNamespace>
<AssemblyName>Microsoft.AspNet.Abstractions</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Microsoft.AspNet.Abstractions.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="IBuilder.cs" />
<Compile Include="PathString.cs" />
<Compile Include="HttpContextBase.cs" />
<Compile Include="HttpRequestBase.cs" />
<Compile Include="HttpResponseBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryString.cs" />
<Compile Include="RequestDelegate.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Microsoft.AspNet.Abstractions.nuspec" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,22 @@
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
<owners>$authors$</owners>
<licenseUrl>$licenseUrl$</licenseUrl>
<projectUrl>$projectUrl$</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<title>$title$</title>
<description>$title$</description>
<tags>$tags$</tags>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="$id$.dll" target="lib\net45" />
<file src="$id$.xml" target="lib\net45" />
<file src="$id$.pdb" target="lib\net45" />
<file src="src\**" target="src" />
</files>
</package>

View File

@ -0,0 +1,232 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Linq;
namespace Microsoft.AspNet.Abstractions
{
/// <summary>
/// Provides correct escaping for Path and PathBase values when needed to reconstruct a request or redirect URI string
/// </summary>
public struct PathString : IEquatable<PathString>
{
/// <summary>
/// Represents the empty path. This field is read-only.
/// </summary>
public static readonly PathString Empty = new PathString(String.Empty);
private readonly string _value;
/// <summary>
/// Initalize the path string with a given value. This value must be in unescaped format. Use
/// PathString.FromUriComponent(value) if you have a path value which is in an escaped format.
/// </summary>
/// <param name="value">The unescaped path to be assigned to the Value property.</param>
public PathString(string value)
{
if (!String.IsNullOrEmpty(value) && value[0] != '/')
{
throw new ArgumentException(""/*Resources.Exception_PathMustStartWithSlash*/, "value");
}
_value = value;
}
/// <summary>
/// The unescaped path value
/// </summary>
public string Value
{
get { return _value; }
}
/// <summary>
/// True if the path is not empty
/// </summary>
public bool HasValue
{
get { return !String.IsNullOrEmpty(_value); }
}
/// <summary>
/// Provides the path string escaped in a way which is correct for combining into the URI representation.
/// </summary>
/// <returns>The escaped path value</returns>
public override string ToString()
{
return ToUriComponent();
}
/// <summary>
/// Provides the path string escaped in a way which is correct for combining into the URI representation.
/// </summary>
/// <returns>The escaped path value</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "Purpose of the method is to return a string")]
public string ToUriComponent()
{
// TODO: Measure the cost of this escaping and consider optimizing.
return HasValue ? String.Join("/", _value.Split('/').Select(Uri.EscapeDataString)) : String.Empty;
}
/// <summary>
/// Returns an PathString given the path as it is escaped in the URI format. The string MUST NOT contain any
/// value that is not a path.
/// </summary>
/// <param name="uriComponent">The escaped path as it appears in the URI format.</param>
/// <returns>The resulting PathString</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", Justification = "Requirements not compatible with Uri processing")]
public static PathString FromUriComponent(string uriComponent)
{
// REVIEW: what is the exactly correct thing to do?
return new PathString(Uri.UnescapeDataString(uriComponent));
}
/// <summary>
/// Returns an PathString given the path as from a Uri object. Relative Uri objects are not supported.
/// </summary>
/// <param name="uri">The Uri object</param>
/// <returns>The resulting PathString</returns>
public static PathString FromUriComponent(Uri uri)
{
if (uri == null)
{
throw new ArgumentNullException("uri");
}
// REVIEW: what is the exactly correct thing to do?
return new PathString("/" + uri.GetComponents(UriComponents.Path, UriFormat.Unescaped));
}
public bool StartsWithSegments(PathString other)
{
string value1 = Value ?? String.Empty;
string value2 = other.Value ?? String.Empty;
if (value1.StartsWith(value2, StringComparison.OrdinalIgnoreCase))
{
return value1.Length == value2.Length || value1[value2.Length] == '/';
}
return false;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "Secondary information needed after boolean result obtained")]
public bool StartsWithSegments(PathString other, out PathString remaining)
{
string value1 = Value ?? String.Empty;
string value2 = other.Value ?? String.Empty;
if (value1.StartsWith(value2, StringComparison.OrdinalIgnoreCase))
{
if (value1.Length == value2.Length || value1[value2.Length] == '/')
{
remaining = new PathString(value1.Substring(value2.Length));
return true;
}
}
remaining = Empty;
return false;
}
/// <summary>
/// Adds two PathString instances into a combined PathString value.
/// </summary>
/// <returns>The combined PathString value</returns>
public PathString Add(PathString other)
{
return new PathString(Value + other.Value);
}
/// <summary>
/// Combines a PathString and QueryString into the joined URI formatted string value.
/// </summary>
/// <returns>The joined URI formatted string value</returns>
public string Add(QueryString other)
{
return ToUriComponent() + other.ToUriComponent();
}
/// <summary>
/// Compares this PathString value to another value. The default comparison is StringComparison.OrdinalIgnoreCase.
/// </summary>
/// <param name="other">The second PathString for comparison.</param>
/// <returns>True if both PathString values are equal</returns>
public bool Equals(PathString other)
{
return string.Equals(_value, other._value, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Compares this PathString value to another value using a specific StringComparison type
/// </summary>
/// <param name="other">The second PathString for comparison</param>
/// <param name="comparisonType">The StringComparison type to use</param>
/// <returns>True if both PathString values are equal</returns>
public bool Equals(PathString other, StringComparison comparisonType)
{
return string.Equals(_value, other._value, comparisonType);
}
/// <summary>
/// Compares this PathString value to another value. The default comparison is StringComparison.OrdinalIgnoreCase.
/// </summary>
/// <param name="obj">The second PathString for comparison.</param>
/// <returns>True if both PathString values are equal</returns>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is PathString && Equals((PathString)obj, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Returns the hash code for the PathString value. The hash code is provided by the OrdinalIgnoreCase implementation.
/// </summary>
/// <returns>The hash code</returns>
public override int GetHashCode()
{
return (_value != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(_value) : 0);
}
/// <summary>
/// Operator call through to Equals
/// </summary>
/// <param name="left">The left parameter</param>
/// <param name="right">The right parameter</param>
/// <returns>True if both PathString values are equal</returns>
public static bool operator ==(PathString left, PathString right)
{
return left.Equals(right, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Operator call through to Equals
/// </summary>
/// <param name="left">The left parameter</param>
/// <param name="right">The right parameter</param>
/// <returns>True if both PathString values are not equal</returns>
public static bool operator !=(PathString left, PathString right)
{
return !left.Equals(right, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Operator call through to Add
/// </summary>
/// <param name="left">The left parameter</param>
/// <param name="right">The right parameter</param>
/// <returns>The PathString combination of both values</returns>
public static PathString operator +(PathString left, PathString right)
{
return left.Add(right);
}
/// <summary>
/// Operator call through to Add
/// </summary>
/// <param name="left">The left parameter</param>
/// <param name="right">The right parameter</param>
/// <returns>The PathString combination of both values</returns>
public static string operator +(PathString left, QueryString right)
{
return left.Add(right);
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.Abstractions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.Abstractions")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f67dab3e-89ef-4d28-a57e-230af874bbe8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]

View File

@ -0,0 +1,142 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNet.Abstractions
{
/// <summary>
/// Provides correct handling for QueryString value when needed to reconstruct a request or redirect URI string
/// </summary>
public struct QueryString : IEquatable<QueryString>
{
/// <summary>
/// Represents the empty query string. This field is read-only.
/// </summary>
public static readonly QueryString Empty = new QueryString(String.Empty);
private readonly string _value;
/// <summary>
/// Initalize the query string with a given value. This value must be in escaped and delimited format without
/// a leading '?' character.
/// </summary>
/// <param name="value">The query string to be assigned to the Value property.</param>
public QueryString(string value)
{
_value = value;
}
/// <summary>
/// Initialize a query string with a single given parameter name and value. The value is
/// </summary>
/// <param name="name">The unencoded parameter name</param>
/// <param name="value">The unencoded parameter value</param>
public QueryString(string name, string value)
{
_value = Uri.EscapeDataString(name) + '=' + Uri.EscapeDataString(value);
}
/// <summary>
/// The unescaped query string without the leading '?' character
/// </summary>
public string Value
{
get { return _value; }
}
/// <summary>
/// True if the query string is not empty
/// </summary>
public bool HasValue
{
get { return !String.IsNullOrWhiteSpace(_value); }
}
/// <summary>
/// Provides the query string escaped in a way which is correct for combining into the URI representation.
/// A leading '?' character will be prepended unless the Value is null or empty. Characters which are potentally
/// dangerous are escaped.
/// </summary>
/// <returns>The query string value</returns>
public override string ToString()
{
return ToUriComponent();
}
/// <summary>
/// Provides the query string escaped in a way which is correct for combining into the URI representation.
/// A leading '?' character will be prepended unless the Value is null or empty. Characters which are potentially
/// dangerous are escaped.
/// </summary>
/// <returns>The query string value</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "Purpose of the method is to return a string")]
public string ToUriComponent()
{
// Escape things properly so System.Uri doesn't mis-interpret the data.
return HasValue ? "?" + _value.Replace("#", "%23") : String.Empty;
}
/// <summary>
/// Returns an QueryString given the query as it is escaped in the URI format. The string MUST NOT contain any
/// value that is not a query.
/// </summary>
/// <param name="uriComponent">The escaped query as it appears in the URI format.</param>
/// <returns>The resulting QueryString</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", Justification = "Delimiter characters ? and # must be escaped by this method instead of truncating the value")]
public static QueryString FromUriComponent(string uriComponent)
{
if (String.IsNullOrEmpty(uriComponent))
{
return new QueryString(string.Empty);
}
if (uriComponent[0] != '?')
{
throw new ArgumentException(""/*Resources.Exception_QueryStringMustStartWithDelimiter*/, "uriComponent");
}
return new QueryString(uriComponent.Substring(1));
}
/// <summary>
/// Returns an QueryString given the query as from a Uri object. Relative Uri objects are not supported.
/// </summary>
/// <param name="uri">The Uri object</param>
/// <returns>The resulting QueryString</returns>
public static QueryString FromUriComponent(Uri uri)
{
if (uri == null)
{
throw new ArgumentNullException("uri");
}
return new QueryString(uri.GetComponents(UriComponents.Query, UriFormat.UriEscaped));
}
public bool Equals(QueryString other)
{
return string.Equals(_value, other._value);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is QueryString && Equals((QueryString)obj);
}
public override int GetHashCode()
{
return (_value != null ? _value.GetHashCode() : 0);
}
public static bool operator ==(QueryString left, QueryString right)
{
return left.Equals(right);
}
public static bool operator !=(QueryString left, QueryString right)
{
return !left.Equals(right);
}
}
}

View File

@ -0,0 +1,6 @@
using System.Threading.Tasks;
namespace Microsoft.AspNet.Abstractions
{
public delegate Task RequestDelegate(HttpContextBase context);
}

View File

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.AspNet.FeatureModel.Implementation;
namespace Microsoft.AspNet.FeatureModel
{
public class FeatureContainer : IFeatureContainer
{
private readonly IFeatureContainer _defaultFeatures;
private readonly IDictionary<Type, object> _featureByFeatureType = new Dictionary<Type, object>();
private readonly IDictionary<string, Type> _featureTypeByName = new Dictionary<string, Type>();
private readonly object _containerSync = new Object();
private int _containerRevision;
public FeatureContainer()
{
}
public FeatureContainer(IFeatureContainer defaultFeatures)
{
_defaultFeatures = defaultFeatures;
}
public virtual object GetFeature(Type type)
{
object feature;
if (_featureByFeatureType.TryGetValue(type, out feature))
{
return feature;
}
Type actualType;
if (_featureTypeByName.TryGetValue(type.FullName, out actualType))
{
if (_featureByFeatureType.TryGetValue(actualType, out feature))
{
return Converter.Convert(type, actualType, feature);
}
}
return _defaultFeatures != null ? _defaultFeatures.GetFeature(type) : null;
}
public virtual object GetDefaultFeature(Type type)
{
return null;
}
public virtual void SetFeature(Type type, object feature)
{
lock (_containerSync)
{
Type priorFeatureType;
if (_featureTypeByName.TryGetValue(type.FullName, out priorFeatureType))
{
if (priorFeatureType == type)
{
_featureByFeatureType[type] = feature;
}
else
{
_featureTypeByName[type.FullName] = type;
_featureByFeatureType.Remove(priorFeatureType);
_featureByFeatureType.Add(type, feature);
}
}
else
{
_featureTypeByName.Add(type.FullName, type);
_featureByFeatureType.Add(type, feature);
}
Interlocked.Increment(ref _containerRevision);
}
}
public virtual int Revision
{
get { return _containerRevision; }
}
public void Dispose()
{
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
namespace Microsoft.AspNet.FeatureModel
{
public interface IFeatureContainer : IDisposable
{
object GetFeature(Type type);
void SetFeature(Type type, object feature);
//IEnumerable<Type> GetFeatureTypes();
int Revision { get; }
}
}

View File

@ -0,0 +1,384 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
namespace Microsoft.AspNet.FeatureModel.Implementation
{
public abstract class NonGenericProxyBase
{
public readonly Type WrappedType;
protected NonGenericProxyBase(Type wrappedType)
{
this.WrappedType = wrappedType;
}
public abstract object UnderlyingInstanceAsObject
{
get;
}
}
public class BaseType<T> : NonGenericProxyBase where T : class
{
protected T instance;
public BaseType(T inst)
: base(typeof(T))
{
if (inst == null) throw new InvalidOperationException("should never construct proxy over null");
this.instance = inst;
}
public T UnderlyingInstance
{
get
{
return instance;
}
}
public override object UnderlyingInstanceAsObject
{
get
{
return instance;
}
}
}
public class Converter
{
public static object Convert(Type outputType, Type inputType, object input)
{
if (inputType == outputType) return input;
if (!inputType.IsInterface || !outputType.IsInterface) throw new InvalidOperationException("Both types must be interfaces");
if (inputType.GetInterfaces().Contains(outputType)) return input;
if (input == null) return null;
Type t = EnsureConverter(outputType, inputType);
return Activator.CreateInstance(t, input);
}
public static TOut Convert<TOut>(Type inputType, object input)
where TOut : class
{
return (TOut)Convert(typeof (TOut), inputType, input);
}
public static TOut Convert<TIn, TOut>(TIn input)
where TIn : class
where TOut : class
{
return Convert<TOut>(typeof(TIn), input);
}
public static TOut Convert<TOut>(object input)
where TOut : class
{
if (input == null) return null;
var interfaceName = typeof(TOut).FullName;
foreach (var inputType in input.GetType().GetInterfaces())
{
if (inputType.FullName == interfaceName)
{
return Convert<TOut>(inputType, input);
}
}
return null;
}
public static Type EnsureConverter(Type tout, Type tin)
{
CacheResult result;
if (!ConverterTypeCache.TryGetValue(new Tuple<Type, Type>(tin, tout), out result))
{
EnsureCastPossible(tout, tin);
return EnsureConverter(tout, tin);
}
else
{
if (result is ErrorResult)
{
throw new InvalidCastException((result as ErrorResult).error);
}
else if (result is CurrentlyVerifyingResult)
{
throw new InvalidOperationException("Type cannot be obtained in verification phase");
}
else if (result is TypeBuilderResult)
{
return (result as TypeBuilderResult).result;
}
else if (result is VerificationSucceededResult)
{
return CreateWrapperType(tout, tin, result as VerificationSucceededResult);
}
else
{
throw new InvalidOperationException("Invalid cache state");
}
}
}
class CacheResult
{
}
class TypeBuilderResult : CacheResult
{
internal TypeBuilderResult(Type result)
{
this.result = result;
}
internal readonly Type result;
}
class ErrorResult : CacheResult
{
internal ErrorResult(string error)
{
this.error = error;
}
internal readonly string error;
}
class CurrentlyVerifyingResult : CacheResult
{
}
enum SuccessKind
{
Identity,
SubInterface,
Wrapper,
}
class VerificationSucceededResult : CacheResult
{
internal VerificationSucceededResult(SuccessKind kind)
{
this.kind = kind;
}
internal VerificationSucceededResult(Dictionary<MethodInfo, MethodInfo> mappings)
{
this.kind = SuccessKind.Wrapper;
this.methodMappings = mappings;
}
internal readonly SuccessKind kind;
internal readonly Dictionary<MethodInfo, MethodInfo> methodMappings;
}
static Dictionary<Tuple<Type, Type>, CacheResult> ConverterTypeCache = new Dictionary<Tuple<Type, Type>, CacheResult>();
static ConditionalWeakTable<object, NonGenericProxyBase> ConverterInstanceCache = new ConditionalWeakTable<object, NonGenericProxyBase>();
static AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ProxyHolderAssembly"), AssemblyBuilderAccess.Run);
static ModuleBuilder modb = ab.DefineDynamicModule("Main Module");
class EqComparer : IEqualityComparer<ParameterInfo>
{
bool IEqualityComparer<ParameterInfo>.Equals(ParameterInfo x, ParameterInfo y)
{
return EqualTypes(x.ParameterType, y.ParameterType);
}
int IEqualityComparer<ParameterInfo>.GetHashCode(ParameterInfo obj)
{
return obj.GetHashCode();
}
}
static bool EqualTypes(Type sourceType, Type targetType)
{
return EnsureCastPossible(targetType, sourceType);
}
static MethodInfo FindCorrespondingMethod(Type targetType, Type sourceType, MethodInfo miTarget)
{
MethodInfo[] sms = sourceType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where((MethodInfo mi) => mi.Name == miTarget.Name).ToArray();
if (sms != null && sms.Length != 0)
{
MethodInfo[] sm = null;
try
{
sm = sms.Where((mi) => (mi.GetParameters().SequenceEqual(miTarget.GetParameters(), new EqComparer()))).ToArray();
}
catch
{
}
if (sm != null && sm.Length != 0)
{
if (sm.Length > 1) return null;
if (EqualTypes(sm[0].ReturnType, miTarget.ReturnType))
{
return sm[0];
}
}
}
MethodInfo[] rval = sourceType.GetInterfaces().Select((inheritedItf) => FindCorrespondingMethod(targetType, inheritedItf, miTarget)).ToArray();
if (rval == null || rval.Length == 0) return null;
if (rval.Length > 1) return null;
return rval[0];
}
static void AddMethod(Type targetType, Type sourceType, TypeBuilder tb, MethodInfo miTarget, MethodInfo miSource)
{
ParameterInfo[] pisTarget = miTarget.GetParameters();
ParameterInfo[] pisSource = miSource.GetParameters();
MethodBuilder metb;
Type[] typesTarget;
if (pisTarget == null || pisTarget.Length == 0)
{
metb = tb.DefineMethod(miTarget.Name, MethodAttributes.Virtual, CallingConventions.HasThis, miTarget.ReturnType, null);
pisTarget = new ParameterInfo[0];
typesTarget = new Type[0];
}
else
{
typesTarget = pisTarget.Select((pi) => pi.ParameterType).ToArray();
Type[][] requiredCustomMods = pisTarget.Select((pi) => pi.GetRequiredCustomModifiers()).ToArray();
Type[][] optionalCustomMods = pisTarget.Select((pi) => pi.GetOptionalCustomModifiers()).ToArray();
metb = tb.DefineMethod(miTarget.Name, MethodAttributes.Virtual, CallingConventions.HasThis, miTarget.ReturnType, null, null, typesTarget, requiredCustomMods, optionalCustomMods);
}
ILGenerator il = metb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, tb.BaseType.GetField("instance", BindingFlags.NonPublic | BindingFlags.Instance));
for (int pi = 0; pi < pisTarget.Length; pi++)
{
il.Emit(OpCodes.Ldarg, pi + 1);
EmitParamConversion(il, typesTarget[pi], pisSource[pi].ParameterType);
}
il.EmitCall(OpCodes.Callvirt, miSource, null);
EmitParamConversion(il, miSource.ReturnType, miTarget.ReturnType);
il.Emit(OpCodes.Ret);
tb.DefineMethodOverride(metb, miTarget);
}
static void EmitParamConversion(ILGenerator il, Type typeOnStack, Type typeRequiredInSignature)
{
if (typeOnStack != typeRequiredInSignature)
{
if (typeOnStack.GetInterfaces().Contains(typeRequiredInSignature))
{
il.Emit(OpCodes.Castclass, typeRequiredInSignature);
}
else
{
Label lEnd = il.DefineLabel();
Label lCreateProxy = il.DefineLabel();
il.Emit(OpCodes.Dup); // o o
il.Emit(OpCodes.Brfalse_S, lEnd); // o
il.Emit(OpCodes.Dup); // o o
il.Emit(OpCodes.Isinst, typeof(NonGenericProxyBase)); // o [p/n]
il.Emit(OpCodes.Brfalse_S, lCreateProxy); // o
il.Emit(OpCodes.Isinst, typeof(NonGenericProxyBase)); // p
il.EmitCall(OpCodes.Callvirt, typeof(NonGenericProxyBase).GetMethod("get_UnderlyingInstanceAsObject"), null); // uo
il.Emit(OpCodes.Dup); // uo uo
il.Emit(OpCodes.Isinst, typeRequiredInSignature); // uo [ro/n]
il.Emit(OpCodes.Brtrue_S, lEnd); // uo
il.MarkLabel(lCreateProxy); // uo
Type paramProxyType = EnsureConverter(typeRequiredInSignature, typeOnStack);
il.Emit(OpCodes.Newobj, paramProxyType.GetConstructors()[0]);
il.MarkLabel(lEnd); // ro
}
}
}
static bool EnsureCastPossible(Type targetType, Type sourceType)
{
var key = new Tuple<Type, Type>(sourceType, targetType);
CacheResult cr = null;
if (ConverterTypeCache.TryGetValue(key, out cr))
{
if (cr is CurrentlyVerifyingResult || cr is VerificationSucceededResult || cr is TypeBuilderResult) return true;
if (cr is ErrorResult) return false;
}
if (targetType == sourceType)
{
ConverterTypeCache[key] = new VerificationSucceededResult(SuccessKind.Identity);
return true;
}
if (targetType.GetInterfaces().Contains(sourceType))
{
ConverterTypeCache[key] = new VerificationSucceededResult(SuccessKind.SubInterface);
return true;
}
if (!targetType.IsInterface || !sourceType.IsInterface)
{
ConverterTypeCache[key] = new ErrorResult("Cannot cast " + sourceType + " to " + targetType);
return false;
}
bool success = false;
ConverterTypeCache[key] = new CurrentlyVerifyingResult();
try
{
Dictionary<MethodInfo, MethodInfo> mappings = new Dictionary<MethodInfo, MethodInfo>();
foreach (MethodInfo mi in targetType.GetMethods().Concat(targetType.GetInterfaces().SelectMany((itf) => itf.GetMethods())))
{
MethodInfo mapping = FindCorrespondingMethod(targetType, sourceType, mi);
if (mapping == null)
{
ConverterTypeCache[key] = new ErrorResult("Can not cast " + sourceType + " to " + targetType + " because of missing method: " + mi.Name);
return false;
}
mappings[mi] = mapping;
}
ConverterTypeCache[key] = new VerificationSucceededResult(mappings);
success = true;
return true;
}
finally
{
if (!success)
{
if (!(ConverterTypeCache[key] is ErrorResult))
{
ConverterTypeCache[key] = new ErrorResult("Can not cast " + sourceType + " to " + targetType);
}
}
}
}
static int counter = 0;
static Type CreateWrapperType(Type targetType, Type sourceType, VerificationSucceededResult result)
{
Dictionary<MethodInfo, MethodInfo> mappings = result.methodMappings;
Type baseType = Assembly.GetExecutingAssembly().GetType("InterfaceMapper.BaseType`1").MakeGenericType(sourceType);
TypeBuilder tb = modb.DefineType("ProxyType" + counter++ + " wrapping:" + sourceType.Name + " to look like:" + targetType.Name, TypeAttributes.Class, baseType, new Type[] { targetType });
ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { sourceType });
ILGenerator il = cb.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Castclass, sourceType);
il.Emit(OpCodes.Call, baseType.GetConstructor(new Type[] { sourceType }));
il.Emit(OpCodes.Ret);
var tuple = new Tuple<Type, Type>(sourceType, targetType);
try
{
ConverterTypeCache[tuple] = new TypeBuilderResult(tb);
foreach (MethodInfo mi in targetType.GetMethods().Concat(targetType.GetInterfaces().SelectMany((itf) => itf.GetMethods())))
{
AddMethod(targetType, sourceType, tb, mi, mappings[mi]);
}
Type t = tb.CreateType();
ConverterTypeCache[tuple] = new TypeBuilderResult(t);
return t;
}
catch (Exception e)
{
ConverterTypeCache[tuple] = new ErrorResult(e.Message);
throw;
}
}
}
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A780873E-09F9-4E44-AE06-AF00C4E88E1E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.FeatureModel</RootNamespace>
<AssemblyName>Microsoft.AspNet.FeatureModel</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Microsoft.AspNet.FeatureModel.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="IFeatureContainer.cs" />
<Compile Include="FeatureContainer.cs" />
<Compile Include="Implementation\Converter.cs" />
<Compile Include="ObjectFeatureContainer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Microsoft.AspNet.FeatureModel.nuspec" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,22 @@
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
<owners>$authors$</owners>
<licenseUrl>$licenseUrl$</licenseUrl>
<projectUrl>$projectUrl$</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<title>$title$</title>
<description>$title$</description>
<tags>$tags$</tags>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="$id$.dll" target="lib\net45" />
<file src="$id$.xml" target="lib\net45" />
<file src="$id$.pdb" target="lib\net45" />
<file src="src\**" target="src" />
</files>
</package>

View File

@ -0,0 +1,50 @@
using System;
using Microsoft.AspNet.FeatureModel.Implementation;
namespace Microsoft.AspNet.FeatureModel
{
public class ObjectFeatureContainer : IFeatureContainer
{
private readonly object _instance;
public ObjectFeatureContainer(object instance)
{
_instance = instance;
}
public void Dispose()
{
var disposable = _instance as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
public object GetFeature(Type type)
{
if (type.IsInstanceOfType(_instance))
{
return _instance;
}
foreach (var interfaceType in _instance.GetType().GetInterfaces())
{
if (interfaceType.FullName == type.FullName)
{
return Converter.Convert(interfaceType, type, _instance);
}
}
return null;
}
public void SetFeature(Type type, object feature)
{
throw new NotImplementedException();
}
public int Revision
{
get { return 0; }
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.FeatureModel")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.FeatureModel")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("cf678d83-e6f7-4433-9bf2-c0efa68e399b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]

View File

@ -0,0 +1,8 @@
using Microsoft.AspNet.FeatureModel;
namespace Microsoft.AspNet.HttpEnvironment
{
public abstract class HttpEnvironmentBase : FeatureContainer, IHttpEnvironment
{
}
}

View File

@ -0,0 +1,10 @@
namespace Microsoft.AspNet.HttpEnvironment
{
public static class HttpEnvironmentExtensions
{
public static TFeature GetFeature<TFeature>(this IHttpEnvironment environment) where TFeature : class
{
return (TFeature)environment.GetFeature(typeof(TFeature));
}
}
}

View File

@ -0,0 +1,8 @@
using Microsoft.AspNet.FeatureModel;
namespace Microsoft.AspNet.HttpEnvironment
{
public interface IHttpEnvironment : IFeatureContainer
{
}
}

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{46D69EC9-7096-49D8-A184-A9BB5B2419A1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.HttpEnvironment</RootNamespace>
<AssemblyName>Microsoft.AspNet.HttpEnvironment</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Microsoft.AspNet.HttpEnvironment.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="HttpEnvironmentBase.cs" />
<Compile Include="HttpEnvironmentExtensions.cs" />
<Compile Include="IHttpEnvironment.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.AspNet.FeatureModel\Microsoft.AspNet.FeatureModel.csproj">
<Project>{A780873E-09F9-4E44-AE06-AF00C4E88E1E}</Project>
<Name>Microsoft.AspNet.FeatureModel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Microsoft.AspNet.HttpEnvironment.nuspec" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,22 @@
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
<owners>$authors$</owners>
<licenseUrl>$licenseUrl$</licenseUrl>
<projectUrl>$projectUrl$</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<title>$title$</title>
<description>$title$</description>
<tags>$tags$</tags>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="$id$.dll" target="lib\net45" />
<file src="$id$.xml" target="lib\net45" />
<file src="$id$.pdb" target="lib\net45" />
<file src="src\**" target="src" />
</files>
</package>

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.Environments")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.Environments")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1b326e9f-7c7a-42cd-9861-cdbef8353aed")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpApplicationInformation
{
string AppName { get; set; }
string AppMode { get; set; }
CancellationToken OnAppDisposing { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpBuffering
{
void DisableRequestBuffering();
void DisableResponseBuffering();
}
}

View File

@ -0,0 +1,13 @@
using System.Net;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpConnection
{
IPAddress RemoteIpAddress { get; set; }
int RemotePort { get; set; }
IPAddress LocalIpAddress { get; set; }
int LocalPort { get; set; }
bool IsLocal { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpRequest
{
string Protocol { get; set; }
string Scheme { get; set; }
string Method { get; set; }
string PathBase { get; set; }
string Path { get; set; }
string QueryString { get; set; }
IDictionary<string, string[]> Headers { get; set; }
Stream Body { get; set; }
Uri Uri { get; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpResponse
{
int StatusCode { get; set; }
string ReasonPhrase { get; set; }
IDictionary<string, string[]> Headers { get; set; }
Stream Body { get; set; }
void OnSendingHeaders(Action<object> callback, object state);
}
}

View File

@ -0,0 +1,10 @@
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpSendFile
{
Task SendFileAsync(string path, long offset, long? length, CancellationToken cancellation);
}
}

View File

@ -0,0 +1,11 @@
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpTransportLayerSecurity
{
X509Certificate ClientCertificate { get; set; }
Task LoadAsync();
}
}

View File

@ -0,0 +1,11 @@
using System.Net.WebSockets;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces
{
public interface IHttpWebSocketAccept
{
bool IsWebSocketRequest { get; set; }
Task<WebSocket> AcceptAsync();
}
}

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{42309978-0661-41D8-8654-39453265C5F9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.HttpFeature</RootNamespace>
<AssemblyName>Microsoft.AspNet.HttpFeature</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Microsoft.AspNet.HttpFeature.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="IHttpApplicationInformation.cs" />
<Compile Include="IHttpSendFile.cs" />
<Compile Include="IHttpTransportLayerSecurity.cs" />
<Compile Include="IHttpWebSocketAccept.cs" />
<Compile Include="Security\IAuthenticationChallenge.cs" />
<Compile Include="Security\IAuthenticationDescription.cs" />
<Compile Include="Security\IAuthenticationResult.cs" />
<Compile Include="Security\IAuthenticationSignIn.cs" />
<Compile Include="Security\IAuthenticationSignOut.cs" />
<Compile Include="Security\IHttpAuthentication.cs" />
<Compile Include="IHttpBuffering.cs" />
<Compile Include="IHttpConnection.cs" />
<Compile Include="IHttpRequest.cs" />
<Compile Include="IHttpResponse.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Microsoft.AspNet.HttpFeature.nuspec" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,22 @@
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
<owners>$authors$</owners>
<licenseUrl>$licenseUrl$</licenseUrl>
<projectUrl>$projectUrl$</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<title>$title$</title>
<description>$title$</description>
<tags>$tags$</tags>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="$id$.dll" target="lib\net45" />
<file src="$id$.xml" target="lib\net45" />
<file src="$id$.pdb" target="lib\net45" />
<file src="src\**" target="src" />
</files>
</package>

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.Interfaces")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.Interfaces")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fbcea83c-9fdd-445d-a2d4-93e9062754f3")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Interfaces
{
public interface IAuthenticationChallenge
{
IEnumerable<string> AuthenticationTypes { get; }
IDictionary<string, string> Properties { get; }
}
}

View File

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Interfaces.Security
{
public interface IAuthenticationDescription
{
IDictionary<string, object> Properties { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System.Collections.Generic;
using System.Security.Claims;
namespace Microsoft.AspNet.Interfaces.Security
{
public interface IAuthenticationResult
{
ClaimsIdentity Identity { get; }
IDictionary<string, object> Properties { get; }
IAuthenticationDescription Description { get; }
}
}

View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Security.Claims;
namespace Microsoft.AspNet.Interfaces.Security
{
public interface IAuthenticationSignIn
{
ClaimsPrincipal User { get; }
IDictionary<string, string> Properties { get; }
}
}

View File

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Microsoft.AspNet.Interfaces.Security
{
public interface IAuthenticationSignOut
{
IEnumerable<string> AuthenticationTypes { get; }
}
}

View File

@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Interfaces.Security
{
public interface IHttpAuthentication
{
IPrincipal User { get; set; }
IEnumerable<IAuthenticationResult> Authenticate(string[] authenticationTypes);
Task<IEnumerable<IAuthenticationResult>> AuthenticateAsync(string[] authenticationTypes);
IAuthenticationChallenge ChallengeDetails { get; set; }
IAuthenticationSignIn SignInDetails { get; set; }
IAuthenticationSignOut SignOutDetails { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using Microsoft.AspNet.Abstractions;
using Shouldly;
using Xunit;
namespace Microsoft.AspNet.PipelineCore.Tests
{
public class BuilderTests
{
[Fact]
public void BuildReturnsCallableDelegate()
{
var builder = new Builder();
var app = builder.Build();
var mockHttpContext = new Moq.Mock<HttpContextBase>();
var mockHttpResponse = new Moq.Mock<HttpResponseBase>();
mockHttpContext.SetupGet(x => x.Response).Returns(mockHttpResponse.Object);
mockHttpResponse.SetupProperty(x => x.StatusCode);
app.Invoke(mockHttpContext.Object);
mockHttpContext.Object.Response.StatusCode.ShouldBe(404);
}
}
}

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{86942914-0334-4352-87ED-B971281C74E2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.PipelineCore.Tests</RootNamespace>
<AssemblyName>Microsoft.AspNet.PipelineCore.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Microsoft.AspNet.PipelineCore.Tests.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Moq, Version=4.2.1312.1622, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Moq.4.2.1312.1622\lib\net40\Moq.dll</HintPath>
</Reference>
<Reference Include="Shouldly, Version=1.1.1.1, Culture=neutral, PublicKeyToken=6042cbcb05cbc941, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Shouldly.1.1.1.1\lib\35\Shouldly.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="xunit, Version=1.9.2.1705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BuilderTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNet.PipelineCore\Microsoft.AspNet.PipelineCore.csproj">
<Project>{A4D3E280-8838-4614-9B99-4874C3CBDF82}</Project>
<Name>Microsoft.AspNet.PipelineCore</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Microsoft.AspNet.Abstractions\Microsoft.AspNet.Abstractions.csproj">
<Project>{4E1520B1-01F4-481B-96A2-24067EAA52FA}</Project>
<Name>Microsoft.AspNet.Abstractions</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.PipelineCore.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.PipelineCore.Tests")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7c564547-b037-4054-a1ec-18e62717be47")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Moq" version="4.2.1312.1622" targetFramework="net45" />
<package id="Shouldly" version="1.1.1.1" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.Interfaces;
using Microsoft.AspNet.PipelineCore.Owin;
namespace Microsoft.AspNet.PipelineCore
{
public class Builder : IBuilder
{
private readonly IFeatureContainer _features;
private readonly IList<Entry> _components = new List<Entry>();
public Builder()
{
_features = new FeatureModel.FeatureContainer();
}
public Builder(IFeatureContainer features)
{
_features = features;
}
public void Dispose()
{
_features.Dispose();
}
public virtual object GetFeature(Type type)
{
return _features.GetFeature(type);
}
public virtual void SetFeature(Type type, object feature)
{
_features.SetFeature(type, feature);
}
public virtual int Revision
{
get { return _features.Revision; }
}
public IBuilder Use(object middleware, params object[] args)
{
_components.Add(new Entry(middleware, args));
return this;
}
class Entry
{
private readonly object _middleware;
private readonly object[] _args;
public Entry(object middleware, object[] args)
{
_middleware = middleware;
_args = args;
}
}
public IBuilder New()
{
return new Builder(_features);
}
public RequestDelegate Build()
{
RequestDelegate app = async context => context.Response.StatusCode = 404;
foreach (var component in _components.Reverse())
{
app = Activate(component, app);
}
return app;
}
private RequestDelegate Activate(Entry component, RequestDelegate app)
{
return app;
}
public Func<TContext, Task> Adapt<TContext>(object app)
{
return null;
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.FeatureModel;
using Microsoft.AspNet.HttpEnvironment;
namespace Microsoft.AspNet.PipelineCore
{
public class HttpContext : HttpContextBase, IHttpEnvironment
{
private readonly IFeatureContainer _features;
private readonly HttpRequestBase _request;
private readonly HttpResponseBase _response;
public HttpContext(IHttpEnvironment environment)
{
_features = environment;
_request = new HttpRequest(this);
_response = new HttpResponse(this);
}
public override HttpRequestBase Request { get { return _request; } }
public override HttpResponseBase Response { get { return _response; } }
public void Dispose()
{
_features.Dispose();
}
public object GetFeature(Type type)
{
return _features.GetFeature(type);
}
public void SetFeature(Type type, object feature)
{
_features.SetFeature(type, feature);
}
public int Revision
{
get { return _features.Revision; }
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.IO;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.Interfaces;
namespace Microsoft.AspNet.PipelineCore
{
public class HttpRequest : HttpRequestBase
{
private readonly HttpContext _context;
private int _revision;
private IHttpRequest _request;
private IHttpConnection _connection;
public HttpRequest(HttpContext context)
{
_context = context;
}
private IHttpRequest IHttpRequest
{
get { return EnsureCurrent(_request) ?? (_request = _context.GetFeature<IHttpRequest>()); }
}
private IHttpConnection IHttpConnection
{
get { return EnsureCurrent(_connection) ?? (_connection = _context.GetFeature<IHttpConnection>()); }
}
private T EnsureCurrent<T>(T feature) where T : class
{
if (_revision == _context.Revision) return feature;
_request = null;
_connection = null;
_revision = _context.Revision;
return null;
}
public override HttpContextBase HttpContext { get { return _context; } }
public override Uri Uri
{
get { return IHttpRequest.Uri; }
}
//public override Uri Uri { get { _request} }
public override PathString PathBase
{
get { return new PathString(IHttpRequest.PathBase); }
set { IHttpRequest.PathBase = value.Value; }
}
public override PathString Path
{
get { return new PathString(IHttpRequest.Path); }
set { IHttpRequest.Path = value.Value; }
}
public override QueryString QueryString
{
get { return new QueryString(IHttpRequest.QueryString); }
set { IHttpRequest.QueryString = value.Value; }
}
public override Stream Body
{
get { return IHttpRequest.Body; }
set { IHttpRequest.Body = value; }
}
}
}

View File

@ -0,0 +1,43 @@
using System.IO;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.Interfaces;
namespace Microsoft.AspNet.PipelineCore
{
public class HttpResponse : HttpResponseBase
{
private readonly HttpContext _context;
private IHttpResponse _response;
private int _revision;
public HttpResponse(HttpContext context)
{
_context = context;
}
private IHttpResponse IHttpResponse
{
get { return EnsureCurrent(_response) ?? (_response = _context.GetFeature<IHttpResponse>()); }
}
private T EnsureCurrent<T>(T feature) where T : class
{
if (_revision == _context.Revision) return feature;
_response = null;
_revision = _context.Revision;
return null;
}
public override HttpContextBase HttpContext { get { return _context; } }
public override int StatusCode
{
get { return IHttpResponse.StatusCode; }
set { IHttpResponse.StatusCode = value; }
}
public override Stream Body { get { return _response.Body; } set { _response.Body = value; } }
}
}

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A4D3E280-8838-4614-9B99-4874C3CBDF82}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.AspNet.PipelineCore</RootNamespace>
<AssemblyName>Microsoft.AspNet.PipelineCore</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Microsoft.AspNet.PipelineCore.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Builder.cs" />
<Compile Include="HttpContext.cs" />
<Compile Include="HttpRequest.cs" />
<Compile Include="HttpResponse.cs" />
<Compile Include="Owin\OwinConstants.cs" />
<Compile Include="Owin\OwinHttpEnvironment.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.AspNet.FeatureModel\Microsoft.AspNet.FeatureModel.csproj">
<Project>{A780873E-09F9-4E44-AE06-AF00C4E88E1E}</Project>
<Name>Microsoft.AspNet.FeatureModel</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.AspNet.Abstractions\Microsoft.AspNet.Abstractions.csproj">
<Project>{4e1520b1-01f4-481b-96a2-24067eaa52fa}</Project>
<Name>Microsoft.AspNet.Abstractions</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.AspNet.HttpEnvironment\Microsoft.AspNet.HttpEnvironment.csproj">
<Project>{46D69EC9-7096-49D8-A184-A9BB5B2419A1}</Project>
<Name>Microsoft.AspNet.HttpEnvironment</Name>
</ProjectReference>
<ProjectReference Include="..\Microsoft.AspNet.HttpFeature\Microsoft.AspNet.HttpFeature.csproj">
<Project>{42309978-0661-41d8-8654-39453265c5f9}</Project>
<Name>Microsoft.AspNet.HttpFeature</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Microsoft.AspNet.PipelineCore.nuspec" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,22 @@
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<authors>$authors$</authors>
<owners>$authors$</owners>
<licenseUrl>$licenseUrl$</licenseUrl>
<projectUrl>$projectUrl$</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<title>$title$</title>
<description>$title$</description>
<tags>$tags$</tags>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="$id$.dll" target="lib\net45" />
<file src="$id$.xml" target="lib\net45" />
<file src="$id$.pdb" target="lib\net45" />
<file src="src\**" target="src" />
</files>
</package>

View File

@ -0,0 +1,174 @@
namespace Microsoft.AspNet.PipelineCore.Owin
{
internal static class OwinConstants
{
#region OWIN v1.0.0 - 3.2.1. Request Data
// http://owin.org/spec/owin-1.0.0.html
public const string RequestScheme = "owin.RequestScheme";
public const string RequestMethod = "owin.RequestMethod";
public const string RequestPathBase = "owin.RequestPathBase";
public const string RequestPath = "owin.RequestPath";
public const string RequestQueryString = "owin.RequestQueryString";
public const string RequestProtocol = "owin.RequestProtocol";
public const string RequestHeaders = "owin.RequestHeaders";
public const string RequestBody = "owin.RequestBody";
#endregion
#region OWIN v1.0.0 - 3.2.2. Response Data
// http://owin.org/spec/owin-1.0.0.html
public const string ResponseStatusCode = "owin.ResponseStatusCode";
public const string ResponseReasonPhrase = "owin.ResponseReasonPhrase";
public const string ResponseProtocol = "owin.ResponseProtocol";
public const string ResponseHeaders = "owin.ResponseHeaders";
public const string ResponseBody = "owin.ResponseBody";
#endregion
#region OWIN v1.0.0 - 3.2.3. Other Data
// http://owin.org/spec/owin-1.0.0.html
public const string CallCancelled = "owin.CallCancelled";
public const string OwinVersion = "owin.Version";
#endregion
#region OWIN Keys for IAppBuilder.Properties
internal static class Builder
{
public const string AddSignatureConversion = "builder.AddSignatureConversion";
public const string DefaultApp = "builder.DefaultApp";
}
#endregion
#region OWIN Key Guidelines and Common Keys - 6. Common keys
// http://owin.org/spec/CommonKeys.html
internal static class CommonKeys
{
public const string ClientCertificate = "ssl.ClientCertificate";
public const string RemoteIpAddress = "server.RemoteIpAddress";
public const string RemotePort = "server.RemotePort";
public const string LocalIpAddress = "server.LocalIpAddress";
public const string LocalPort = "server.LocalPort";
public const string IsLocal = "server.IsLocal";
public const string TraceOutput = "host.TraceOutput";
public const string Addresses = "host.Addresses";
public const string AppName = "host.AppName";
public const string Capabilities = "server.Capabilities";
public const string OnSendingHeaders = "server.OnSendingHeaders";
public const string OnAppDisposing = "host.OnAppDisposing";
public const string Scheme = "scheme";
public const string Host = "host";
public const string Port = "port";
public const string Path = "path";
}
#endregion
#region SendFiles v0.3.0
// http://owin.org/extensions/owin-SendFile-Extension-v0.3.0.htm
internal static class SendFiles
{
// 3.1. Startup
public const string Version = "sendfile.Version";
public const string Support = "sendfile.Support";
public const string Concurrency = "sendfile.Concurrency";
// 3.2. Per Request
public const string SendAsync = "sendfile.SendAsync";
}
#endregion
#region Opaque v0.3.0
// http://owin.org/extensions/owin-OpaqueStream-Extension-v0.3.0.htm
internal static class OpaqueConstants
{
// 3.1. Startup
public const string Version = "opaque.Version";
// 3.2. Per Request
public const string Upgrade = "opaque.Upgrade";
// 5. Consumption
public const string Stream = "opaque.Stream";
// public const string Version = "opaque.Version"; // redundant, declared above
public const string CallCancelled = "opaque.CallCancelled";
}
#endregion
#region WebSocket v0.4.0
// http://owin.org/extensions/owin-OpaqueStream-Extension-v0.3.0.htm
internal static class WebSocket
{
// 3.1. Startup
public const string Version = "websocket.Version";
// 3.2. Per Request
public const string Accept = "websocket.Accept";
// 4. Accept
public const string SubProtocol = "websocket.SubProtocol";
// 5. Consumption
public const string SendAsync = "websocket.SendAsync";
public const string ReceiveAsync = "websocket.ReceiveAsync";
public const string CloseAsync = "websocket.CloseAsync";
// public const string Version = "websocket.Version"; // redundant, declared above
public const string CallCancelled = "websocket.CallCancelled";
public const string ClientCloseStatus = "websocket.ClientCloseStatus";
public const string ClientCloseDescription = "websocket.ClientCloseDescription";
}
#endregion
#region Security v0.1.0
// http://owin.org/extensions/owin-Security-Extension-v0.1.0.htm
internal static class Security
{
// 3.2. Per Request
public const string User = "server.User";
public const string Authenticate = "security.Authenticate";
// 3.3. Response
public const string SignIn = "security.SignIn";
public const string SignOut = "security.SignOut";
public const string Challenge = "security.Challenge";
}
#endregion
}
}

View File

@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.HttpEnvironment;
using Microsoft.AspNet.Interfaces;
namespace Microsoft.AspNet.PipelineCore.Owin
{
public class OwinHttpEnvironment :
IHttpRequest, IHttpResponse, IHttpConnection, IHttpSendFile, IHttpTransportLayerSecurity
{
public IDictionary<string, object> Environment { get; set; }
public OwinHttpEnvironment(IDictionary<string, object> environment)
{
Environment = environment;
}
T Prop<T>(string key)
{
object value;
if (Environment.TryGetValue(key, out value) && value is T)
{
return (T)value;
}
return default(T);
}
void Prop(string key, object value)
{
Environment[key] = value;
}
string IHttpRequest.Protocol
{
get { return Prop<string>("owin.RequestProtocol"); }
set { Prop("owin.RequestProtocol", value); }
}
Uri IHttpRequest.Uri
{
get { throw new NotImplementedException(); }
}
string IHttpRequest.Scheme
{
get { return Prop<string>("owin.RequestScheme"); }
set { Prop("owin.RequestScheme", value); }
}
string IHttpRequest.Method
{
get { return Prop<string>("owin.RequestMethod"); }
set { Prop("owin.RequestMethod", value); }
}
string IHttpRequest.PathBase
{
get { return Prop<string>("owin.RequestPathBase"); }
set { Prop("owin.RequestPathBase", value); }
}
string IHttpRequest.Path
{
get { return Prop<string>("owin.RequestPath"); }
set { Prop("owin.RequestPath", value); }
}
string IHttpRequest.QueryString
{
get { return Prop<string>("owin.RequestQueryString"); }
set { Prop("owin.RequestQueryString", value); }
}
IDictionary<string, string[]> IHttpRequest.Headers
{
get { return Prop<IDictionary<string, string[]>>("owin.RequestHeaders"); }
set { Prop("owin.RequestHeaders", value); }
}
Stream IHttpRequest.Body
{
get { return Prop<Stream>("owin.RequestBody"); }
set { Prop("owin.RequestBody", value); }
}
int IHttpResponse.StatusCode
{
get { return Prop<int>("owin.ResponseStatusCode"); }
set { Prop("owin.ResponseStatusCode", value); }
}
string IHttpResponse.ReasonPhrase
{
get { return Prop<string>("owin.ResponseReasonPhrase"); }
set { Prop("owin.ResponseReasonPhrase", value); }
}
IDictionary<string, string[]> IHttpResponse.Headers
{
get { return Prop<IDictionary<string, string[]>>("owin.ResponseHeaders"); }
set { Prop("owin.ResponseHeaders", value); }
}
Stream IHttpResponse.Body
{
get { return Prop<Stream>("owin.ResponseBody"); }
set { Prop("owin.ResponseBody", value); }
}
void IHttpResponse.OnSendingHeaders(Action<object> callback, object state)
{
// TODO:
}
IPAddress IHttpConnection.RemoteIpAddress
{
get { return IPAddress.Parse(Prop<string>(OwinConstants.CommonKeys.RemoteIpAddress)); }
set { Prop(OwinConstants.CommonKeys.RemoteIpAddress, value.ToString()); }
}
int IHttpConnection.RemotePort
{
get { return int.Parse(Prop<string>(OwinConstants.CommonKeys.RemotePort)); }
set { Prop(OwinConstants.CommonKeys.RemotePort, value.ToString(CultureInfo.InvariantCulture)); }
}
IPAddress IHttpConnection.LocalIpAddress
{
get { return IPAddress.Parse(Prop<string>(OwinConstants.CommonKeys.LocalIpAddress)); }
set { Prop(OwinConstants.CommonKeys.LocalIpAddress, value.ToString()); }
}
int IHttpConnection.LocalPort
{
get { return int.Parse(Prop<string>(OwinConstants.CommonKeys.LocalPort)); }
set { Prop(OwinConstants.CommonKeys.LocalPort, value.ToString(CultureInfo.InvariantCulture)); }
}
bool IHttpConnection.IsLocal
{
get { return Prop<bool>(OwinConstants.CommonKeys.IsLocal); }
set { Prop(OwinConstants.CommonKeys.LocalPort, value); }
}
Task IHttpSendFile.SendFileAsync(string path, long offset, long? length, CancellationToken cancellation)
{
throw new NotImplementedException();
}
X509Certificate IHttpTransportLayerSecurity.ClientCertificate
{
get { return Prop<X509Certificate>(OwinConstants.CommonKeys.ClientCertificate); }
set { Prop(OwinConstants.CommonKeys.ClientCertificate, value); }
}
Task IHttpTransportLayerSecurity.LoadAsync()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.AspNet.Abstractions.Implementation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.AspNet.Abstractions.Implementation")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5886f89f-de4d-4e44-81c2-7a32b2c89cfd")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyVersion("0.1.0")]
[assembly: AssemblyFileVersion("0.1.0")]