diff --git a/src/Metapackages/.gitignore b/src/Metapackages/.gitignore new file mode 100644 index 0000000000..3af0091ea3 --- /dev/null +++ b/src/Metapackages/.gitignore @@ -0,0 +1,37 @@ +[Oo]bj/ +[Bb]in/ +TestResults/ +.nuget/ +_ReSharper.*/ +packages/ +artifacts/ +PublishProfiles/ +*.user +*.suo +*.cache +*.docstates +_ReSharper.* +nuget.exe +*net45.csproj +*net451.csproj +*k10.csproj +*.psess +*.vsp +*.pidb +*.userprefs +*DS_Store +*.ncrunchsolution +*.*sdf +*.ipch +*.sln.ide +project.lock.json +.vs +.vscode/ +.build/ +.testPublish/ +global.json + +# Dependencies from pre-requisite builds +.deps/ +.rw/ +.ro/ diff --git a/src/Metapackages/Directory.Build.props b/src/Metapackages/Directory.Build.props new file mode 100644 index 0000000000..9bcc46cef9 --- /dev/null +++ b/src/Metapackages/Directory.Build.props @@ -0,0 +1,21 @@ + + + + + + + + + Microsoft ASP.NET Core + https://github.com/aspnet/MetaPackages + git + $(MSBuildThisFileDirectory) + false + $(MSBuildThisFileDirectory)build\Key.snk + true + true + true + + diff --git a/src/Metapackages/Directory.Build.targets b/src/Metapackages/Directory.Build.targets new file mode 100644 index 0000000000..53b3f6e1da --- /dev/null +++ b/src/Metapackages/Directory.Build.targets @@ -0,0 +1,7 @@ + + + $(MicrosoftNETCoreApp20PackageVersion) + $(MicrosoftNETCoreApp21PackageVersion) + $(NETStandardLibrary20PackageVersion) + + diff --git a/src/Metapackages/MetaPackages.sln b/src/Metapackages/MetaPackages.sln new file mode 100644 index 0000000000..659427dfcb --- /dev/null +++ b/src/Metapackages/MetaPackages.sln @@ -0,0 +1,116 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27005.2 +MinimumVisualStudioVersion = 15.0.26730.03 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}" + ProjectSection(SolutionItems) = preProject + src\Directory.Build.props = src\Directory.Build.props + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore", "src\Microsoft.AspNetCore\Microsoft.AspNetCore.csproj", "{6F3D43F7-9546-4B41-AF04-CF4708B62051}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{97D53BEB-A511-4FBE-B784-AB407D9A219F}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + NuGet.config = NuGet.config + version.xml = version.xml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{F92CB7A1-C38E-408C-A7EC-A5C040D041E1}" + ProjectSection(SolutionItems) = preProject + build\dependencies.props = build\dependencies.props + build\repo.targets = build\repo.targets + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{192F583C-C4CA-43E5-B31C-D21B7806E274}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "samples\SampleApp\SampleApp.csproj", "{AF5BB04E-92F7-4737-8B98-F86F6244FAB2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{9E49B5B9-9E72-42FB-B684-90CA1B1BCF9C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.FunctionalTests", "test\Microsoft.AspNetCore.FunctionalTests\Microsoft.AspNetCore.FunctionalTests.csproj", "{C72A756A-D29D-44C7-83D4-821DBE82DBCA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestSites", "TestSites", "{EC22261D-0DE1-47DE-8F7C-072675D6F5B4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartRouteBuilderUrlApp", "test\TestSites\StartRouteBuilderUrlApp\StartRouteBuilderUrlApp.csproj", "{AB42054B-1801-4FEE-B5C3-8529C6D7BFDA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartWithIApplicationBuilderUrlApp", "test\TestSites\StartWithIApplicationBuilderUrlApp\StartWithIApplicationBuilderUrlApp.csproj", "{3A85FA52-F601-422E-A42E-9F187DB28492}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartRequestDelegateUrlApp", "test\TestSites\StartRequestDelegateUrlApp\StartRequestDelegateUrlApp.csproj", "{401C741B-6C7C-4E08-9F09-C3D43D22C0DE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateDefaultBuilderApp", "test\TestSites\CreateDefaultBuilderApp\CreateDefaultBuilderApp.csproj", "{79CF58CE-B020-45D8-BDB5-2D8036BEAD14}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyInjectionApp", "test\TestSites\DependencyInjectionApp\DependencyInjectionApp.csproj", "{65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateDefaultBuilderOfTApp", "test\TestSites\CreateDefaultBuilderOfTApp\CreateDefaultBuilderOfTApp.csproj", "{A922B5AC-836B-44F4-83F1-3CB9EB08A3F8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Tests", "test\Microsoft.AspNetCore.Tests\Microsoft.AspNetCore.Tests.csproj", "{BD08F027-3BB9-427B-9367-19534B7376B3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F3D43F7-9546-4B41-AF04-CF4708B62051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6F3D43F7-9546-4B41-AF04-CF4708B62051}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6F3D43F7-9546-4B41-AF04-CF4708B62051}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6F3D43F7-9546-4B41-AF04-CF4708B62051}.Release|Any CPU.Build.0 = Release|Any CPU + {AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF5BB04E-92F7-4737-8B98-F86F6244FAB2}.Release|Any CPU.Build.0 = Release|Any CPU + {C72A756A-D29D-44C7-83D4-821DBE82DBCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C72A756A-D29D-44C7-83D4-821DBE82DBCA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C72A756A-D29D-44C7-83D4-821DBE82DBCA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C72A756A-D29D-44C7-83D4-821DBE82DBCA}.Release|Any CPU.Build.0 = Release|Any CPU + {AB42054B-1801-4FEE-B5C3-8529C6D7BFDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB42054B-1801-4FEE-B5C3-8529C6D7BFDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB42054B-1801-4FEE-B5C3-8529C6D7BFDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB42054B-1801-4FEE-B5C3-8529C6D7BFDA}.Release|Any CPU.Build.0 = Release|Any CPU + {3A85FA52-F601-422E-A42E-9F187DB28492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A85FA52-F601-422E-A42E-9F187DB28492}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A85FA52-F601-422E-A42E-9F187DB28492}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A85FA52-F601-422E-A42E-9F187DB28492}.Release|Any CPU.Build.0 = Release|Any CPU + {401C741B-6C7C-4E08-9F09-C3D43D22C0DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {401C741B-6C7C-4E08-9F09-C3D43D22C0DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {401C741B-6C7C-4E08-9F09-C3D43D22C0DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {401C741B-6C7C-4E08-9F09-C3D43D22C0DE}.Release|Any CPU.Build.0 = Release|Any CPU + {79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79CF58CE-B020-45D8-BDB5-2D8036BEAD14}.Release|Any CPU.Build.0 = Release|Any CPU + {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Release|Any CPU.Build.0 = Release|Any CPU + {A922B5AC-836B-44F4-83F1-3CB9EB08A3F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A922B5AC-836B-44F4-83F1-3CB9EB08A3F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A922B5AC-836B-44F4-83F1-3CB9EB08A3F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A922B5AC-836B-44F4-83F1-3CB9EB08A3F8}.Release|Any CPU.Build.0 = Release|Any CPU + {BD08F027-3BB9-427B-9367-19534B7376B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD08F027-3BB9-427B-9367-19534B7376B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD08F027-3BB9-427B-9367-19534B7376B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD08F027-3BB9-427B-9367-19534B7376B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6F3D43F7-9546-4B41-AF04-CF4708B62051} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09} + {AF5BB04E-92F7-4737-8B98-F86F6244FAB2} = {192F583C-C4CA-43E5-B31C-D21B7806E274} + {C72A756A-D29D-44C7-83D4-821DBE82DBCA} = {9E49B5B9-9E72-42FB-B684-90CA1B1BCF9C} + {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} = {9E49B5B9-9E72-42FB-B684-90CA1B1BCF9C} + {AB42054B-1801-4FEE-B5C3-8529C6D7BFDA} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {3A85FA52-F601-422E-A42E-9F187DB28492} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {401C741B-6C7C-4E08-9F09-C3D43D22C0DE} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {79CF58CE-B020-45D8-BDB5-2D8036BEAD14} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {A922B5AC-836B-44F4-83F1-3CB9EB08A3F8} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {BD08F027-3BB9-427B-9367-19534B7376B3} = {9E49B5B9-9E72-42FB-B684-90CA1B1BCF9C} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A666E9B0-125B-4975-B35B-09A6D68A5047} + EndGlobalSection +EndGlobal diff --git a/src/Metapackages/NuGetPackageVerifier.json b/src/Metapackages/NuGetPackageVerifier.json new file mode 100644 index 0000000000..b153ab1515 --- /dev/null +++ b/src/Metapackages/NuGetPackageVerifier.json @@ -0,0 +1,7 @@ +{ + "Default": { + "rules": [ + "DefaultCompositeRule" + ] + } +} \ No newline at end of file diff --git a/src/Metapackages/README.md b/src/Metapackages/README.md new file mode 100644 index 0000000000..d35e5f0866 --- /dev/null +++ b/src/Metapackages/README.md @@ -0,0 +1,7 @@ +Meta packages +======== + +This repo contains NuGet meta packages that help quickly reference sets of common packages. + +This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo. + diff --git a/src/Metapackages/build/Key.snk b/src/Metapackages/build/Key.snk new file mode 100644 index 0000000000..e10e4889c1 Binary files /dev/null and b/src/Metapackages/build/Key.snk differ diff --git a/src/Metapackages/build/dependencies.props b/src/Metapackages/build/dependencies.props new file mode 100644 index 0000000000..bca0b5e999 --- /dev/null +++ b/src/Metapackages/build/dependencies.props @@ -0,0 +1,41 @@ + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + + 2.1.3-rtm-15802 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 0.5.1 + 2.1.2 + 2.1.2 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.1.1 + 2.0.0 + 2.1.2 + 15.6.1 + 4.7.49 + 2.0.3 + 2.3.1 + 2.4.0-beta.1.build3945 + + + + + + + + diff --git a/src/Metapackages/build/repo.props b/src/Metapackages/build/repo.props new file mode 100644 index 0000000000..dab1601c88 --- /dev/null +++ b/src/Metapackages/build/repo.props @@ -0,0 +1,15 @@ + + + + + + Internal.AspNetCore.Universe.Lineup + 2.1.0-rc1-* + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json + + + + + + + diff --git a/src/Metapackages/build/sources.props b/src/Metapackages/build/sources.props new file mode 100644 index 0000000000..9215df9751 --- /dev/null +++ b/src/Metapackages/build/sources.props @@ -0,0 +1,17 @@ + + + + + $(DotNetRestoreSources) + + $(RestoreSources); + https://dotnet.myget.org/F/dotnet-core/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; + + + $(RestoreSources); + https://api.nuget.org/v3/index.json; + + + diff --git a/src/Metapackages/samples/SampleApp/Program.cs b/src/Metapackages/samples/SampleApp/Program.cs new file mode 100644 index 0000000000..b5eb900273 --- /dev/null +++ b/src/Metapackages/samples/SampleApp/Program.cs @@ -0,0 +1,94 @@ +// 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 Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; + +namespace SampleApp +{ + public class Program + { + public static void Main(string[] args) + { + HelloWorld(); + + CustomUrl(); + + CustomRouter(); + + CustomApplicationBuilder(); + + StartupClass(args); + } + + private static void HelloWorld() + { + using (WebHost.Start(context => context.Response.WriteAsync("Hello, World!"))) + { + //host.WaitForShutdown(); // TODO: https://github.com/aspnet/Hosting/issues/1022 + Console.WriteLine("Running HelloWorld: Press any key to shutdown and start the next sample..."); + Console.ReadKey(); + } + } + + private static void CustomUrl() + { + // Changing the listening URL + using (WebHost.Start("http://localhost:8080", context => context.Response.WriteAsync("Hello, World!"))) + { + //host.WaitForShutdown(); // TODO: https://github.com/aspnet/Hosting/issues/1022 + Console.WriteLine("Running CustomUrl: Press any key to shutdown and start the next sample..."); + Console.ReadKey(); + } + } + + private static void CustomRouter() + { + // Using a router + using (WebHost.Start(router => router + .MapGet("hello/{name}", (req, res, data) => res.WriteAsync($"Hello, {data.Values["name"]}")) + .MapGet("goodbye/{name}", (req, res, data) => res.WriteAsync($"Goodbye, {data.Values["name"]}")) + .MapGet("throw/{message?}", (req, res, data) => throw new Exception((string)data.Values["message"] ?? "Uh oh!")) + .MapGet("{greeting}/{name}", (req, res, data) => res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}")) + .MapGet("", (req, res, data) => res.WriteAsync($"Hello, World!")))) + { + //host.WaitForShutdown(); // TODO: https://github.com/aspnet/Hosting/issues/1022 + Console.WriteLine("Running CustomRouter: Press any key to shutdown and start the next sample..."); + Console.ReadKey(); + } + } + + private static void CustomApplicationBuilder() + { + // Using a application builder + using (WebHost.StartWith(app => + { + app.UseStaticFiles(); + app.Run(async context => + { + await context.Response.WriteAsync("Hello, World!"); + }); + })) + { + //host.WaitForShutdown(); // TODO: https://github.com/aspnet/Hosting/issues/1022 + Console.WriteLine("Running CustomApplicationBuilder: Press any key to shutdown and start the next sample..."); + Console.ReadKey(); + } + } + + private static void StartupClass(string[] args) + { + // Using defaults with a Startup class + using (var host = WebHost.CreateDefaultBuilder(args) + .UseStartup() + .Build()) + { + host.Run(); + } + } + } +} diff --git a/src/Metapackages/samples/SampleApp/Properties/launchSettings.json b/src/Metapackages/samples/SampleApp/Properties/launchSettings.json new file mode 100644 index 0000000000..f0370cf22b --- /dev/null +++ b/src/Metapackages/samples/SampleApp/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:53432/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "SampleApp": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:53433" + } + } +} diff --git a/src/Metapackages/samples/SampleApp/SampleApp.csproj b/src/Metapackages/samples/SampleApp/SampleApp.csproj new file mode 100644 index 0000000000..622f64cc4c --- /dev/null +++ b/src/Metapackages/samples/SampleApp/SampleApp.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.1;net461 + aspnetcore-MetaPackagesSampleApp-20170406180413 + + + + + + + + + + + diff --git a/src/Metapackages/samples/SampleApp/Startup.cs b/src/Metapackages/samples/SampleApp/Startup.cs new file mode 100644 index 0000000000..287fffd27a --- /dev/null +++ b/src/Metapackages/samples/SampleApp/Startup.cs @@ -0,0 +1,26 @@ +// 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.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace SampleApp +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + + } + + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + app.Run(async (context) => + { + await context.Response.WriteAsync($"Hello from {nameof(Startup)}!"); + }); + } + } +} diff --git a/src/Metapackages/samples/SampleApp/appsettings.json b/src/Metapackages/samples/SampleApp/appsettings.json new file mode 100644 index 0000000000..6a1c35ebcf --- /dev/null +++ b/src/Metapackages/samples/SampleApp/appsettings.json @@ -0,0 +1,50 @@ +{ + "AllowedHosts": "example.com;localhost", + "Kestrel": { + "EndPoints": { + "Http": { + "Url": "http://localhost:5005" + } + + // To enable HTTPS using a certificate file, set the path to a .pfx file in + // the "Path" property below and configure the password in user secrets. + // The "Password" property should be set in user secrets. + //"HttpsInlineCertFile": { + // "Url": "http://localhost:5005" + // "Certificate": { + // "Path": "", + // "Password: "" + // } + //}, + + //"HttpsInlineCertStore": { + // "Url": "http://localhost:5005" + // "Certificate": { + // "Subject": "", + // "Store": "", + // "Location": "", + // "AllowInvalid": "" // Set to "true" to allow invalid certificates (e.g. expired) + // } + //}, + + // This uses the cert defined under Certificates/Default or the development cert. + //"HttpsDefaultCert": { + // "Url": "http://localhost:5005" + //} + } + }, + "Certificates": { + //"Default": { + // "Path": "", + // "Password": "" + //}, + + // From cert store: + //"Default": { + // "Subject": "", + // "Store": "", + // "Location": "", + // "AllowInvalid": "" // Set to "true" to allow invalid certificates (e.g. expired certificates) + //} + } +} diff --git a/src/Metapackages/samples/SampleApp/wwwroot/htmlpage.html b/src/Metapackages/samples/SampleApp/wwwroot/htmlpage.html new file mode 100644 index 0000000000..ab3af6d3f7 --- /dev/null +++ b/src/Metapackages/samples/SampleApp/wwwroot/htmlpage.html @@ -0,0 +1,12 @@ + + + + + + + + + + A static HTML file. + + \ No newline at end of file diff --git a/src/Metapackages/src/Directory.Build.props b/src/Metapackages/src/Directory.Build.props new file mode 100644 index 0000000000..410f24daa9 --- /dev/null +++ b/src/Metapackages/src/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Metapackages/src/Microsoft.AspNetCore/HostFilteringStartupFilter.cs b/src/Metapackages/src/Microsoft.AspNetCore/HostFilteringStartupFilter.cs new file mode 100644 index 0000000000..56c6d9c34f --- /dev/null +++ b/src/Metapackages/src/Microsoft.AspNetCore/HostFilteringStartupFilter.cs @@ -0,0 +1,21 @@ +// 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 Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; + +namespace Microsoft.AspNetCore +{ + internal class HostFilteringStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return app => + { + app.UseHostFiltering(); + next(app); + }; + } + } +} \ No newline at end of file diff --git a/src/Metapackages/src/Microsoft.AspNetCore/Microsoft.AspNetCore.csproj b/src/Metapackages/src/Microsoft.AspNetCore/Microsoft.AspNetCore.csproj new file mode 100644 index 0000000000..e52a4f74ed --- /dev/null +++ b/src/Metapackages/src/Microsoft.AspNetCore/Microsoft.AspNetCore.csproj @@ -0,0 +1,30 @@ + + + + netstandard2.0 + aspnetcore + Microsoft.AspNetCore + true + false + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Metapackages/src/Microsoft.AspNetCore/WebHost.cs b/src/Metapackages/src/Microsoft.AspNetCore/WebHost.cs new file mode 100644 index 0000000000..8c49d2eb23 --- /dev/null +++ b/src/Metapackages/src/Microsoft.AspNetCore/WebHost.cs @@ -0,0 +1,241 @@ +// 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.IO; +using System.Reflection; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.HostFiltering; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore +{ + /// + /// Provides convenience methods for creating instances of and with pre-configured defaults. + /// + public static class WebHost + { + /// + /// Initializes and starts a new with pre-configured defaults. + /// See for details. + /// + /// A delegate that handles requests to the application. + /// A started that hosts the application. + public static IWebHost Start(RequestDelegate app) => + Start(url: null, app: app); + + /// + /// Initializes and starts a new with pre-configured defaults. + /// See for details. + /// + /// The URL the hosted application will listen on. + /// A delegate that handles requests to the application. + /// A started that hosts the application. + public static IWebHost Start(string url, RequestDelegate app) + { + var startupAssemblyName = app.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name; + return StartWith(url: url, configureServices: null, app: appBuilder => appBuilder.Run(app), applicationName: startupAssemblyName); + } + + /// + /// Initializes and starts a new with pre-configured defaults. + /// See for details. + /// + /// A delegate that configures the router for handling requests to the application. + /// A started that hosts the application. + public static IWebHost Start(Action routeBuilder) => + Start(url: null, routeBuilder: routeBuilder); + + /// + /// Initializes and starts a new with pre-configured defaults. + /// See for details. + /// + /// The URL the hosted application will listen on. + /// A delegate that configures the router for handling requests to the application. + /// A started that hosts the application. + public static IWebHost Start(string url, Action routeBuilder) + { + var startupAssemblyName = routeBuilder.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name; + return StartWith(url, services => services.AddRouting(), appBuilder => appBuilder.UseRouter(routeBuilder), applicationName: startupAssemblyName); + } + + /// + /// Initializes and starts a new with pre-configured defaults. + /// See for details. + /// + /// The delegate that configures the . + /// A started that hosts the application. + public static IWebHost StartWith(Action app) => + StartWith(url: null, app: app); + + /// + /// Initializes and starts a new with pre-configured defaults. + /// See for details. + /// + /// The URL the hosted application will listen on. + /// The delegate that configures the . + /// A started that hosts the application. + public static IWebHost StartWith(string url, Action app) => + StartWith(url: url, configureServices: null, app: app, applicationName: null); + + private static IWebHost StartWith(string url, Action configureServices, Action app, string applicationName) + { + var builder = CreateDefaultBuilder(); + + if (!string.IsNullOrEmpty(url)) + { + builder.UseUrls(url); + } + + if (configureServices != null) + { + builder.ConfigureServices(configureServices); + } + + builder.Configure(app); + + if (!string.IsNullOrEmpty(applicationName)) + { + builder.UseSetting(WebHostDefaults.ApplicationKey, applicationName); + } + + var host = builder.Build(); + + host.Start(); + + return host; + } + + /// + /// Initializes a new instance of the class with pre-configured defaults. + /// + /// + /// The following defaults are applied to the returned : + /// use Kestrel as the web server and configure it using the application's configuration providers, + /// set the to the result of , + /// load from 'appsettings.json' and 'appsettings.[].json', + /// load from User Secrets when is 'Development' using the entry assembly, + /// load from environment variables, + /// configures the to log to the console and debug output, + /// enables IIS integration, + /// and enables the ability for frameworks to bind their options to their default configuration sections. + /// + /// The initialized . + public static IWebHostBuilder CreateDefaultBuilder() => + CreateDefaultBuilder(args: null); + + /// + /// Initializes a new instance of the class with pre-configured defaults. + /// + /// + /// The following defaults are applied to the returned : + /// use Kestrel as the web server and configure it using the application's configuration providers, + /// set the to the result of , + /// load from 'appsettings.json' and 'appsettings.[].json', + /// load from User Secrets when is 'Development' using the entry assembly, + /// load from environment variables, + /// load from supplied command line args, + /// configures the to log to the console and debug output, + /// enables IIS integration, + /// and enables the ability for frameworks to bind their options to their default configuration sections. + /// + /// The command line args. + /// The initialized . + public static IWebHostBuilder CreateDefaultBuilder(string[] args) + { + var builder = new WebHostBuilder() + .UseKestrel((builderContext, options) => + { + options.Configure(builderContext.Configuration.GetSection("Kestrel")); + }) + .UseContentRoot(Directory.GetCurrentDirectory()) + .ConfigureAppConfiguration((hostingContext, config) => + { + var env = hostingContext.HostingEnvironment; + + config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); + + if (env.IsDevelopment()) + { + var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); + if (appAssembly != null) + { + config.AddUserSecrets(appAssembly, optional: true); + } + } + + config.AddEnvironmentVariables(); + + if (args != null) + { + config.AddCommandLine(args); + } + }) + .ConfigureLogging((hostingContext, logging) => + { + logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); + logging.AddConsole(); + logging.AddDebug(); + }) + .ConfigureServices((hostingContext, services) => + { + // Fallback + services.PostConfigure(options => + { + if (options.AllowedHosts == null || options.AllowedHosts.Count == 0) + { + // "AllowedHosts": "localhost;127.0.0.1;[::1]" + var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + // Fall back to "*" to disable. + options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" }); + } + }); + // Change notification + services.AddSingleton>( + new ConfigurationChangeTokenSource(hostingContext.Configuration)); + + services.AddTransient(); + }) + .UseIISIntegration() + .UseDefaultServiceProvider((context, options) => + { + options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); + }); + + if (args != null) + { + builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build()); + } + + return builder; + } + + /// + /// Initializes a new instance of the class with pre-configured defaults using typed Startup. + /// + /// + /// The following defaults are applied to the returned : + /// use Kestrel as the web server and configure it using the application's configuration providers, + /// set the to the result of , + /// load from 'appsettings.json' and 'appsettings.[].json', + /// load from User Secrets when is 'Development' using the entry assembly, + /// load from environment variables, + /// load from supplied command line args, + /// configures the to log to the console and debug output, + /// enables IIS integration, + /// enables the ability for frameworks to bind their options to their default configuration sections. + /// + /// The type containing the startup methods for the application. + /// The command line args. + /// The initialized . + public static IWebHostBuilder CreateDefaultBuilder(string[] args) where TStartup : class => + CreateDefaultBuilder(args).UseStartup(); + } +} diff --git a/src/Metapackages/src/Microsoft.AspNetCore/baseline.netcore.json b/src/Metapackages/src/Microsoft.AspNetCore/baseline.netcore.json new file mode 100644 index 0000000000..482a58e908 --- /dev/null +++ b/src/Metapackages/src/Microsoft.AspNetCore/baseline.netcore.json @@ -0,0 +1,136 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.AspNetCore.WebHost", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Start", + "Parameters": [ + { + "Name": "app", + "Type": "Microsoft.AspNetCore.Http.RequestDelegate" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Start", + "Parameters": [ + { + "Name": "url", + "Type": "System.String" + }, + { + "Name": "app", + "Type": "Microsoft.AspNetCore.Http.RequestDelegate" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Start", + "Parameters": [ + { + "Name": "routeBuilder", + "Type": "System.Action" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Start", + "Parameters": [ + { + "Name": "url", + "Type": "System.String" + }, + { + "Name": "routeBuilder", + "Type": "System.Action" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "StartWith", + "Parameters": [ + { + "Name": "app", + "Type": "System.Action" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "StartWith", + "Parameters": [ + { + "Name": "url", + "Type": "System.String" + }, + { + "Name": "app", + "Type": "System.Action" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHost", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "CreateDefaultBuilder", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "CreateDefaultBuilder", + "Parameters": [ + { + "Name": "args", + "Type": "System.String[]" + } + ], + "ReturnType": "Microsoft.AspNetCore.Hosting.IWebHostBuilder", + "Static": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + } + ] +} \ No newline at end of file diff --git a/src/Metapackages/test/Directory.Build.props b/src/Metapackages/test/Directory.Build.props new file mode 100644 index 0000000000..2a4205c758 --- /dev/null +++ b/src/Metapackages/test/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + netcoreapp2.1 + $(DeveloperBuildTestTfms) + netcoreapp2.1;netcoreapp2.0 + $(StandardTestTfms);net461 + + + + + + diff --git a/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj b/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj new file mode 100644 index 0000000000..d4a5bbdf12 --- /dev/null +++ b/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj @@ -0,0 +1,28 @@ + + + + $(StandardTestTfms) + + + true + + + + + + + + + + + + + + + + + + diff --git a/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs b/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs new file mode 100644 index 0000000000..b882205779 --- /dev/null +++ b/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs @@ -0,0 +1,238 @@ +// 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.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Microsoft.AspNetCore.Tests +{ + public class WebHostFunctionalTests : LoggedTest + { + private readonly string _testSitesPath; + + public WebHostFunctionalTests(ITestOutputHelper output) : base(output) + { + _testSitesPath = GetTestSitesPath(); + } + + [Fact] + public async Task Start_RequestDelegate_Url() + { + await ExecuteStartOrStartWithTest(deploymentResult => deploymentResult.HttpClient.GetAsync(string.Empty), "StartRequestDelegateUrlApp"); + } + + [Fact] + public async Task Start_RouteBuilder_Url() + { + await ExecuteStartOrStartWithTest(deploymentResult => deploymentResult.HttpClient.GetAsync("/route"), "StartRouteBuilderUrlApp"); + } + + [Fact] + public async Task StartWith_IApplicationBuilder_Url() + { + await ExecuteStartOrStartWithTest(deploymentResult => deploymentResult.HttpClient.GetAsync(string.Empty), "StartWithIApplicationBuilderUrlApp"); + } + + [Fact] + public async Task CreateDefaultBuilder_InitializeWithDefaults() + { + var applicationName = "CreateDefaultBuilderApp"; + await ExecuteTestApp(applicationName, async (deploymentResult, logger) => + { + var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken); + + var responseText = await response.Content.ReadAsStringAsync(); + try + { + // Assert server is Kestrel + Assert.Equal("Kestrel", response.Headers.Server.ToString()); + // Set from default config + Assert.Equal("http://localhost:5002/", deploymentResult.ApplicationBaseUri); + // The application name will be sent in response when all asserts succeed in the test app. + Assert.Equal(applicationName, responseText); + } + catch (XunitException) + { + logger.LogWarning(response.ToString()); + logger.LogWarning(responseText); + throw; + } + }, setTestEnvVars: true); + } + + [Fact] + public async Task CreateDefaultBuilderOfT_InitializeWithDefaults() + { + var applicationName = "CreateDefaultBuilderOfTApp"; + await ExecuteTestApp(applicationName, async (deploymentResult, logger) => + { + var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken); + + var responseText = await response.Content.ReadAsStringAsync(); + try + { + // Assert server is Kestrel + Assert.Equal("Kestrel", response.Headers.Server.ToString()); + // Set from default config + Assert.Equal("http://localhost:5002/", deploymentResult.ApplicationBaseUri); + // The application name will be sent in response when all asserts succeed in the test app. + Assert.Equal(applicationName, responseText); + } + catch (XunitException) + { + logger.LogWarning(response.ToString()); + logger.LogWarning(responseText); + throw; + } + }, setTestEnvVars: true); + } + + [Theory] + [InlineData("Development", "InvalidOperationException: Cannot consume scoped service")] + [InlineData("Production", "Success")] + public async Task CreateDefaultBuilder_InitializesDependencyInjectionSettingsBasedOnEnv(string environment, string expected) + { + var applicationName = "DependencyInjectionApp"; + await ExecuteTestApp(applicationName, async (deploymentResult, logger) => + { + var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken); + var responseText = await response.Content.ReadAsStringAsync(); + try + { + // Assert UseDeveloperExceptionPage is called in WebHostStartupFilter. + Assert.Contains(expected, responseText); + } + catch (XunitException) + { + logger.LogWarning(response.ToString()); + logger.LogWarning(responseText); + throw; + } + }, setTestEnvVars: true, environment: environment); + } + + [Fact] + public void LoggingConfigurationSectionPassedToLoggerByDefault() + { + try + { + File.WriteAllText("appsettings.json", @" +{ + ""Logging"": { + ""LogLevel"": { + ""Default"": ""Warning"" + } + } +} +"); + using (var webHost = WebHost.Start(context => context.Response.WriteAsync("Hello, World!"))) + { + var factory = (ILoggerFactory)webHost.Services.GetService(typeof(ILoggerFactory)); + var logger = factory.CreateLogger("Test"); + + logger.Log(LogLevel.Information, 0, "Message", null, (s, e) => + { + Assert.True(false); + return string.Empty; + }); + + var logWritten = false; + logger.Log(LogLevel.Warning, 0, "Message", null, (s, e) => + { + logWritten = true; + return string.Empty; + }); + + Assert.True(logWritten); + } + } + finally + { + File.Delete("appsettings.json"); + } + } + + private async Task ExecuteStartOrStartWithTest(Func> getResponse, string applicationName) + { + await ExecuteTestApp(applicationName, async (deploymentResult, logger) => + { + var response = await RetryHelper.RetryRequest(() => getResponse(deploymentResult), logger, deploymentResult.HostShutdownToken); + + var responseText = await response.Content.ReadAsStringAsync(); + try + { + Assert.Equal(applicationName, responseText); + } + catch (XunitException) + { + logger.LogWarning(response.ToString()); + logger.LogWarning(responseText); + throw; + } + }); + } + + private async Task ExecuteTestApp(string applicationName, + Func assertAction, + bool setTestEnvVars = false, + string environment = "Development") + { + using (StartLog(out var loggerFactory, applicationName)) + { + var logger = loggerFactory.CreateLogger(nameof(WebHost.Start)); + var deploymentParameters = new DeploymentParameters(Path.Combine(_testSitesPath, applicationName), ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64); + + if (setTestEnvVars) + { + deploymentParameters.EnvironmentVariables.Add(new KeyValuePair("aspnetcore_environment", environment)); + deploymentParameters.EnvironmentVariables.Add(new KeyValuePair("envKey", "envValue")); + } + + using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory)) + { + var deploymentResult = await deployer.DeployAsync(); + + await assertAction(deploymentResult, logger); + } + } + } + + private static string GetTestSitesPath() + { + var applicationBasePath = AppContext.BaseDirectory; + + var directoryInfo = new DirectoryInfo(applicationBasePath); + do + { + var solutionFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, "MetaPackages.sln")); + if (solutionFileInfo.Exists) + { + return Path.GetFullPath(Path.Combine(directoryInfo.FullName, "test", "TestSites")); + } + + directoryInfo = directoryInfo.Parent; + } + while (directoryInfo.Parent != null); + + throw new Exception($"Solution root could not be found using {applicationBasePath}"); + } + + private static int GetWebHostPort(IWebHost webHost) + => webHost.ServerFeatures.Get().Addresses + .Select(serverAddress => new Uri(serverAddress).Port) + .FirstOrDefault(); + } +} diff --git a/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/testCert.pfx b/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/testCert.pfx new file mode 100644 index 0000000000..7118908c2d Binary files /dev/null and b/src/Metapackages/test/Microsoft.AspNetCore.FunctionalTests/testCert.pfx differ diff --git a/src/Metapackages/test/Microsoft.AspNetCore.Tests/Microsoft.AspNetCore.Tests.csproj b/src/Metapackages/test/Microsoft.AspNetCore.Tests/Microsoft.AspNetCore.Tests.csproj new file mode 100644 index 0000000000..1b8156a1ca --- /dev/null +++ b/src/Metapackages/test/Microsoft.AspNetCore.Tests/Microsoft.AspNetCore.Tests.csproj @@ -0,0 +1,18 @@ + + + + $(StandardTestTfms) + + + + + + + + + + + + + + diff --git a/src/Metapackages/test/Microsoft.AspNetCore.Tests/WebHostTests.cs b/src/Metapackages/test/Microsoft.AspNetCore.Tests/WebHostTests.cs new file mode 100644 index 0000000000..e076f0f19c --- /dev/null +++ b/src/Metapackages/test/Microsoft.AspNetCore.Tests/WebHostTests.cs @@ -0,0 +1,69 @@ +// 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.Threading; +using Microsoft.AspNetCore.HostFiltering; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Microsoft.AspNetCore.Tests +{ + public class WebHostTests + { + [Fact] + public void WebHostConfiguration_IncludesCommandLineArguments() + { + var builder = WebHost.CreateDefaultBuilder(new string[] { "--urls", "http://localhost:5001" }); + Assert.Equal("http://localhost:5001", builder.GetSetting(WebHostDefaults.ServerUrlsKey)); + } + + [Fact] + public void WebHostConfiguration_HostFilterOptionsAreReloadable() + { + var host = WebHost.CreateDefaultBuilder() + .Configure(app => { }) + .ConfigureAppConfiguration(configBuilder => + { + configBuilder.Add(new ReloadableMemorySource()); + }).Build(); + var config = host.Services.GetRequiredService(); + var monitor = host.Services.GetRequiredService>(); + var options = monitor.CurrentValue; + + Assert.Contains("*", options.AllowedHosts); + + var changed = new ManualResetEvent(false); + monitor.OnChange(newOptions => + { + changed.Set(); + }); + + config["AllowedHosts"] = "NewHost"; + + Assert.True(changed.WaitOne(TimeSpan.FromSeconds(10))); + options = monitor.CurrentValue; + Assert.Contains("NewHost", options.AllowedHosts); + } + + private class ReloadableMemorySource : IConfigurationSource + { + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + return new ReloadableMemoryProvider(); + } + } + + private class ReloadableMemoryProvider : ConfigurationProvider + { + public override void Set(string key, string value) + { + base.Set(key, value); + OnReload(); + } + } + } +} diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/CreateDefaultBuilderApp.csproj b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/CreateDefaultBuilderApp.csproj new file mode 100644 index 0000000000..7b43959e2f --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/CreateDefaultBuilderApp.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.0 + aspnetcore-CreateDefaultBuilder-20170424224131 + + + + + + + diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/Program.cs b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/Program.cs new file mode 100644 index 0000000000..e8b91c67c0 --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/Program.cs @@ -0,0 +1,76 @@ +// 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.IO; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace CreateDefaultBuilderApp +{ + public class Program + { + static void Main(string[] args) + { + string responseMessage = string.Empty; + + WebHost.CreateDefaultBuilder(new[] { "--cliKey", "cliValue" }) + .ConfigureServices((context, services) => + { + responseMessage = GetResponseMessage(context, services); + }) + .Configure(app => + { + app.Run(context => + { + return context.Response.WriteAsync(responseMessage); + }); + }) + .Build().Run(); + } + + private static string GetResponseMessage(WebHostBuilderContext context, IServiceCollection services) + { + // Verify ContentRootPath set + if (!string.Equals(Directory.GetCurrentDirectory(), context.HostingEnvironment.ContentRootPath, StringComparison.Ordinal)) + { + return $"Current directory incorrect. Expected: {Directory.GetCurrentDirectory()} Actual: {context.HostingEnvironment.ContentRootPath}"; + } + + // Verify appsettings.json loaded + if (!string.Equals("settingsValue", context.Configuration["settingsKey"], StringComparison.Ordinal)) + { + return $"appsettings.json not loaded into Configuration."; + } + + // Verify appsettings.environment.json loaded + if (!string.Equals("devSettingsValue", context.Configuration["devSettingsKey"], StringComparison.Ordinal)) + { + return $"appsettings.{context.HostingEnvironment.EnvironmentName}.json not loaded into Configuration."; + } + + // TODO: Verify UserSecrets loaded + + // Verify environment variables loaded + if (!string.Equals("envValue", context.Configuration["envKey"], StringComparison.Ordinal)) + { + return $"Environment variables not loaded into Configuration."; + } + + // Verify command line arguments loaded + if (!string.Equals("cliValue", context.Configuration["cliKey"], StringComparison.Ordinal)) + { + return $"Command line arguments not loaded into Configuration."; + } + + // TODO: Verify AddConsole called + // TODO: Verify AddDebug called + // TODO: Verify UseIISIntegration called + + return context.HostingEnvironment.ApplicationName; + } + } +} \ No newline at end of file diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/appsettings.Development.json b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/appsettings.Development.json new file mode 100644 index 0000000000..d2ccc50d64 --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/appsettings.Development.json @@ -0,0 +1,3 @@ +{ + "devSettingsKey": "devSettingsValue" +} diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/appsettings.json b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/appsettings.json new file mode 100644 index 0000000000..393b080efb --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderApp/appsettings.json @@ -0,0 +1,10 @@ +{ + "settingsKey": "settingsValue", + "Kestrel": { + "Endpoints": { + "HTTP": { + "Url": "http://localhost:5002" + } + } + } +} diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/CreateDefaultBuilderOfTApp.csproj b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/CreateDefaultBuilderOfTApp.csproj new file mode 100644 index 0000000000..c73ee499ff --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/CreateDefaultBuilderOfTApp.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.0 + aspnetcore-CreateDefaultBuilderOfT-20170424224131 + + + + + + + diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/Program.cs b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/Program.cs new file mode 100644 index 0000000000..fbdc90efee --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/Program.cs @@ -0,0 +1,14 @@ +// 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.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; + +namespace CreateDefaultBuilderOfTApp +{ + public class Program + { + static void Main(string[] args) => WebHost.CreateDefaultBuilder(new[] { "--cliKey", "cliValue" }) .Build().Run(); + } +} \ No newline at end of file diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/Startup.cs b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/Startup.cs new file mode 100644 index 0000000000..2bfb0cdfe9 --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/Startup.cs @@ -0,0 +1,74 @@ +// 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.IO; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.HostFiltering; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace CreateDefaultBuilderOfTApp +{ + class Startup + { + public void Configure(IApplicationBuilder app, WebHostBuilderContext webHostBuilderContext) + { + app.Run(context => + { + var message = GetResponseMessage(webHostBuilderContext, app.ApplicationServices.GetRequiredService>()); + return context.Response.WriteAsync(message); + }); + } + + private static string GetResponseMessage(WebHostBuilderContext context, IOptions hostFilteringOptions) + { + // Verify ContentRootPath set + if (!string.Equals(Directory.GetCurrentDirectory(), context.HostingEnvironment.ContentRootPath, StringComparison.Ordinal)) + { + return $"Current directory incorrect. Expected: {Directory.GetCurrentDirectory()} Actual: {context.HostingEnvironment.ContentRootPath}"; + } + + // Verify appsettings.json loaded + if (!string.Equals("settingsValue", context.Configuration["settingsKey"], StringComparison.Ordinal)) + { + return $"appsettings.json not loaded into Configuration."; + } + + // Verify appsettings.environment.json loaded + if (!string.Equals("devSettingsValue", context.Configuration["devSettingsKey"], StringComparison.Ordinal)) + { + return $"appsettings.{context.HostingEnvironment.EnvironmentName}.json not loaded into Configuration."; + } + + // TODO: Verify UserSecrets loaded + + // Verify environment variables loaded + if (!string.Equals("envValue", context.Configuration["envKey"], StringComparison.Ordinal)) + { + return $"Environment variables not loaded into Configuration."; + } + + // Verify command line arguments loaded + if (!string.Equals("cliValue", context.Configuration["cliKey"], StringComparison.Ordinal)) + { + return $"Command line arguments not loaded into Configuration."; + } + + // Verify allowed hosts were loaded + var hosts = string.Join(',', hostFilteringOptions.Value.AllowedHosts); + if (!string.Equals("example.com,localhost", hosts, StringComparison.Ordinal)) + { + return $"AllowedHosts not loaded into Options."; + } + + // TODO: Verify AddConsole called + // TODO: Verify AddDebug called + // TODO: Verify UseIISIntegration called + + return context.HostingEnvironment.ApplicationName; + } + } +} diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/appsettings.Development.json b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/appsettings.Development.json new file mode 100644 index 0000000000..d2ccc50d64 --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/appsettings.Development.json @@ -0,0 +1,3 @@ +{ + "devSettingsKey": "devSettingsValue" +} diff --git a/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/appsettings.json b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/appsettings.json new file mode 100644 index 0000000000..27eb1aaf44 --- /dev/null +++ b/src/Metapackages/test/TestSites/CreateDefaultBuilderOfTApp/appsettings.json @@ -0,0 +1,11 @@ +{ + "settingsKey": "settingsValue", + "AllowedHosts": "example.com;localhost", + "Kestrel": { + "Endpoints": { + "HTTP": { + "Url": "http://localhost:5002" + } + } + } +} diff --git a/src/Metapackages/test/TestSites/DependencyInjectionApp/DependencyInjectionApp.csproj b/src/Metapackages/test/TestSites/DependencyInjectionApp/DependencyInjectionApp.csproj new file mode 100644 index 0000000000..7930c4a822 --- /dev/null +++ b/src/Metapackages/test/TestSites/DependencyInjectionApp/DependencyInjectionApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + diff --git a/src/Metapackages/test/TestSites/DependencyInjectionApp/Program.cs b/src/Metapackages/test/TestSites/DependencyInjectionApp/Program.cs new file mode 100644 index 0000000000..6e4850002b --- /dev/null +++ b/src/Metapackages/test/TestSites/DependencyInjectionApp/Program.cs @@ -0,0 +1,68 @@ +// 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.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Logging.Console; +using Microsoft.Extensions.Logging.Debug; + +namespace CreateDefaultBuilderApp +{ + public class Program + { + static void Main(string[] args) + { + WebHost.CreateDefaultBuilder() + .UseUrls("http://localhost:5002") + .ConfigureServices((context, services) => + { + services.AddSingleton(typeof(IService<>), typeof(Service<>)); + services.AddScoped(); + }) + .Configure(app => + { + app.Run(context => + { + try + { + context.RequestServices.GetService>(); + return context.Response.WriteAsync("Success"); + } + catch (Exception ex) + { + return context.Response.WriteAsync(ex.ToString()); + } + }); + }) + .Build().Run(); + } + + interface IService + { + } + + interface IAnotherService + { + } + + class Service: IService + { + public Service(T t) + { + } + } + + class AnotherService: IAnotherService + { + } + } +} diff --git a/src/Metapackages/test/TestSites/StartRequestDelegateUrlApp/Program.cs b/src/Metapackages/test/TestSites/StartRequestDelegateUrlApp/Program.cs new file mode 100644 index 0000000000..351f870b56 --- /dev/null +++ b/src/Metapackages/test/TestSites/StartRequestDelegateUrlApp/Program.cs @@ -0,0 +1,43 @@ +// 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.Threading; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace StartRequestDelegateUrlApp +{ + public class Program + { + static void Main(string[] args) + { + var messageSent = new ManualResetEventSlim(false); + + using (var host = WebHost.Start("http://127.0.0.1:0", async context => + { + // Respond with the ApplicationName. + var env = context.RequestServices.GetRequiredService(); + await context.Response.WriteAsync(env.ApplicationName); + messageSent.Set(); + })) + { + // Need these for test deployer to consider host deployment successful + // The address written here is used by the client to send requests + var addresses = host.ServerFeatures.Get().Addresses; + foreach (var address in addresses) + { + Console.WriteLine($"Now listening on: {address}"); + } + Console.WriteLine("Application started. Press Ctrl+C to shut down."); + + // Shut down after message sent or timeout + messageSent.Wait(TimeSpan.FromSeconds(30)); + + } + } + } +} \ No newline at end of file diff --git a/src/Metapackages/test/TestSites/StartRequestDelegateUrlApp/StartRequestDelegateUrlApp.csproj b/src/Metapackages/test/TestSites/StartRequestDelegateUrlApp/StartRequestDelegateUrlApp.csproj new file mode 100644 index 0000000000..7930c4a822 --- /dev/null +++ b/src/Metapackages/test/TestSites/StartRequestDelegateUrlApp/StartRequestDelegateUrlApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + diff --git a/src/Metapackages/test/TestSites/StartRouteBuilderUrlApp/Program.cs b/src/Metapackages/test/TestSites/StartRouteBuilderUrlApp/Program.cs new file mode 100644 index 0000000000..5aa13ea396 --- /dev/null +++ b/src/Metapackages/test/TestSites/StartRouteBuilderUrlApp/Program.cs @@ -0,0 +1,43 @@ +// 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.Threading; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; + +namespace StartRequestDelegateUrlApp +{ + public class Program + { + static void Main(string[] args) + { + var messageSent = new ManualResetEventSlim(false); + + using (var host = WebHost.Start("http://127.0.0.1:0", router => + router.MapGet("route", async (req, res, data) => + { + var env = req.HttpContext.RequestServices.GetRequiredService(); + await res.WriteAsync(env.ApplicationName); + messageSent.Set(); + }))) + { + // Need these for test deployer to consider host deployment successful + // The address written here is used by the client to send requests + var addresses = host.ServerFeatures.Get().Addresses; + foreach (var address in addresses) + { + Console.WriteLine($"Now listening on: {address}"); + } + Console.WriteLine("Application started. Press Ctrl+C to shut down."); + + // Shut down after message sent or timeout + messageSent.Wait(TimeSpan.FromSeconds(30)); + } + } + } +} \ No newline at end of file diff --git a/src/Metapackages/test/TestSites/StartRouteBuilderUrlApp/StartRouteBuilderUrlApp.csproj b/src/Metapackages/test/TestSites/StartRouteBuilderUrlApp/StartRouteBuilderUrlApp.csproj new file mode 100644 index 0000000000..7930c4a822 --- /dev/null +++ b/src/Metapackages/test/TestSites/StartRouteBuilderUrlApp/StartRouteBuilderUrlApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + diff --git a/src/Metapackages/test/TestSites/StartWithIApplicationBuilderUrlApp/Program.cs b/src/Metapackages/test/TestSites/StartWithIApplicationBuilderUrlApp/Program.cs new file mode 100644 index 0000000000..f904dcff57 --- /dev/null +++ b/src/Metapackages/test/TestSites/StartWithIApplicationBuilderUrlApp/Program.cs @@ -0,0 +1,45 @@ +// 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.Threading; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace StartWithIApplicationBuilderUrlApp +{ + public class Program + { + static void Main(string[] args) + { + var messageSent = new ManualResetEventSlim(false); + + using (var host = WebHost.StartWith("http://127.0.0.1:0", app => + { + app.Run(async context => + { + var env = context.RequestServices.GetRequiredService(); + await context.Response.WriteAsync(env.ApplicationName); + messageSent.Set(); + }); + })) + { + // Need these for test deployer to consider host deployment successful + // The address written here is used by the client to send requests + var addresses = host.ServerFeatures.Get().Addresses; + foreach (var address in addresses) + { + Console.WriteLine($"Now listening on: {address}"); + } + Console.WriteLine("Application started. Press Ctrl+C to shut down."); + + // Shut down after message sent or timeout + messageSent.Wait(TimeSpan.FromSeconds(30)); + } + } + } +} \ No newline at end of file diff --git a/src/Metapackages/test/TestSites/StartWithIApplicationBuilderUrlApp/StartWithIApplicationBuilderUrlApp.csproj b/src/Metapackages/test/TestSites/StartWithIApplicationBuilderUrlApp/StartWithIApplicationBuilderUrlApp.csproj new file mode 100644 index 0000000000..7930c4a822 --- /dev/null +++ b/src/Metapackages/test/TestSites/StartWithIApplicationBuilderUrlApp/StartWithIApplicationBuilderUrlApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0 + + + + + + + diff --git a/src/Metapackages/version.props b/src/Metapackages/version.props new file mode 100644 index 0000000000..c5a1f7a6cf --- /dev/null +++ b/src/Metapackages/version.props @@ -0,0 +1,12 @@ + + + 2.1.7 + servicing + $(VersionPrefix) + $(VersionPrefix)-$(VersionSuffix)-final + t000 + a- + $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) + $(VersionSuffix)-$(BuildNumber) + +