Move functional tests of CORS middleware to this repo

- related to aspnet/Mvc#3612
This commit is contained in:
Doug Bunting 2015-12-11 21:53:45 -08:00
parent 2514b1112b
commit c3c0b45225
14 changed files with 256 additions and 4 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ nuget.exe
*.sln.ide
node_modules
**/[Cc]ompiler/[Rr]esources/**/*.js
*launchSettings.json

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{84FE6872-A610-4CEC-855F-A84CBF1F40FC}"
EndProject
@ -16,6 +16,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Cors", "sr
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Cors.Test", "test\Microsoft.AspNet.Cors.Test\Microsoft.AspNet.Cors.Test.xproj", "{F05BE96F-F869-4408-A480-96935B4835EE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{538380BF-0D4C-4E30-8F41-E75C4B1C01FA}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CorsMiddlewareWebSite", "test\WebSites\CorsMiddlewareWebSite\CorsMiddlewareWebSite.xproj", "{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -30,6 +34,10 @@ Global
{F05BE96F-F869-4408-A480-96935B4835EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F05BE96F-F869-4408-A480-96935B4835EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F05BE96F-F869-4408-A480-96935B4835EE}.Release|Any CPU.Build.0 = Release|Any CPU
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -37,5 +45,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{41349FCD-D1C4-47A6-82D0-D16D00A8D59D} = {84FE6872-A610-4CEC-855F-A84CBF1F40FC}
{F05BE96F-F869-4408-A480-96935B4835EE} = {F32074C7-087C-46CC-A913-422BFD2D6E0A}
{538380BF-0D4C-4E30-8F41-E75C4B1C01FA} = {F32074C7-087C-46CC-A913-422BFD2D6E0A}
{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB} = {538380BF-0D4C-4E30-8F41-E75C4B1C01FA}
EndGlobalSection
EndGlobal

View File

@ -1,3 +1,3 @@
{
"projects": ["src", "test"]
"projects": ["src", "test/WebSites"]
}

View File

@ -3,7 +3,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.Primitives;

View File

@ -0,0 +1,98 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNet.Cors.Infrastructure
{
public class CorsMiddlewareFunctionalTests : IClassFixture<CorsTestFixture<CorsMiddlewareWebSite.Startup>>
{
public CorsMiddlewareFunctionalTests(CorsTestFixture<CorsMiddlewareWebSite.Startup> fixture)
{
Client = fixture.Client;
}
public HttpClient Client { get; }
[Theory]
[InlineData("GET")]
[InlineData("HEAD")]
[InlineData("POST")]
public async Task ResourceWithSimpleRequestPolicy_Allows_SimpleRequests(string method)
{
// Arrange
var path = "/CorsMiddleware/EC6AA70D-BA3E-4B71-A87F-18625ADDB2BD";
var origin = "http://example.com";
var request = new HttpRequestMessage(new HttpMethod(method), path);
request.Headers.Add(CorsConstants.Origin, origin);
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal(path, content);
var responseHeaders = response.Headers;
var header = Assert.Single(response.Headers);
Assert.Equal(CorsConstants.AccessControlAllowOrigin, header.Key);
Assert.Equal(new[] { "http://example.com" }, header.Value.ToArray());
}
[Theory]
[InlineData("GET")]
[InlineData("HEAD")]
[InlineData("POST")]
[InlineData("PUT")]
public async Task PolicyFailed_Disallows_PreFlightRequest(string method)
{
// Arrange
var path = "/CorsMiddleware/9B8BB9C6-5BF2-4255-A636-DCB450D51AAE";
var request = new HttpRequestMessage(new HttpMethod(CorsConstants.PreflightHttpMethod), path);
// Adding a custom header makes it a non-simple request.
request.Headers.Add(CorsConstants.Origin, "http://example.com");
request.Headers.Add(CorsConstants.AccessControlRequestMethod, method);
request.Headers.Add(CorsConstants.AccessControlRequestHeaders, "Custom");
// Act
var response = await Client.SendAsync(request);
// Assert
// Middleware applied the policy and since that did not pass, there were no access control headers.
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
Assert.Empty(response.Headers);
// It should short circuit and hence no result.
var content = await response.Content.ReadAsStringAsync();
Assert.Equal(string.Empty, content);
}
[Fact]
public async Task PolicyFailed_Allows_ActualRequest_WithMissingResponseHeaders()
{
// Arrange
var path = "/CorsMiddleware/1E6C6F4D-1E1C-450E-8BD0-73DBF089A78F";
var request = new HttpRequestMessage(HttpMethod.Put, path);
// Adding a custom header makes it a non simple request.
request.Headers.Add(CorsConstants.Origin, "http://example2.com");
// Act
var response = await Client.SendAsync(request);
// Assert
// Middleware applied the policy and since that did not pass, there were no access control headers.
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Empty(response.Headers);
// It still has executed the action.
var content = await response.Content.ReadAsStringAsync();
Assert.Equal(path, content);
}
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Net.Http;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.TestHost;
namespace Microsoft.AspNet.Cors.Infrastructure
{
public class CorsTestFixture<TStartup> : IDisposable
where TStartup : class
{
private readonly TestServer _server;
public CorsTestFixture()
{
var builder = new WebHostBuilder().UseStartup<TStartup>();
_server = new TestServer(builder);
Client = _server.CreateClient();
Client.BaseAddress = new Uri("http://localhost");
}
public HttpClient Client { get; }
public void Dispose()
{
Client.Dispose();
_server.Dispose();
}
}
}

View File

@ -13,5 +13,8 @@
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -1,8 +1,10 @@
{
{
"version": "1.0.0-*",
"dependencies": {
"CorsMiddlewareWebSite": "1.0.0-*",
"Microsoft.AspNet.Cors": "6.0.0-*",
"Microsoft.AspNet.TestHost": "1.0.0-*",
"Microsoft.Extensions.Logging.Testing": "1.0.0-*",
"xunit.runner.aspnet": "2.0.0-aspnet-*"
},
"commands": {

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>b42d4844-fff8-4ec2-88d1-3ae95234d9eb</ProjectGuid>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<DevelopmentServerPort>41642</DevelopmentServerPort>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@ -0,0 +1,38 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
namespace CorsMiddlewareWebSite
{
public class EchoMiddleware
{
/// <summary>
/// Instantiates a new <see cref="EchoMiddleware"/>.
/// </summary>
/// <param name="next">The next middleware in the pipeline.</param>
public EchoMiddleware(RequestDelegate next)
{
}
/// <summary>
/// Echo the request's path in the response. Does not invoke later middleware in the pipeline.
/// </summary>
/// <param name="context">The <see cref="HttpContext"/> of the current request.</param>
/// <returns>A <see cref="Task"/> that completes when writing to the response is done.</returns>
public Task Invoke(HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
context.Response.ContentType = "text/plain; charset=utf-8";
var path = context.Request.PathBase + context.Request.Path + context.Request.QueryString;
return context.Response.WriteAsync(path, Encoding.UTF8);
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace CorsMiddlewareWebSite
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors(policy => policy.WithOrigins("http://example.com"));
app.UseMiddleware<EchoMiddleware>();
}
}
}

View File

@ -0,0 +1,15 @@
{
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel",
"weblistener": "Microsoft.AspNet.Server.WebListener"
},
"dependencies": {
"Microsoft.AspNet.Cors": "6.0.0-*",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
"Microsoft.AspNet.Server.WebListener": "1.0.0-*"
},
"frameworks": {
"dnx451": { },
"dnxcore50": { }
}
}

View File

@ -0,0 +1,4 @@
CorsMiddlewareWebSite
===
This web site illustrates how to use CorsMiddleware to apply a policy for entire application.

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
</system.webServer>
</configuration>