From 7fbedc602cd1b600668e9ac54dc2d0322f09b1c4 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 31 Oct 2018 16:26:41 -0700 Subject: [PATCH] Move 22 into subfolder --- .appveyor.yml | 27 - .editorconfig | 24 - .gitattributes | 53 -- .gitmodules | 3 - .vsts-pipelines/builds/ci-internal-21.yml | 30 - .vsts-pipelines/builds/ci-internal.yml | 13 - .vsts-pipelines/builds/ci-public.yml | 15 - .vsts-pipelines/templates/build-steps.yml | 88 --- CONTRIBUTING.md | 4 - LICENSE.txt | 228 ------ NuGet.config | 7 - README.md | 18 - THIRD_PARTY_NOTICES | 42 - build.cmd | 2 - build.sh | 8 - korebuild-lock.txt | 2 - mv_to_src.sh | 35 + run.cmd | 2 - run.ps1 | 209 ----- run.sh | 256 ------ .gitignore => src/IISIntegration/.gitignore | 0 .../IISIntegration/Directory.Build.props | 0 .../IISIntegration/Directory.Build.targets | 0 .../IISIntegration/IISIntegration.NoV1.sln | 0 .../IISIntegration/IISIntegration.sln | 0 .../IISIntegration/NuGetPackageVerifier.json | 0 .../NuGetPackageVerifier.xplat.json | 0 .../IIS.Performance/FirstRequestConfig.cs | 0 .../IIS.Performance/IIS.Performance.csproj | 0 .../IIS.Performance/PlaintextBenchmark.cs | 0 .../IIS.Performance/StartupTimeBenchmark.cs | 0 .../IISIntegration/build}/Build.Settings | 0 .../build}/Config.Definitions.Props | 0 {build => src/IISIntegration/build}/Key.snk | Bin .../build}/applicationhost.config | 0 .../build}/applicationhost.iis.config | 0 .../IISIntegration/build}/assets.props | 0 .../build}/buildpipeline/pipeline.groovy | 36 +- .../buildpipeline/windows-appverif.groovy | 0 .../build}/buildpipeline/windows.groovy | 30 +- .../IISIntegration/build}/dependencies.props | 0 .../build}/functional-test-assets.targets | 0 .../IISIntegration/build}/launchSettings.json | 0 .../IISIntegration/build}/native.targets | 0 .../IISIntegration/build}/repo.props | 0 .../IISIntegration/build}/repo.targets | 0 .../IISIntegration/build}/sources.props | 0 .../IISIntegration/build}/testsite.props | 0 .../IISIntegration/korebuild.json | 0 ...crosoft.AspNetCore.AspNetCoreModule.nuspec | 0 ...icrosoft.AspNetCore.AspNetCoreModule.props | 0 ...osoft.AspNetCore.AspNetCoreModuleV2.nuspec | 0 ...oft.AspNetCore.AspNetCoreModuleV2.props.in | 0 .../samples}/IISSample/IISSample.csproj | 0 .../IISSample/Properties/launchSettings.json | 0 .../samples}/IISSample/Startup.cs | 0 .../samples}/IISSample/web.config | 0 .../NativeIISSample/NativeIISSample.csproj | 0 .../Properties/launchSettings.json | 0 .../samples}/NativeIISSample/Startup.cs | 0 .../samples}/NativeIISSample/web.config | 0 .../AspNetCore/AspNetCore.vcxproj | 0 .../AspNetCore/Inc/application.h | 0 .../AspNetCore/Inc/applicationmanager.h | 0 .../AspNetCore/Inc/aspnetcoreconfig.h | 0 .../AspNetCore/Inc/debugutil.h | 0 .../AspNetCore/Inc/environmentvariablehash.h | 0 .../AspNetCore/Inc/filewatcher.h | 0 .../AspNetCore/Inc/forwarderconnection.h | 0 .../AspNetCore/Inc/forwardinghandler.h | 0 .../AspNetCoreModuleV1/AspNetCore/Inc/path.h | 0 .../AspNetCore/Inc/processmanager.h | 0 .../AspNetCore/Inc/protocolconfig.h | 0 .../AspNetCore/Inc/proxymodule.h | 0 .../AspNetCore/Inc/resource.h | 0 .../AspNetCore/Inc/responseheaderhash.h | 0 .../AspNetCore/Inc/serverprocess.h | 0 .../AspNetCore/Inc/sttimer.h | 0 .../AspNetCore/Inc/websockethandler.h | 0 .../AspNetCore/Inc/winhttphelper.h | 0 .../AspNetCoreModuleV1/AspNetCore/Source.def | 0 .../AspNetCore/aspnetcore_msg.mc | 0 .../AspNetCore/aspnetcoremodule.rc | 0 .../AspNetCoreModuleV1/AspNetCore/resource.h | 0 .../AspNetCore/src/application.cxx | 0 .../AspNetCore/src/applicationmanager.cxx | 0 .../AspNetCore/src/aspnetcoreconfig.cxx | 0 .../AspNetCore/src/filewatcher.cxx | 0 .../AspNetCore/src/forwarderconnection.cxx | 0 .../AspNetCore/src/forwardinghandler.cxx | 0 .../AspNetCore/src/main.cxx | 0 .../AspNetCore/src/path.cxx | 0 .../AspNetCore/src/precomp.hxx | 0 .../AspNetCore/src/processmanager.cxx | 0 .../AspNetCore/src/protocolconfig.cxx | 0 .../AspNetCore/src/proxymodule.cxx | 0 .../AspNetCore/src/responseheaderhash.cxx | 0 .../AspNetCore/src/serverprocess.cxx | 0 .../AspNetCore/src/websockethandler.cxx | 0 .../AspNetCore/src/winhttphelper.cxx | 0 .../AspNetCoreModuleV1/IISLib/IISLib.vcxproj | 0 .../src}/AspNetCoreModuleV1/IISLib/acache.cxx | 0 .../src}/AspNetCoreModuleV1/IISLib/acache.h | 0 .../src}/AspNetCoreModuleV1/IISLib/ahutil.cpp | 0 .../src}/AspNetCoreModuleV1/IISLib/ahutil.h | 0 .../src}/AspNetCoreModuleV1/IISLib/base64.cpp | 0 .../src}/AspNetCoreModuleV1/IISLib/base64.h | 0 .../src}/AspNetCoreModuleV1/IISLib/buffer.h | 0 .../src}/AspNetCoreModuleV1/IISLib/datetime.h | 0 .../src}/AspNetCoreModuleV1/IISLib/dbgutil.h | 0 .../src}/AspNetCoreModuleV1/IISLib/hashfn.h | 0 .../AspNetCoreModuleV1/IISLib/hashtable.h | 0 .../AspNetCoreModuleV1/IISLib/listentry.h | 0 .../src}/AspNetCoreModuleV1/IISLib/macros.h | 0 .../AspNetCoreModuleV1/IISLib/multisz.cpp | 0 .../src}/AspNetCoreModuleV1/IISLib/multisz.h | 0 .../AspNetCoreModuleV1/IISLib/multisza.cpp | 0 .../src}/AspNetCoreModuleV1/IISLib/multisza.h | 0 .../src}/AspNetCoreModuleV1/IISLib/ntassert.h | 0 .../src}/AspNetCoreModuleV1/IISLib/percpu.h | 0 .../src}/AspNetCoreModuleV1/IISLib/precomp.h | 0 .../src}/AspNetCoreModuleV1/IISLib/prime.h | 0 .../src}/AspNetCoreModuleV1/IISLib/pudebug.h | 0 .../src}/AspNetCoreModuleV1/IISLib/reftrace.c | 0 .../src}/AspNetCoreModuleV1/IISLib/reftrace.h | 0 .../src}/AspNetCoreModuleV1/IISLib/rwlock.h | 0 .../AspNetCoreModuleV1/IISLib/stringa.cpp | 0 .../src}/AspNetCoreModuleV1/IISLib/stringa.h | 0 .../AspNetCoreModuleV1/IISLib/stringu.cpp | 0 .../src}/AspNetCoreModuleV1/IISLib/stringu.h | 0 .../src}/AspNetCoreModuleV1/IISLib/tracelog.c | 0 .../src}/AspNetCoreModuleV1/IISLib/tracelog.h | 0 .../src}/AspNetCoreModuleV1/IISLib/treehash.h | 0 .../src}/AspNetCoreModuleV1/IISLib/util.cxx | 0 .../AspNetCore/AppOfflineApplication.cpp | 0 .../AspNetCore/AppOfflineApplication.h | 0 .../AspNetCore/AppOfflineHandler.cpp | 0 .../AspNetCore/AppOfflineHandler.h | 0 .../AspNetCore/ApplicationFactory.h | 0 .../AspNetCore/AspNetCore.vcxproj | 608 +++++++------- .../AspNetCore/DisconnectHandler.cpp | 0 .../AspNetCore/DisconnectHandler.h | 0 .../AspNetCore/HandlerResolver.cpp | 0 .../AspNetCore/HandlerResolver.h | 0 .../AspNetCore/HtmlResponses.rc | Bin .../AspNetCore/InProcessShimStaticHtml.htm | 0 .../AspNetCore/OutOfProcessShimStaticHtml.htm | 0 .../PollingAppOfflineApplication.cpp | 0 .../AspNetCore/PollingAppOfflineApplication.h | 0 .../AspNetCore/ServerErrorApplication.h | 0 .../AspNetCore/ShimOptions.cpp | 0 .../AspNetCore/ShimOptions.h | 0 .../AspNetCoreModuleV2/AspNetCore/Source.def | 0 .../AspNetCoreModuleV2/AspNetCore/ancm.mof | 0 .../AspNetCore/applicationinfo.cpp | 0 .../AspNetCore/applicationinfo.h | 0 .../AspNetCore/applicationmanager.cpp | 0 .../AspNetCore/applicationmanager.h | 0 .../AspNetCore/aspnetcore_schema_v2.xml | 0 .../AspNetCore/aspnetcoremodule.rc | 0 .../AspNetCoreModuleV2/AspNetCore/dllmain.cpp | 0 .../AspNetCore/globalmodule.cpp | 0 .../AspNetCore/globalmodule.h | 0 .../AspNetCore/proxymodule.cpp | 0 .../AspNetCore/proxymodule.h | 0 .../AspNetCoreModuleV2/AspNetCore/resource.h | 0 .../AspNetCoreModuleV2/AspNetCore/stdafx.cpp | 0 .../AspNetCoreModuleV2/AspNetCore/stdafx.h | 0 .../CommonLib/BaseOutputManager.h | 0 .../CommonLib/CommonLib.vcxproj | 584 +++++++------- .../CommonLib/ConfigurationLoadException.h | 0 .../CommonLib/ConfigurationSection.cpp | 0 .../CommonLib/ConfigurationSection.h | 0 .../CommonLib/ConfigurationSource.cpp | 0 .../CommonLib/ConfigurationSource.h | 0 .../CommonLib/Environment.cpp | 0 .../CommonLib/Environment.h | 0 .../AspNetCoreModuleV2/CommonLib/EventLog.cpp | 0 .../AspNetCoreModuleV2/CommonLib/EventLog.h | 0 .../CommonLib/EventTracing.h | 0 .../CommonLib/FileOutputManager.cpp | 0 .../CommonLib/FileOutputManager.h | 0 .../CommonLib/GlobalVersionUtility.cpp | 0 .../CommonLib/GlobalVersionUtility.h | 0 .../CommonLib/HandleWrapper.cpp | 0 .../CommonLib/HandleWrapper.h | 0 .../CommonLib/IOutputManager.h | 0 .../CommonLib/InvalidOperationException.h | 0 .../CommonLib/LoggingHelpers.cpp | 0 .../CommonLib/LoggingHelpers.h | 0 .../CommonLib/ModuleHelpers.h | 0 .../CommonLib/NonCopyable.h | 0 .../CommonLib/NullOutputManager.h | 0 .../CommonLib/PipeOutputManager.cpp | 0 .../CommonLib/PipeOutputManager.h | 0 .../CommonLib/ResultException.h | 0 .../CommonLib/SRWExclusiveLock.cpp | 0 .../CommonLib/SRWExclusiveLock.h | 0 .../CommonLib/SRWSharedLock.cpp | 0 .../CommonLib/SRWSharedLock.h | 0 .../CommonLib/ServerErrorHandler.h | 0 .../CommonLib/StdWrapper.cpp | 0 .../AspNetCoreModuleV2/CommonLib/StdWrapper.h | 0 .../CommonLib/StringHelpers.cpp | 0 .../CommonLib/StringHelpers.h | 0 .../WebConfigConfigurationSection.cpp | 0 .../CommonLib/WebConfigConfigurationSection.h | 0 .../WebConfigConfigurationSource.cpp | 0 .../CommonLib/WebConfigConfigurationSource.h | 0 .../CommonLib/application.h | 0 .../CommonLib/aspnetcore_event.h | 0 .../CommonLib/aspnetcore_msg.mc | 0 .../CommonLib/config_utility.h | 0 .../CommonLib/debugutil.cpp | 0 .../AspNetCoreModuleV2/CommonLib/debugutil.h | 0 .../AspNetCoreModuleV2/CommonLib/exceptions.h | 0 .../CommonLib/file_utility.cpp | 0 .../CommonLib/file_utility.h | 0 .../AspNetCoreModuleV2/CommonLib/fx_ver.cpp | 0 .../AspNetCoreModuleV2/CommonLib/fx_ver.h | 0 .../CommonLib/hostfxr_utility.cpp | 0 .../CommonLib/hostfxr_utility.h | 0 .../CommonLib/hostfxroptions.cpp | 0 .../CommonLib/hostfxroptions.h | 0 .../CommonLib/iapplication.h | 0 .../CommonLib/irequesthandler.h | 0 .../CommonLib/requesthandler.h | 0 .../AspNetCoreModuleV2/CommonLib/resources.h | 0 .../AspNetCoreModuleV2/CommonLib/stdafx.cpp | 0 .../AspNetCoreModuleV2/CommonLib/stdafx.h | 0 .../AspNetCoreModuleV2/CommonLib/sttimer.h | 0 .../AspNetCoreModuleV2/CommonLib/targetver.h | 0 .../AspNetCoreModuleV2/DefaultRules.ruleset | 0 .../AspNetCoreModuleV2/IISLib/IISLib.vcxproj | 410 +++++----- .../src}/AspNetCoreModuleV2/IISLib/acache.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/acache.h | 0 .../src}/AspNetCoreModuleV2/IISLib/ahutil.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/ahutil.h | 0 .../src}/AspNetCoreModuleV2/IISLib/base64.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/base64.h | 0 .../src}/AspNetCoreModuleV2/IISLib/buffer.h | 0 .../src}/AspNetCoreModuleV2/IISLib/datetime.h | 0 .../src}/AspNetCoreModuleV2/IISLib/dbgutil.h | 0 .../src}/AspNetCoreModuleV2/IISLib/hashfn.h | 0 .../AspNetCoreModuleV2/IISLib/hashtable.h | 0 .../AspNetCoreModuleV2/IISLib/listentry.h | 0 .../src}/AspNetCoreModuleV2/IISLib/macros.h | 0 .../AspNetCoreModuleV2/IISLib/multisz.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/multisz.h | 0 .../AspNetCoreModuleV2/IISLib/multisza.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/multisza.h | 0 .../src}/AspNetCoreModuleV2/IISLib/ntassert.h | 0 .../src}/AspNetCoreModuleV2/IISLib/percpu.h | 0 .../src}/AspNetCoreModuleV2/IISLib/precomp.h | 0 .../src}/AspNetCoreModuleV2/IISLib/prime.h | 0 .../src}/AspNetCoreModuleV2/IISLib/reftrace.c | 0 .../src}/AspNetCoreModuleV2/IISLib/reftrace.h | 0 .../src}/AspNetCoreModuleV2/IISLib/rwlock.h | 0 .../AspNetCoreModuleV2/IISLib/stringa.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/stringa.h | 0 .../AspNetCoreModuleV2/IISLib/stringu.cpp | 0 .../src}/AspNetCoreModuleV2/IISLib/stringu.h | 0 .../src}/AspNetCoreModuleV2/IISLib/tracelog.c | 0 .../src}/AspNetCoreModuleV2/IISLib/tracelog.h | 0 .../src}/AspNetCoreModuleV2/IISLib/treehash.h | 0 .../src}/AspNetCoreModuleV2/IISLib/util.cpp | 0 .../InProcessRequestHandler/HtmlResponses.rc | Bin .../InProcessApplicationBase.cpp | 0 .../InProcessApplicationBase.h | 0 .../InProcessOptions.cpp | 0 .../InProcessOptions.h | 0 .../InProcessRequestHandler.vcxproj | 550 ++++++------- .../InProcessRhStaticHtml.htm | 0 .../ShuttingDownApplication.h | 0 .../InProcessRequestHandler/Source.def | 0 .../StartupExceptionApplication.h | 0 .../StartupExceptionHandler.h | 0 .../InProcessRequestHandler/dllmain.cpp | 0 .../inprocessapplication.cpp | 0 .../inprocessapplication.h | 0 .../inprocesshandler.cpp | 0 .../inprocesshandler.h | 0 .../inprocessrequesthandler.rc | 0 .../managedexports.cpp | 0 .../InProcessRequestHandler/resource.h | 0 .../InProcessRequestHandler/stdafx.cpp | 0 .../InProcessRequestHandler/stdafx.h | 0 .../HtmlResponses.rc | 0 .../OutOfProcessRequestHandler.vcxproj | 568 +++++++------- .../OutOfProcessRhStaticHtml.htm | 0 .../OutOfProcessRequestHandler/Source.def | 0 .../OutOfProcessRequestHandler/dllmain.cpp | 0 .../forwarderconnection.cpp | 0 .../forwarderconnection.h | 0 .../forwardinghandler.cpp | 0 .../forwardinghandler.h | 0 .../outofprocessrequesthandler.rc | 0 .../outprocessapplication.cpp | 0 .../outprocessapplication.h | 0 .../processmanager.cpp | 0 .../processmanager.h | 0 .../protocolconfig.cpp | 0 .../protocolconfig.h | 0 .../OutOfProcessRequestHandler/resource.h | 0 .../responseheaderhash.cpp | 0 .../responseheaderhash.h | 0 .../serverprocess.cpp | 0 .../serverprocess.h | 0 .../OutOfProcessRequestHandler/stdafx.cpp | 0 .../OutOfProcessRequestHandler/stdafx.h | 0 .../url_utility.cpp | 0 .../OutOfProcessRequestHandler/url_utility.h | 0 .../websockethandler.cpp | 0 .../websockethandler.h | 0 .../winhttphelper.cpp | 0 .../winhttphelper.h | 0 .../AppOfflineTrackingApplication.cpp | 0 .../AppOfflineTrackingApplication.h | 0 .../RequestHandlerLib.vcxproj | 0 .../environmentvariablehash.h | 0 .../environmentvariablehelpers.h | 0 .../RequestHandlerLib/filewatcher.cpp | 0 .../RequestHandlerLib/filewatcher.h | 0 .../requesthandler_config.cpp | 0 .../RequestHandlerLib/requesthandler_config.h | 0 .../RequestHandlerLib/stdafx.h | 0 .../src}/Directory.Build.props | 0 .../AppHostConfig/IIS.config | 0 .../Common.FunctionalTests/AppOfflineTests.cs | 0 .../Common.FunctionalTests/BasicAuthTests.cs | 0 .../ClientCertificateFixture.cs | 0 .../ClientCertificateTests.cs | 0 .../ClientDisconnectStress.cs | 0 .../CommonStartupTests.cs | 0 .../CompressionTests.cs | 0 .../ConfigurationChangeTests.cs | 0 .../Inprocess/ClientDisconnectTests.cs | 0 .../Inprocess/CompressionTests.cs | 0 .../Inprocess/EnvironmentVariableTests.cs | 0 .../Inprocess/ErrorPagesTests.cs | 0 .../Inprocess/EventLogTests.cs | 0 .../Inprocess/FeatureCollectionTests.cs | 0 .../Inprocess/FixtureLoggedTest.cs | 0 .../Inprocess/FrebTests.cs | 0 .../Inprocess/HelloWorldTests.cs | 0 .../Inprocess/HostingEnvironmentTests.cs | 0 .../InvalidReadWriteOperationTests.cs | 0 .../Inprocess/LargeResponseBodyTests.cs | 0 .../Inprocess/LogPipeTests.cs | 0 .../Inprocess/ResponseHeaderTests.cs | 0 .../Inprocess/ResponseInvalidOrderingTests.cs | 0 .../Inprocess/ServerVariablesTest.cs | 0 .../Inprocess/StartupExceptionTests.cs | 0 .../Inprocess/StartupTests.cs | 0 .../Inprocess/SynchronousReadAndWriteTests.cs | 0 .../Common.FunctionalTests/LogFileTests.cs | 0 .../MultiApplicationTests.cs | 0 .../OutOfProcess/AspNetCorePortTests.cs | 0 .../OutOfProcess/GlobalVersionTests.cs | 0 .../OutOfProcess/HelloWorldTest.cs | 0 .../PublishedSitesFixture.cs | 0 .../RequiresNewHandler.cs | 0 .../Common.FunctionalTests/RequiresNewShim.cs | 0 .../ServerAbortTests.cs | 0 .../SkipIfNotAdminAttribute.cs | 0 .../SkipVSTSAttribute.cs | 0 .../Utilities/AppVerifier.cs | 0 .../Utilities/EventLogHelpers.cs | 0 .../Utilities/FunctionalTestsBase.cs | 0 .../Utilities/Helpers.cs | 0 .../Utilities/IISCapability.cs | 0 .../Utilities/IISCompressionSiteCollection.cs | 0 .../Utilities/IISCompressionSiteFixture.cs | 0 .../Utilities/IISFunctionalTestBase.cs | 0 .../Utilities/IISTestSiteCollection.cs | 0 .../Utilities/IISTestSiteFixture.cs | 0 .../Utilities/LogFileTestBase.cs | 0 .../RequiresEnvironmentVariableAttribute.cs | 0 .../Utilities/SkipIfDebugAttribute.cs | 0 .../WindowsAuthTests.cs | 0 .../test}/Common.Tests/Common.Tests.csproj | 0 .../Common.Tests/Utilities/DisposableList.cs | 0 .../Common.Tests/Utilities/TestConnections.cs | 0 .../Utilities/TimeoutExtensions.cs | 0 .../CommonLibTests/CommonLibTests.vcxproj | 0 .../CommonLibTests/ConfigUtilityTests.cpp | 0 .../CommonLibTests/FileOutputManagerTests.cpp | 0 .../CommonLibTests/GlobalVersionTests.cpp | 0 .../test}/CommonLibTests/Helpers.cpp | 0 .../test}/CommonLibTests/Helpers.h | 0 .../test}/CommonLibTests/NativeTests.targets | 0 .../CommonLibTests/PipeOutputManagerTests.cpp | 0 .../exception_handler_tests.cpp | 0 .../test}/CommonLibTests/fakeclasses.h | 0 .../CommonLibTests/hostfxr_utility_tests.cpp | 0 .../inprocess_application_tests.cpp | 0 .../test}/CommonLibTests/main.cpp | 0 .../test}/CommonLibTests/stdafx.h | 0 .../test}/CommonLibTests/utility_tests.cpp | 0 .../test}/Directory.Build.props | 0 .../BackwardsCompatibilityTests.cs | 0 .../DeployerSelector.cs | 0 ...kwardsCompatibility.FunctionalTests.csproj | 0 .../DeployerSelector.cs | 0 .../ForwardsCompatibilityTests.cs | 0 ...rwardsCompatibility.FunctionalTests.csproj | 0 .../IIS.FunctionalTests/DeployerSelector.cs | 0 .../IIS.FunctionalTests.csproj | 0 .../Inprocess/StdOutRedirectionTests.cs | 0 .../MofFileTests.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../RequiresIISAttribute.cs | 0 .../ServicesTests.cs | 0 .../AppHostConfig/HostableWebCore.config | 0 .../test}/IIS.Tests/ClientDisconnectTests.cs | 0 .../IIS.Tests/ConnectionIdFeatureTests.cs | 0 .../IIS.Tests/HttpBodyControlFeatureTests.cs | 0 .../test}/IIS.Tests/IIS.Tests.csproj | 0 .../test}/IIS.Tests/ResponseAbortTests.cs | 0 .../test}/IIS.Tests/StrictTestServerTests.cs | 0 .../test}/IIS.Tests/TestServerTest.cs | 0 ...pIfHostableWebCoreNotAvailibleAttribute.cs | 0 .../test}/IIS.Tests/Utilities/TestServer.cs | 0 .../DeployerSelector.cs | 0 .../IISExpress.FunctionalTests/HttpsTests.cs | 0 .../IISExpress.FunctionalTests.csproj | 0 .../InProcess/AuthenticationTests.cs | 0 .../InProcess/ShutdownTests.cs | 0 .../InProcess/WebSocketTests.cs | 0 .../OutOfProcess/MultipleAppTests.cs | 0 .../OutOfProcess/NtlmAuthentationTest.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../RequiresIISAttribute.cs | 0 .../UpgradeFeatureDetectionTests.cs | 0 .../IISExtensionTests.cs | 0 .../IISMiddlewareTests.cs | 0 ...NetCore.Server.IISIntegration.Tests.csproj | 0 .../test}/TestTasks/InjectRequestHandler.cs | 0 .../test}/TestTasks/TestTasks.csproj | 0 .../test}/WebSites/Directory.Build.props | 0 .../InProcessWebSite.csproj | 0 .../Properties/launchSettings.json | 0 .../WebSites/InProcessWebSite/DummyServer.cs | 0 .../InProcessWebSite/InProcessWebSite.csproj | 0 .../WebSites/InProcessWebSite/Program.cs | 0 .../Properties/launchSettings.json | 0 .../InProcessWebSite/Startup.WebSockets.cs | 0 .../WebSites/InProcessWebSite/Startup.cs | 0 .../WebSites/InProcessWebSite/web.config | 0 .../InProcessWebSite/wwwroot/static.txt | 0 .../OutOfProcessWebSite.csproj | 0 .../WebSites/OutOfProcessWebSite/Program.cs | 0 .../Properties/launchSettings.json | 0 .../WebSites/OutOfProcessWebSite/Startup.cs | 0 .../OutOfProcessWebSite/wwwroot/static.txt | 0 .../WebSites/StressTestWebSite/Program.cs | 0 .../Properties/launchSettings.json | 0 .../WebSites/StressTestWebSite/Startup.cs | 0 .../StressTestWebSite.csproj | 0 .../shared/SharedStartup/Startup.shared.cs | 0 .../WebSites/shared/WebSockets/Constants.cs | 0 .../shared/WebSockets/HandshakeHelpers.cs | 0 .../WebSites/shared/WebSockets/TestStartup.cs | 0 .../IISIntegration/test}/gtest/gtest.vcxproj | 0 .../AssemblyInfo.cs | 0 .../Core/DuplexStream.cs | 0 .../Core/EmptyStream.cs | 0 .../Core/HttpRequestStream.cs | 0 .../Core/HttpResponseStream.cs | 0 .../Core/HttpStreamState.cs | 0 .../Core/HttpUpgradeStream.cs | 0 .../Core/IISConfigurationData.cs | 0 .../Core/IISHttpContext.FeatureCollection.cs | 0 .../Core/IISHttpContext.Features.cs | 0 .../IISHttpContext.IHttpConnectionFeature.cs | 0 ...tpContext.IHttpRequestIdentifierFeature.cs | 0 ...HttpContext.IHttpRequestLifetimeFeature.cs | 0 .../Core/IISHttpContext.IO.cs | 0 .../Core/IISHttpContext.Log.cs | 0 .../Core/IISHttpContext.cs | 0 .../Core/IISHttpContextOfT.cs | 0 .../Core/IISHttpServer.cs | 0 .../Core/IISNativeApplication.cs | 0 .../Core/IISServerAuthenticationHandler.cs | 0 .../Core/IISServerSetupFilter.cs | 0 .../Core/IO/AsyncIOEngine.Flush.cs | 0 .../Core/IO/AsyncIOEngine.Read.cs | 0 .../Core/IO/AsyncIOEngine.Write.cs | 0 .../Core/IO/AsyncIOEngine.cs | 0 .../Core/IO/AsyncIOOperation.cs | 0 .../Core/IO/AsyncWriteOperationBase.cs | 0 .../Core/IO/IAsyncIOEngine.cs | 0 .../IO/WebSocketsAsyncIOEngine.Initialize.cs | 0 .../Core/IO/WebSocketsAsyncIOEngine.Read.cs | 0 .../Core/IO/WebSocketsAsyncIOEngine.Write.cs | 0 .../Core/IO/WebSocketsAsyncIOEngine.cs | 0 .../Core/OutputProducer.cs | 0 .../Core/ReadOnlyStream.cs | 0 .../Core/Streams.cs | 0 .../ThrowingWasUpgradedWriteOnlyStream.cs | 0 .../Core/WrappingStream.cs | 0 .../Core/WriteOnlyStream.cs | 0 .../CoreStrings.resx | 0 .../HttpContextExtensions.cs | 0 .../IISServerDefaults.cs | 0 .../IISServerOptions.cs | 0 .../IServerVariableFeature.cs | 0 .../Microsoft.AspNetCore.Server.IIS.csproj | 0 .../Microsoft.AspNetCore.Server.IIS.targets | 0 .../NativeMethods.cs | 0 .../Properties/CoreStrings.Designer.cs | 0 .../WebHostBuilderIISExtensions.cs | 0 .../src}/Microsoft.AspNetCore.Server.IIS/_._ | 0 .../AuthenticationHandler.cs | 0 .../ForwardedTlsConnectionFeature.cs | 0 .../IISDefaults.cs | 0 .../IISHostingStartup.cs | 0 .../IISMiddleware.cs | 0 .../IISOptions.cs | 0 .../IISSetupFilter.cs | 0 ...ft.AspNetCore.Server.IISIntegration.csproj | 0 ...t.AspNetCore.Server.IISIntegration.targets | 0 .../NativeMethods.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../WebHostBuilderIISExtensions.cs | 0 .../baseline.netcore.json | 0 .../ApplicationDeployerFactory.cs | 0 .../Http.config | 0 .../IISDeployer.cs | 0 .../IISDeployerBase.cs | 0 .../IISDeploymentParameterExtensions.cs | 0 .../IISDeploymentParameters.cs | 0 .../IISDeploymentResult.cs | 0 .../IISExpressDeployer.cs | 0 .../LoggingHandler.cs | 0 ...tCore.Server.IntegrationTesting.IIS.csproj | 0 .../ProcessTracker.cs | 0 .../RetryHandler.cs | 0 .../WebConfigHelpers.cs | 0 .../XElementExtensions.cs | 0 .../AppHostConfig/IIS.config | 740 ++++++++++++++++++ .../Common.FunctionalTests/AppOfflineTests.cs | 287 +++++++ .../Common.FunctionalTests/BasicAuthTests.cs | 70 ++ .../ClientCertificateFixture.cs | 104 +++ .../ClientCertificateTests.cs | 108 +++ .../ClientDisconnectStress.cs | 65 ++ .../CommonStartupTests.cs | 44 ++ .../CompressionTests.cs | 58 ++ .../ConfigurationChangeTests.cs | 126 +++ .../Inprocess/ClientDisconnectTests.cs | 108 +++ .../Inprocess/CompressionTests.cs | 96 +++ .../Inprocess/EnvironmentVariableTests.cs | 51 ++ .../Inprocess/ErrorPagesTests.cs | 131 ++++ .../Inprocess/EventLogTests.cs | 46 ++ .../Inprocess/FeatureCollectionTests.cs | 29 + .../Inprocess/FixtureLoggedTest.cs | 31 + .../Inprocess/FrebTests.cs | 181 +++++ .../Inprocess/HelloWorldTests.cs | 30 + .../Inprocess/HostingEnvironmentTests.cs | 33 + .../InvalidReadWriteOperationTests.cs | 84 ++ .../Inprocess/LargeResponseBodyTests.cs | 36 + .../Inprocess/LogPipeTests.cs | 83 ++ .../Inprocess/ResponseHeaderTests.cs | 85 ++ .../Inprocess/ResponseInvalidOrderingTests.cs | 29 + .../Inprocess/ServerVariablesTest.cs | 59 ++ .../Inprocess/StartupExceptionTests.cs | 100 +++ .../Inprocess/StartupTests.cs | 479 ++++++++++++ .../Inprocess/SynchronousReadAndWriteTests.cs | 197 +++++ .../Common.FunctionalTests/LogFileTests.cs | 242 ++++++ .../MultiApplicationTests.cs | 144 ++++ .../OutOfProcess/AspNetCorePortTests.cs | 125 +++ .../OutOfProcess/GlobalVersionTests.cs | 252 ++++++ .../OutOfProcess/HelloWorldTest.cs | 81 ++ .../PublishedSitesFixture.cs | 65 ++ .../RequiresNewHandler.cs | 16 + .../Common.FunctionalTests/RequiresNewShim.cs | 16 + .../ServerAbortTests.cs | 65 ++ .../SkipIfNotAdminAttribute.cs | 25 + .../SkipVSTSAttribute.cs | 17 + .../Utilities/AppVerifier.cs | 83 ++ .../Utilities/EventLogHelpers.cs | 210 +++++ .../Utilities/FunctionalTestsBase.cs | 59 ++ .../Utilities/Helpers.cs | 241 ++++++ .../Utilities/IISCapability.cs | 22 + .../Utilities/IISCompressionSiteCollection.cs | 13 + .../Utilities/IISCompressionSiteFixture.cs | 44 ++ .../Utilities/IISFunctionalTestBase.cs | 15 + .../Utilities/IISTestSiteCollection.cs | 29 + .../Utilities/IISTestSiteFixture.cs | 191 +++++ .../Utilities/LogFileTestBase.cs | 34 + .../RequiresEnvironmentVariableAttribute.cs | 24 + .../Utilities/SkipIfDebugAttribute.cs | 22 + .../WindowsAuthTests.cs | 52 ++ .../test/Common.Tests/Common.Tests.csproj | 22 + .../Common.Tests/Utilities/DisposableList.cs | 25 + .../Common.Tests/Utilities/TestConnections.cs | 252 ++++++ .../Utilities/TimeoutExtensions.cs | 26 + .../CommonLibTests/CommonLibTests.vcxproj | 196 +++++ .../CommonLibTests/ConfigUtilityTests.cpp | 123 +++ .../CommonLibTests/FileOutputManagerTests.cpp | 152 ++++ .../CommonLibTests/GlobalVersionTests.cpp | 153 ++++ .../test/CommonLibTests/Helpers.cpp | 41 + .../test/CommonLibTests/Helpers.h | 28 + .../test/CommonLibTests/NativeTests.targets | 8 + .../CommonLibTests/PipeOutputManagerTests.cpp | 162 ++++ .../exception_handler_tests.cpp | 49 ++ .../test/CommonLibTests/fakeclasses.h | 190 +++++ .../CommonLibTests/hostfxr_utility_tests.cpp | 122 +++ .../inprocess_application_tests.cpp | 85 ++ .../test/CommonLibTests/main.cpp | 12 + .../test/CommonLibTests/stdafx.h | 59 ++ .../test/CommonLibTests/utility_tests.cpp | 75 ++ src/IISIntegration/test/Directory.Build.props | 16 + .../BackwardsCompatibilityTests.cs | 39 + .../DeployerSelector.cs | 14 + ...kwardsCompatibility.FunctionalTests.csproj | 46 ++ .../DeployerSelector.cs | 14 + .../ForwardsCompatibilityTests.cs | 38 + ...rwardsCompatibility.FunctionalTests.csproj | 45 ++ .../IIS.FunctionalTests/DeployerSelector.cs | 14 + .../IIS.FunctionalTests.csproj | 46 ++ .../Inprocess/StdOutRedirectionTests.cs | 150 ++++ .../MofFileTests.cs | 26 + .../Properties/AssemblyInfo.cs | 10 + .../RequiresIISAttribute.cs | 150 ++++ .../ServicesTests.cs | 96 +++ .../AppHostConfig/HostableWebCore.config | 198 +++++ .../test/IIS.Tests/ClientDisconnectTests.cs | 302 +++++++ .../IIS.Tests/ConnectionIdFeatureTests.cs | 54 ++ .../IIS.Tests/HttpBodyControlFeatureTests.cs | 31 + .../test/IIS.Tests/IIS.Tests.csproj | 32 + .../test/IIS.Tests/ResponseAbortTests.cs | 151 ++++ .../test/IIS.Tests/StrictTestServerTests.cs | 24 + .../test/IIS.Tests/TestServerTest.cs | 35 + ...pIfHostableWebCoreNotAvailibleAttribute.cs | 17 + .../test/IIS.Tests/Utilities/TestServer.cs | 211 +++++ .../DeployerSelector.cs | 14 + .../IISExpress.FunctionalTests/HttpsTests.cs | 60 ++ .../IISExpress.FunctionalTests.csproj | 38 + .../InProcess/AuthenticationTests.cs | 70 ++ .../InProcess/ShutdownTests.cs | 90 +++ .../InProcess/WebSocketTests.cs | 79 ++ .../OutOfProcess/MultipleAppTests.cs | 81 ++ .../OutOfProcess/NtlmAuthentationTest.cs | 87 ++ .../Properties/AssemblyInfo.cs | 10 + .../RequiresIISAttribute.cs | 24 + .../UpgradeFeatureDetectionTests.cs | 83 ++ .../IISExtensionTests.cs | 33 + .../IISMiddlewareTests.cs | 420 ++++++++++ ...NetCore.Server.IISIntegration.Tests.csproj | 18 + .../test/TestTasks/InjectRequestHandler.cs | 62 ++ .../test/TestTasks/TestTasks.csproj | 12 + .../test/WebSites/Directory.Build.props | 7 + .../InProcessWebSite.csproj | 32 + .../Properties/launchSettings.json | 42 + .../WebSites/InProcessWebSite/DummyServer.cs | 30 + .../InProcessWebSite/InProcessWebSite.csproj | 33 + .../test/WebSites/InProcessWebSite/Program.cs | 114 +++ .../Properties/launchSettings.json | 42 + .../InProcessWebSite/Startup.WebSockets.cs | 147 ++++ .../test/WebSites/InProcessWebSite/Startup.cs | 699 +++++++++++++++++ .../test/WebSites/InProcessWebSite/web.config | 16 + .../InProcessWebSite/wwwroot/static.txt | 0 .../OutOfProcessWebSite.csproj | 31 + .../WebSites/OutOfProcessWebSite/Program.cs | 45 ++ .../Properties/launchSettings.json | 42 + .../WebSites/OutOfProcessWebSite/Startup.cs | 105 +++ .../OutOfProcessWebSite/wwwroot/static.txt | 0 .../WebSites/StressTestWebSite/Program.cs | 26 + .../Properties/launchSettings.json | 42 + .../WebSites/StressTestWebSite/Startup.cs | 232 ++++++ .../StressTestWebSite.csproj | 25 + .../shared/SharedStartup/Startup.shared.cs | 117 +++ .../WebSites/shared/WebSockets/Constants.cs | 17 + .../shared/WebSockets/HandshakeHelpers.cs | 41 + .../WebSites/shared/WebSockets/TestStartup.cs | 38 + src/IISIntegration/test/gtest/gtest.vcxproj | 180 +++++ .../tools}/GenerateNativeAssets.ps1 | 0 .../tools}/SetupTestEnvironment.ps1 | 0 .../tools}/UpdateIISExpressCertificate.ps1 | 0 .../IISIntegration/tools}/certificate.ps1 | 0 .../IISIntegration/tools}/httpsys.ps1 | 0 .../IISIntegration/tools}/installancm.ps1 | 0 .../IISIntegration/tools}/update_schema.ps1 | 0 .../IISIntegration/version.props | 0 test/gtest/googletest | 1 - 686 files changed, 13828 insertions(+), 2425 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .editorconfig delete mode 100644 .gitattributes delete mode 100644 .gitmodules delete mode 100644 .vsts-pipelines/builds/ci-internal-21.yml delete mode 100644 .vsts-pipelines/builds/ci-internal.yml delete mode 100644 .vsts-pipelines/builds/ci-public.yml delete mode 100644 .vsts-pipelines/templates/build-steps.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 LICENSE.txt delete mode 100644 NuGet.config delete mode 100644 README.md delete mode 100644 THIRD_PARTY_NOTICES delete mode 100644 build.cmd delete mode 100755 build.sh delete mode 100644 korebuild-lock.txt create mode 100644 mv_to_src.sh delete mode 100644 run.cmd delete mode 100644 run.ps1 delete mode 100755 run.sh rename .gitignore => src/IISIntegration/.gitignore (100%) rename Directory.Build.props => src/IISIntegration/Directory.Build.props (100%) rename Directory.Build.targets => src/IISIntegration/Directory.Build.targets (100%) rename IISIntegration.NoV1.sln => src/IISIntegration/IISIntegration.NoV1.sln (100%) rename IISIntegration.sln => src/IISIntegration/IISIntegration.sln (100%) rename NuGetPackageVerifier.json => src/IISIntegration/NuGetPackageVerifier.json (100%) rename NuGetPackageVerifier.xplat.json => src/IISIntegration/NuGetPackageVerifier.xplat.json (100%) rename {benchmarks => src/IISIntegration/benchmarks}/IIS.Performance/FirstRequestConfig.cs (100%) rename {benchmarks => src/IISIntegration/benchmarks}/IIS.Performance/IIS.Performance.csproj (100%) rename {benchmarks => src/IISIntegration/benchmarks}/IIS.Performance/PlaintextBenchmark.cs (100%) rename {benchmarks => src/IISIntegration/benchmarks}/IIS.Performance/StartupTimeBenchmark.cs (100%) rename {build => src/IISIntegration/build}/Build.Settings (100%) rename {build => src/IISIntegration/build}/Config.Definitions.Props (100%) rename {build => src/IISIntegration/build}/Key.snk (100%) rename {build => src/IISIntegration/build}/applicationhost.config (100%) rename {build => src/IISIntegration/build}/applicationhost.iis.config (100%) rename {build => src/IISIntegration/build}/assets.props (100%) rename {build => src/IISIntegration/build}/buildpipeline/pipeline.groovy (96%) rename {build => src/IISIntegration/build}/buildpipeline/windows-appverif.groovy (100%) rename {build => src/IISIntegration/build}/buildpipeline/windows.groovy (98%) rename {build => src/IISIntegration/build}/dependencies.props (100%) rename {build => src/IISIntegration/build}/functional-test-assets.targets (100%) rename {build => src/IISIntegration/build}/launchSettings.json (100%) rename {build => src/IISIntegration/build}/native.targets (100%) rename {build => src/IISIntegration/build}/repo.props (100%) rename {build => src/IISIntegration/build}/repo.targets (100%) rename {build => src/IISIntegration/build}/sources.props (100%) rename {build => src/IISIntegration/build}/testsite.props (100%) rename korebuild.json => src/IISIntegration/korebuild.json (100%) rename {nuget => src/IISIntegration/nuget}/Microsoft.AspNetCore.AspNetCoreModule.nuspec (100%) rename {nuget => src/IISIntegration/nuget}/Microsoft.AspNetCore.AspNetCoreModule.props (100%) rename {nuget => src/IISIntegration/nuget}/Microsoft.AspNetCore.AspNetCoreModuleV2.nuspec (100%) rename {nuget => src/IISIntegration/nuget}/Microsoft.AspNetCore.AspNetCoreModuleV2.props.in (100%) rename {samples => src/IISIntegration/samples}/IISSample/IISSample.csproj (100%) rename {samples => src/IISIntegration/samples}/IISSample/Properties/launchSettings.json (100%) rename {samples => src/IISIntegration/samples}/IISSample/Startup.cs (100%) rename {samples => src/IISIntegration/samples}/IISSample/web.config (100%) rename {samples => src/IISIntegration/samples}/NativeIISSample/NativeIISSample.csproj (100%) rename {samples => src/IISIntegration/samples}/NativeIISSample/Properties/launchSettings.json (100%) rename {samples => src/IISIntegration/samples}/NativeIISSample/Startup.cs (100%) rename {samples => src/IISIntegration/samples}/NativeIISSample/web.config (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/application.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/applicationmanager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/aspnetcoreconfig.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/debugutil.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/environmentvariablehash.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/filewatcher.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/forwarderconnection.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/forwardinghandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/path.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/processmanager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/protocolconfig.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/proxymodule.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/resource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/responseheaderhash.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/serverprocess.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/websockethandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Inc/winhttphelper.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/Source.def (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/aspnetcore_msg.mc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/aspnetcoremodule.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/resource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/application.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/applicationmanager.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/aspnetcoreconfig.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/filewatcher.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/forwarderconnection.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/forwardinghandler.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/main.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/path.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/precomp.hxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/processmanager.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/protocolconfig.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/proxymodule.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/responseheaderhash.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/serverprocess.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/websockethandler.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/AspNetCore/src/winhttphelper.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/IISLib.vcxproj (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/acache.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/acache.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/ahutil.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/ahutil.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/base64.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/base64.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/buffer.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/datetime.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/dbgutil.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/hashfn.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/hashtable.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/listentry.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/macros.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/multisz.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/multisz.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/multisza.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/multisza.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/ntassert.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/percpu.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/precomp.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/prime.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/pudebug.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/reftrace.c (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/reftrace.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/rwlock.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/stringa.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/stringa.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/stringu.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/stringu.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/tracelog.c (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/tracelog.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/treehash.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV1/IISLib/util.cxx (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj (98%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/HtmlResponses.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/InProcessShimStaticHtml.htm (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/OutOfProcessShimStaticHtml.htm (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/ShimOptions.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/Source.def (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/ancm.mof (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/applicationinfo.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/applicationmanager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/aspnetcore_schema_v2.xml (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/aspnetcoremodule.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/dllmain.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/globalmodule.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/proxymodule.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/resource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/stdafx.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/AspNetCore/stdafx.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/BaseOutputManager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj (98%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ConfigurationLoadException.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ConfigurationSource.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ConfigurationSource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/Environment.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/Environment.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/EventLog.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/EventLog.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/EventTracing.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/FileOutputManager.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/FileOutputManager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/HandleWrapper.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/HandleWrapper.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/IOutputManager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/InvalidOperationException.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/LoggingHelpers.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/LoggingHelpers.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ModuleHelpers.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/NonCopyable.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/NullOutputManager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/PipeOutputManager.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/PipeOutputManager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ResultException.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/SRWSharedLock.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/SRWSharedLock.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/ServerErrorHandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/StdWrapper.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/StdWrapper.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/StringHelpers.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/StringHelpers.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/application.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/aspnetcore_event.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/config_utility.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/debugutil.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/debugutil.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/exceptions.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/file_utility.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/file_utility.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/fx_ver.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/fx_ver.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/hostfxroptions.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/iapplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/irequesthandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/requesthandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/resources.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/stdafx.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/stdafx.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/sttimer.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/CommonLib/targetver.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/DefaultRules.ruleset (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/IISLib.vcxproj (97%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/acache.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/acache.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/ahutil.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/ahutil.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/base64.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/base64.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/buffer.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/datetime.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/dbgutil.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/hashfn.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/hashtable.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/listentry.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/macros.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/multisz.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/multisz.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/multisza.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/multisza.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/ntassert.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/percpu.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/precomp.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/prime.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/reftrace.c (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/reftrace.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/rwlock.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/stringa.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/stringa.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/stringu.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/stringu.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/tracelog.c (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/tracelog.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/treehash.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/IISLib/util.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/HtmlResponses.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj (98%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRhStaticHtml.htm (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/Source.def (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionHandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/inprocessrequesthandler.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/resource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/HtmlResponses.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj (98%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRhStaticHtml.htm (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/Source.def (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocessrequesthandler.rc (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/resource.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/RequestHandlerLib.vcxproj (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h (100%) rename src/{ => IISIntegration/src}/AspNetCoreModuleV2/RequestHandlerLib/stdafx.h (100%) rename src/{ => IISIntegration/src}/Directory.Build.props (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/AppHostConfig/IIS.config (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/AppOfflineTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/BasicAuthTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/ClientCertificateFixture.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/ClientCertificateTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/ClientDisconnectStress.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/CommonStartupTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/CompressionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/ConfigurationChangeTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/CompressionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/EventLogTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/FrebTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/HelloWorldTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/LogPipeTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/StartupTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/LogFileTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/MultiApplicationTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/PublishedSitesFixture.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/RequiresNewHandler.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/RequiresNewShim.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/ServerAbortTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/SkipIfNotAdminAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/SkipVSTSAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/AppVerifier.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/EventLogHelpers.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/Helpers.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/IISCapability.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/LogFileTestBase.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.FunctionalTests/WindowsAuthTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.Tests/Common.Tests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.Tests/Utilities/DisposableList.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.Tests/Utilities/TestConnections.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Common.Tests/Utilities/TimeoutExtensions.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/CommonLibTests.vcxproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/ConfigUtilityTests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/FileOutputManagerTests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/GlobalVersionTests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/Helpers.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/Helpers.h (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/NativeTests.targets (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/PipeOutputManagerTests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/exception_handler_tests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/fakeclasses.h (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/hostfxr_utility_tests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/inprocess_application_tests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/main.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/stdafx.h (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/CommonLibTests/utility_tests.cpp (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Directory.Build.props (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.FunctionalTests/DeployerSelector.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.FunctionalTests/IIS.FunctionalTests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Shared.FunctionalTests/MofFileTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Shared.FunctionalTests/ServicesTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/AppHostConfig/HostableWebCore.config (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/ClientDisconnectTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/ConnectionIdFeatureTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/HttpBodyControlFeatureTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/IIS.Tests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/ResponseAbortTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/StrictTestServerTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/TestServerTest.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IIS.Tests/Utilities/TestServer.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/DeployerSelector.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/HttpsTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/RequiresIISAttribute.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/TestTasks/InjectRequestHandler.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/TestTasks/TestTasks.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/Directory.Build.props (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/DummyServer.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/InProcessWebSite.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/Program.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/Properties/launchSettings.json (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/Startup.WebSockets.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/Startup.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/web.config (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/InProcessWebSite/wwwroot/static.txt (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/OutOfProcessWebSite/Program.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/OutOfProcessWebSite/Properties/launchSettings.json (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/OutOfProcessWebSite/Startup.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/OutOfProcessWebSite/wwwroot/static.txt (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/StressTestWebSite/Program.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/StressTestWebSite/Properties/launchSettings.json (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/StressTestWebSite/Startup.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/StressTestWebSite/StressTestWebSite.csproj (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/shared/SharedStartup/Startup.shared.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/shared/WebSockets/Constants.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/shared/WebSockets/HandshakeHelpers.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/WebSites/shared/WebSockets/TestStartup.cs (100%) rename {test => src/IISIntegration/src/IISIntegration/test}/gtest/gtest.vcxproj (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/AssemblyInfo.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/DuplexStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/EmptyStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/HttpRequestStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/HttpResponseStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/HttpStreamState.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/HttpUpgradeStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Features.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpConnectionFeature.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestIdentifierFeature.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestLifetimeFeature.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IO.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Log.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContextOfT.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISNativeApplication.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISServerAuthenticationHandler.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Flush.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Read.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Write.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOOperation.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncWriteOperationBase.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/IAsyncIOEngine.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Initialize.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Read.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Write.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/OutputProducer.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/ReadOnlyStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/Streams.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/ThrowingWasUpgradedWriteOnlyStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/WrappingStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Core/WriteOnlyStream.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/CoreStrings.resx (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/HttpContextExtensions.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/IISServerDefaults.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/IServerVariableFeature.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/Properties/CoreStrings.Designer.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IIS/_._ (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/AuthenticationHandler.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/ForwardedTlsConnectionFeature.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/IISDefaults.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/IISHostingStartup.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/IISMiddleware.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/IISOptions.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/IISSetupFilter.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/Properties/AssemblyInfo.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IISIntegration/baseline.netcore.json (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployerBase.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameterExtensions.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameters.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentResult.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ProcessTracker.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/RetryHandler.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs (100%) rename src/{ => IISIntegration/src}/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/XElementExtensions.cs (100%) create mode 100644 src/IISIntegration/test/Common.FunctionalTests/AppHostConfig/IIS.config create mode 100644 src/IISIntegration/test/Common.FunctionalTests/AppOfflineTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/BasicAuthTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/ClientCertificateFixture.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/ClientCertificateTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/ClientDisconnectStress.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/CommonStartupTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/CompressionTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/ConfigurationChangeTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/CompressionTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/EventLogTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/FrebTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/LogFileTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/MultiApplicationTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/PublishedSitesFixture.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/RequiresNewHandler.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/RequiresNewShim.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/ServerAbortTests.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/SkipVSTSAttribute.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/AppVerifier.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/Helpers.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCapability.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs create mode 100644 src/IISIntegration/test/Common.FunctionalTests/WindowsAuthTests.cs create mode 100644 src/IISIntegration/test/Common.Tests/Common.Tests.csproj create mode 100644 src/IISIntegration/test/Common.Tests/Utilities/DisposableList.cs create mode 100644 src/IISIntegration/test/Common.Tests/Utilities/TestConnections.cs create mode 100644 src/IISIntegration/test/Common.Tests/Utilities/TimeoutExtensions.cs create mode 100644 src/IISIntegration/test/CommonLibTests/CommonLibTests.vcxproj create mode 100644 src/IISIntegration/test/CommonLibTests/ConfigUtilityTests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/FileOutputManagerTests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/GlobalVersionTests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/Helpers.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/Helpers.h create mode 100644 src/IISIntegration/test/CommonLibTests/NativeTests.targets create mode 100644 src/IISIntegration/test/CommonLibTests/PipeOutputManagerTests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/exception_handler_tests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/fakeclasses.h create mode 100644 src/IISIntegration/test/CommonLibTests/hostfxr_utility_tests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/inprocess_application_tests.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/main.cpp create mode 100644 src/IISIntegration/test/CommonLibTests/stdafx.h create mode 100644 src/IISIntegration/test/CommonLibTests/utility_tests.cpp create mode 100644 src/IISIntegration/test/Directory.Build.props create mode 100644 src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs create mode 100644 src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs create mode 100644 src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj create mode 100644 src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs create mode 100644 src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs create mode 100644 src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj create mode 100644 src/IISIntegration/test/IIS.FunctionalTests/DeployerSelector.cs create mode 100644 src/IISIntegration/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj create mode 100644 src/IISIntegration/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs create mode 100644 src/IISIntegration/test/IIS.Shared.FunctionalTests/MofFileTests.cs create mode 100644 src/IISIntegration/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs create mode 100644 src/IISIntegration/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs create mode 100644 src/IISIntegration/test/IIS.Shared.FunctionalTests/ServicesTests.cs create mode 100644 src/IISIntegration/test/IIS.Tests/AppHostConfig/HostableWebCore.config create mode 100644 src/IISIntegration/test/IIS.Tests/ClientDisconnectTests.cs create mode 100644 src/IISIntegration/test/IIS.Tests/ConnectionIdFeatureTests.cs create mode 100644 src/IISIntegration/test/IIS.Tests/HttpBodyControlFeatureTests.cs create mode 100644 src/IISIntegration/test/IIS.Tests/IIS.Tests.csproj create mode 100644 src/IISIntegration/test/IIS.Tests/ResponseAbortTests.cs create mode 100644 src/IISIntegration/test/IIS.Tests/StrictTestServerTests.cs create mode 100644 src/IISIntegration/test/IIS.Tests/TestServerTest.cs create mode 100644 src/IISIntegration/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs create mode 100644 src/IISIntegration/test/IIS.Tests/Utilities/TestServer.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/DeployerSelector.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/HttpsTests.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs create mode 100644 src/IISIntegration/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs create mode 100644 src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs create mode 100644 src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs create mode 100644 src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj create mode 100644 src/IISIntegration/test/TestTasks/InjectRequestHandler.cs create mode 100644 src/IISIntegration/test/TestTasks/TestTasks.csproj create mode 100644 src/IISIntegration/test/WebSites/Directory.Build.props create mode 100644 src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj create mode 100644 src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/DummyServer.cs create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/InProcessWebSite.csproj create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/Program.cs create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/Properties/launchSettings.json create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/Startup.WebSockets.cs create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/Startup.cs create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/web.config create mode 100644 src/IISIntegration/test/WebSites/InProcessWebSite/wwwroot/static.txt create mode 100644 src/IISIntegration/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj create mode 100644 src/IISIntegration/test/WebSites/OutOfProcessWebSite/Program.cs create mode 100644 src/IISIntegration/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json create mode 100644 src/IISIntegration/test/WebSites/OutOfProcessWebSite/Startup.cs create mode 100644 src/IISIntegration/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt create mode 100644 src/IISIntegration/test/WebSites/StressTestWebSite/Program.cs create mode 100644 src/IISIntegration/test/WebSites/StressTestWebSite/Properties/launchSettings.json create mode 100644 src/IISIntegration/test/WebSites/StressTestWebSite/Startup.cs create mode 100644 src/IISIntegration/test/WebSites/StressTestWebSite/StressTestWebSite.csproj create mode 100644 src/IISIntegration/test/WebSites/shared/SharedStartup/Startup.shared.cs create mode 100644 src/IISIntegration/test/WebSites/shared/WebSockets/Constants.cs create mode 100644 src/IISIntegration/test/WebSites/shared/WebSockets/HandshakeHelpers.cs create mode 100644 src/IISIntegration/test/WebSites/shared/WebSockets/TestStartup.cs create mode 100644 src/IISIntegration/test/gtest/gtest.vcxproj rename {tools => src/IISIntegration/tools}/GenerateNativeAssets.ps1 (100%) rename {tools => src/IISIntegration/tools}/SetupTestEnvironment.ps1 (100%) rename {tools => src/IISIntegration/tools}/UpdateIISExpressCertificate.ps1 (100%) rename {tools => src/IISIntegration/tools}/certificate.ps1 (100%) rename {tools => src/IISIntegration/tools}/httpsys.ps1 (100%) rename {tools => src/IISIntegration/tools}/installancm.ps1 (100%) rename {tools => src/IISIntegration/tools}/update_schema.ps1 (100%) rename version.props => src/IISIntegration/version.props (100%) delete mode 160000 test/gtest/googletest diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index bb08c43646..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,27 +0,0 @@ -init: - # Reset dynamic port range from AppVeyor setting (1025-65535) to Windows default (49152-65535), - # to prevent conflicts with ANCM random ports (1025-48000). - - netsh int ipv4 show dynamicport tcp - - netsh int ipv4 set dynamic tcp start=49152 num=16384 - - netsh int ipv4 show dynamicport tcp - - - git config --global core.autocrlf true -branches: - only: - - dev - - /^release\/.*$/ - - /^(.*\/)?ci-.*$/ -install: - - ps: .\tools\update_schema.ps1 - - git submodule update --init --recursive - - net start w3svc -build_script: - - ps: .\run.ps1 default-build /p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISForwardsCompatibilityTests=true -clone_depth: 1 -environment: - global: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - DOTNET_CLI_TELEMETRY_OPTOUT: 1 -test: off -deploy: off -os: Visual Studio 2017 diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 17d90aec31..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,24 +0,0 @@ -# EditorConfig is awesome:http://EditorConfig.org - -# top-most EditorConfig file -root = true - -[*] -indent_style = space -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.cs] -indent_size = 4 -dotnet_sort_system_directives_first = true:warning - -# Xml files -[*.{csproj,config,props,targets,ruleset,config,resx,xml}] -indent_size = 2 - -[*.{json, yml}] -indent_size = 2 - -[*.{ps1,sh}] -indent_size = 4 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 204c7323a3..0000000000 --- a/.gitattributes +++ /dev/null @@ -1,53 +0,0 @@ -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain - -*.jpg binary -*.png binary -*.gif binary - -*.cs text=auto diff=csharp -*.vb text=auto -*.resx text=auto -*.c text=auto -*.cpp text=auto -*.cxx text=auto -*.h text=auto -*.hxx text=auto -*.py text=auto -*.rb text=auto -*.java text=auto -*.html text=auto -*.htm text=auto -*.css text=auto -*.scss text=auto -*.sass text=auto -*.less text=auto -*.js text=auto -*.lisp text=auto -*.clj text=auto -*.sql text=auto -*.php text=auto -*.lua text=auto -*.m text=auto -*.asm text=auto -*.erl text=auto -*.fs text=auto -*.fsx text=auto -*.hs text=auto -*.rc text=auto - -*.vcxproj text=auto -*.csproj text=auto -*.vbproj text=auto -*.fsproj text=auto -*.dbproj text=auto -*.sln text=auto eol=crlf -*.sh eol=lf diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 42ecc5d6c7..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "test/gtest/googletest"] - path = test/gtest/googletest - url = https://github.com/google/googletest diff --git a/.vsts-pipelines/builds/ci-internal-21.yml b/.vsts-pipelines/builds/ci-internal-21.yml deleted file mode 100644 index afb252eae8..0000000000 --- a/.vsts-pipelines/builds/ci-internal-21.yml +++ /dev/null @@ -1,30 +0,0 @@ -trigger: -- release/2.2 - -resources: - repositories: - - repository: buildtools - type: git - name: aspnet-BuildTools - ref: refs/heads/release/2.2 - -phases: -- template: .azure\templates\jobs\default-build.yml@buildtools - parameters: - agentOs: Windows - codeSign: false - buildArgs: /p:BuildServerIIS21=true /p:SkipIISExpressTests=true /p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISForwardsCompatibilityTests=true - beforeBuild: - - powershell: "& ./tools/UpdateIISExpressCertificate.ps1; & ./tools/update_schema.ps1; & ./tools/SetupTestEnvironment.ps1 SetupDumps" - displayName: Prepare repo - afterBuild: - - powershell: "& ./tools/SetupTestEnvironment.ps1 Shutdown" - displayName: Stop AppVerifier - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Upload logs - condition: eq(variables['system.pullrequest.isfork'], false) - inputs: - artifactName: logs - artifactType: Container - pathtoPublish: artifacts/logs \ No newline at end of file diff --git a/.vsts-pipelines/builds/ci-internal.yml b/.vsts-pipelines/builds/ci-internal.yml deleted file mode 100644 index 260baf4536..0000000000 --- a/.vsts-pipelines/builds/ci-internal.yml +++ /dev/null @@ -1,13 +0,0 @@ -trigger: -- master -- release/* - -resources: - repositories: - - repository: buildtools - type: git - name: aspnet-BuildTools - ref: refs/heads/release/2.2 - -phases: -- template: ../templates/build-steps.yml diff --git a/.vsts-pipelines/builds/ci-public.yml b/.vsts-pipelines/builds/ci-public.yml deleted file mode 100644 index 0ed1a241ab..0000000000 --- a/.vsts-pipelines/builds/ci-public.yml +++ /dev/null @@ -1,15 +0,0 @@ -trigger: -- master -- release/* - -# See https://github.com/aspnet/BuildTools -resources: - repositories: - - repository: buildtools - type: github - endpoint: DotNet-Bot GitHub Connection - name: aspnet/BuildTools - ref: refs/heads/release/2.2 - -phases: -- template: ../templates/build-steps.yml diff --git a/.vsts-pipelines/templates/build-steps.yml b/.vsts-pipelines/templates/build-steps.yml deleted file mode 100644 index 4db5633ddc..0000000000 --- a/.vsts-pipelines/templates/build-steps.yml +++ /dev/null @@ -1,88 +0,0 @@ -phases: -- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools - parameters: - agentOs: Windows - phaseName: IIS_Express_Tests - buildArgs: /p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISTests=true /p:SkipIISForwardsCompatibilityTests=true - beforeBuild: - - powershell: "& ./tools/UpdateIISExpressCertificate.ps1; & ./tools/update_schema.ps1; & ./tools/SetupTestEnvironment.ps1 Setup" - displayName: Prepare repo - afterBuild: - - powershell: "& ./tools/SetupTestEnvironment.ps1 Shutdown" - displayName: Stop AppVerifier - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Upload logs - condition: eq(variables['system.pullrequest.isfork'], false) - inputs: - artifactName: logs - artifactType: Container - pathtoPublish: artifacts/logs - -- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools - parameters: - agentOs: Windows - phaseName: IIS_Tests - buildArgs: /p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISExpressTests=true /p:SkipIISForwardsCompatibilityTests=true - beforeBuild: - - powershell: "& ./tools/UpdateIISExpressCertificate.ps1; & ./tools/update_schema.ps1; & ./tools/SetupTestEnvironment.ps1 Setup" - displayName: Prepare repo - afterBuild: - - powershell: "& ./tools/SetupTestEnvironment.ps1 Shutdown" - displayName: Stop AppVerifier - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Upload logs - condition: eq(variables['system.pullrequest.isfork'], false) - inputs: - artifactName: logs - artifactType: Container - pathtoPublish: artifacts/logs - -- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools - parameters: - agentOs: Windows - phaseName: IIS_BackCompat_Tests - buildArgs: /p:SkipIISTests=true /p:SkipIISExpressTests=true /p:SkipIISForwardsCompatibilityTests=true - beforeBuild: - - powershell: "& ./tools/UpdateIISExpressCertificate.ps1; & ./tools/update_schema.ps1; & ./tools/SetupTestEnvironment.ps1 Setup" - displayName: Prepare repo - afterBuild: - - powershell: "& ./tools/SetupTestEnvironment.ps1 Shutdown" - displayName: Stop AppVerifier - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Upload logs - condition: eq(variables['system.pullrequest.isfork'], false) - inputs: - artifactName: logs - artifactType: Container - pathtoPublish: artifacts/logs - -- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools - parameters: - agentOs: Windows - phaseName: IIS_ForwardsCompat_Tests - buildArgs: /p:SkipIISTests=true /p:SkipIISExpressTests=true /p:SkipIISBackwardsCompatibilityTests=true - beforeBuild: - - powershell: "& ./tools/UpdateIISExpressCertificate.ps1; & ./tools/update_schema.ps1; & ./tools/SetupTestEnvironment.ps1 Setup" - displayName: Prepare repo - afterBuild: - - powershell: "& ./tools/SetupTestEnvironment.ps1 Shutdown" - displayName: Stop AppVerifier - condition: always() - - task: PublishBuildArtifacts@1 - displayName: Upload logs - condition: eq(variables['system.pullrequest.isfork'], false) - inputs: - artifactName: logs - artifactType: Container - pathtoPublish: artifacts/logs - -- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools - parameters: - agentOs: macOS - -- template: .vsts-pipelines/templates/phases/default-build.yml@buildtools - parameters: - agentOs: Linux diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index eac4268e4c..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,4 +0,0 @@ -Contributing -====== - -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 1508c66d70..0000000000 --- a/LICENSE.txt +++ /dev/null @@ -1,228 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright (c) .NET Foundation and Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -========================= - -ASP.NET Core Module - -Copyright (c) .NET Foundation -All rights reserved. - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the ""Software""), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/NuGet.config b/NuGet.config deleted file mode 100644 index e32bddfd51..0000000000 --- a/NuGet.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/README.md b/README.md deleted file mode 100644 index 217e6fe345..0000000000 --- a/README.md +++ /dev/null @@ -1,18 +0,0 @@ -ASP.NET Core IISIntegration -======== -This repo hosts the ASP.NET Core middleware for IIS integration and the ASP.NET Core Module. - -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. - -## Building from source -1. Install prerequisites - 1. Visual Studio 2017 - 1. Workload: `Desktop development with C++` - 1. Run `run.ps1 install vs` or install the following components - 1. Additional Component: `Windows 8.1 SDK and UCRT SDK` - 2. Additional Component: `Windows 10 SDK (10.0.15063.0) for Desktop C++ [x86 and x64]` - 2. Workload: `ASP.NET and web development` -2. Clone with submodules - 1. `git clone --recurse-submodules IISIntegration` - 2. OR run `git submodule update --init --recursive` after initial clone -3. `build.cmd` diff --git a/THIRD_PARTY_NOTICES b/THIRD_PARTY_NOTICES deleted file mode 100644 index 12e1c32746..0000000000 --- a/THIRD_PARTY_NOTICES +++ /dev/null @@ -1,42 +0,0 @@ -.NET Core uses third-party libraries or other resources that may be -distributed under licenses different than the .NET Core software. - -In the event that we accidentally failed to list a required notice, please -bring it to our attention. Post an issue or email us: - - dotnet@microsoft.com - -The attached notices are provided for information only. - - -License notice for googletest ------------------------------------- - -"Copyright 2008, Google Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." diff --git a/build.cmd b/build.cmd deleted file mode 100644 index c0050bda12..0000000000 --- a/build.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE" diff --git a/build.sh b/build.sh deleted file mode 100755 index 98a4b22765..0000000000 --- a/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) -chmod +x "$DIR/run.sh"; sync -"$DIR/run.sh" default-build "$@" diff --git a/korebuild-lock.txt b/korebuild-lock.txt deleted file mode 100644 index 0055dcb41f..0000000000 --- a/korebuild-lock.txt +++ /dev/null @@ -1,2 +0,0 @@ -version:2.2.0-preview2-20181019.5 -commithash:84a1c04b13bd7127728fee91989db8f2f58c8781 diff --git a/mv_to_src.sh b/mv_to_src.sh new file mode 100644 index 0000000000..2360a52087 --- /dev/null +++ b/mv_to_src.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +dir="$(pwd)" +name="IISIntegration" + +if [ "$skip_src" != false ]; then + echo "Moving $dir into src/$name/" + if [ -d "src/" ]; then + git mv src/ src_tmp/ + fi + mkdir -p "src/$name" + if [ -d "src_tmp/" ]; then + git mv src_tmp/ "src/$name/src/" + fi +fi + +files_to_mv=(NuGetPackageVerifier.json .gitignore README.md version.props Directory.Build.props Directory.Build.targets *.sln shared test tools samples build NuGet benchmarks korebuild.json nuget) +for f in "${files_to_mv[@]}"; do + if [ -e $f ]; then + echo "Moving $f" + git mv $f "src/$name/$f" + fi +done + +files_to_rm=(build.sh build.cmd run.cmd run.sh run.ps1 NuGet.config korebuild-lock.txt .github .vsts-pipelines .vscode .appveyor.yml .travis.yml CONTRIBUTING.md) +for f in "${files_to_rm[@]}"; do + if [ -e $f ]; then + echo "Removing $f" + git rm -r $f + fi +done + +echo "Reorganize source code from aspnet/$name into a subfolder" > .git/COMMIT_EDITMSG +echo "" >> .git/COMMIT_EDITMSG +echo "Prior to reorg, this source existed at https://github.com/aspnet/$name/tree/$(git rev-parse HEAD)" >> .git/COMMIT_EDITMSG \ No newline at end of file diff --git a/run.cmd b/run.cmd deleted file mode 100644 index d52d5c7e68..0000000000 --- a/run.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/run.ps1 b/run.ps1 deleted file mode 100644 index 34604c7175..0000000000 --- a/run.ps1 +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env powershell -#requires -version 4 - -<# -.SYNOPSIS -Executes KoreBuild commands. - -.DESCRIPTION -Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`. - -.PARAMETER Command -The KoreBuild command to run. - -.PARAMETER Path -The folder to build. Defaults to the folder containing this script. - -.PARAMETER Channel -The channel of KoreBuild to download. Overrides the value from the config file. - -.PARAMETER DotNetHome -The directory where .NET Core tools will be stored. - -.PARAMETER ToolsSource -The base url where build tools can be downloaded. Overrides the value from the config file. - -.PARAMETER Update -Updates KoreBuild to the latest version even if a lock file is present. - -.PARAMETER Reinstall -Re-installs KoreBuild - -.PARAMETER ConfigFile -The path to the configuration file that stores values. Defaults to korebuild.json. - -.PARAMETER ToolsSourceSuffix -The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores. - -.PARAMETER CI -Sets up CI specific settings and variables. - -.PARAMETER Arguments -Arguments to be passed to the command - -.NOTES -This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be. -When the lockfile is not present, KoreBuild will create one using latest available version from $Channel. - -The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set -in the file are overridden by command line parameters. - -.EXAMPLE -Example config file: -```json -{ - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", - "channel": "master", - "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" -} -``` -#> -[CmdletBinding(PositionalBinding = $false)] -param( - [Parameter(Mandatory = $true, Position = 0)] - [string]$Command, - [string]$Path = $PSScriptRoot, - [Alias('c')] - [string]$Channel, - [Alias('d')] - [string]$DotNetHome, - [Alias('s')] - [string]$ToolsSource, - [Alias('u')] - [switch]$Update, - [switch]$Reinstall, - [string]$ToolsSourceSuffix, - [string]$ConfigFile = $null, - [switch]$CI, - [Parameter(ValueFromRemainingArguments = $true)] - [string[]]$Arguments -) - -Set-StrictMode -Version 2 -$ErrorActionPreference = 'Stop' - -# -# Functions -# - -function Get-KoreBuild { - - $lockFile = Join-Path $Path 'korebuild-lock.txt' - - if (!(Test-Path $lockFile) -or $Update) { - Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix - } - - $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 - if (!$version) { - Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'" - } - $version = $version.TrimStart('version:').Trim() - $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version) - - if ($Reinstall -and (Test-Path $korebuildPath)) { - Remove-Item -Force -Recurse $korebuildPath - } - - if (!(Test-Path $korebuildPath)) { - Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version" - New-Item -ItemType Directory -Path $korebuildPath | Out-Null - $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip" - - try { - $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" - Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix - if (Get-Command -Name 'Microsoft.PowerShell.Archive\Expand-Archive' -ErrorAction Ignore) { - # Use built-in commands where possible as they are cross-plat compatible - Microsoft.PowerShell.Archive\Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath - } - else { - # Fallback to old approach for old installations of PowerShell - Add-Type -AssemblyName System.IO.Compression.FileSystem - [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath) - } - } - catch { - Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore - throw - } - finally { - Remove-Item $tmpfile -ErrorAction Ignore - } - } - - return $korebuildPath -} - -function Join-Paths([string]$path, [string[]]$childPaths) { - $childPaths | ForEach-Object { $path = Join-Path $path $_ } - return $path -} - -function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) { - if ($RemotePath -notlike 'http*') { - Copy-Item $RemotePath $LocalPath - return - } - - $retries = 10 - while ($retries -gt 0) { - $retries -= 1 - try { - Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath - return - } - catch { - Write-Verbose "Request failed. $retries retries remaining" - } - } - - Write-Error "Download failed: '$RemotePath'." -} - -# -# Main -# - -# Load configuration or set defaults - -$Path = Resolve-Path $Path -if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' } - -if (Test-Path $ConfigFile) { - try { - $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json - if ($config) { - if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } - if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} - } - } - catch { - Write-Host -ForegroundColor Red $Error[0] - Write-Error "$ConfigFile contains invalid JSON." - exit 1 - } -} - -if (!$DotNetHome) { - $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } ` - elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} ` - elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}` - else { Join-Path $PSScriptRoot '.dotnet'} -} - -if (!$Channel) { $Channel = 'master' } -if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } - -# Execute - -$korebuildPath = Get-KoreBuild -Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') - -try { - Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI - Invoke-KoreBuildCommand $Command @Arguments -} -finally { - Remove-Module 'KoreBuild' -ErrorAction Ignore -} diff --git a/run.sh b/run.sh deleted file mode 100755 index 4c1fed5646..0000000000 --- a/run.sh +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# -# variables -# - -RESET="\033[0m" -RED="\033[0;31m" -YELLOW="\033[0;33m" -MAGENTA="\033[0;95m" -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" -verbose=false -update=false -reinstall=false -repo_path="$DIR" -channel='' -tools_source='' -tools_source_suffix='' -ci=false - -# -# Functions -# -__usage() { - echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] ...]" - echo "" - echo "Arguments:" - echo " command The command to be run." - echo " ... Arguments passed to the command. Variable number of arguments allowed." - echo "" - echo "Options:" - echo " --verbose Show verbose output." - echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." - echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." - echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." - echo " --path The directory to build. Defaults to the directory containing the script." - echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." - echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings." - echo " -u|--update Update to the latest KoreBuild even if the lock file is present." - echo " --reinstall Reinstall KoreBuild." - echo " --ci Apply CI specific settings and environment variables." - echo "" - echo "Description:" - echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." - echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." - - if [[ "${1:-}" != '--no-exit' ]]; then - exit 2 - fi -} - -get_korebuild() { - local version - local lock_file="$repo_path/korebuild-lock.txt" - if [ ! -f "$lock_file" ] || [ "$update" = true ]; then - __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix" - fi - version="$(grep 'version:*' -m 1 "$lock_file")" - if [[ "$version" == '' ]]; then - __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" - return 1 - fi - version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" - local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" - - if [ "$reinstall" = true ] && [ -d "$korebuild_path" ]; then - rm -rf "$korebuild_path" - fi - - { - if [ ! -d "$korebuild_path" ]; then - mkdir -p "$korebuild_path" - local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" - tmpfile="$(mktemp)" - echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" - if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then - unzip -q -d "$korebuild_path" "$tmpfile" - fi - rm "$tmpfile" || true - fi - - source "$korebuild_path/KoreBuild.sh" - } || { - if [ -d "$korebuild_path" ]; then - echo "Cleaning up after failed installation" - rm -rf "$korebuild_path" || true - fi - return 1 - } -} - -__error() { - echo -e "${RED}error: $*${RESET}" 1>&2 -} - -__warn() { - echo -e "${YELLOW}warning: $*${RESET}" -} - -__machine_has() { - hash "$1" > /dev/null 2>&1 - return $? -} - -__get_remote_file() { - local remote_path=$1 - local local_path=$2 - local remote_path_suffix=$3 - - if [[ "$remote_path" != 'http'* ]]; then - cp "$remote_path" "$local_path" - return 0 - fi - - local failed=false - if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true - else - failed=true - fi - - if [ "$failed" = true ] && __machine_has curl; then - failed=false - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true - fi - - if [ "$failed" = true ]; then - __error "Download failed: $remote_path" 1>&2 - return 1 - fi -} - -# -# main -# - -command="${1:-}" -shift - -while [[ $# -gt 0 ]]; do - case $1 in - -\?|-h|--help) - __usage --no-exit - exit 0 - ;; - -c|--channel|-Channel) - shift - channel="${1:-}" - [ -z "$channel" ] && __usage - ;; - --config-file|-ConfigFile) - shift - config_file="${1:-}" - [ -z "$config_file" ] && __usage - if [ ! -f "$config_file" ]; then - __error "Invalid value for --config-file. $config_file does not exist." - exit 1 - fi - ;; - -d|--dotnet-home|-DotNetHome) - shift - DOTNET_HOME="${1:-}" - [ -z "$DOTNET_HOME" ] && __usage - ;; - --path|-Path) - shift - repo_path="${1:-}" - [ -z "$repo_path" ] && __usage - ;; - -s|--tools-source|-ToolsSource) - shift - tools_source="${1:-}" - [ -z "$tools_source" ] && __usage - ;; - --tools-source-suffix|-ToolsSourceSuffix) - shift - tools_source_suffix="${1:-}" - [ -z "$tools_source_suffix" ] && __usage - ;; - -u|--update|-Update) - update=true - ;; - --reinstall|-[Rr]einstall) - reinstall=true - ;; - --ci|-[Cc][Ii]) - ci=true - ;; - --verbose|-Verbose) - verbose=true - ;; - --) - shift - break - ;; - *) - break - ;; - esac - shift -done - -if ! __machine_has unzip; then - __error 'Missing required command: unzip' - exit 1 -fi - -if ! __machine_has curl && ! __machine_has wget; then - __error 'Missing required command. Either wget or curl is required.' - exit 1 -fi - -[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json" -if [ -f "$config_file" ]; then - if __machine_has jq ; then - if jq '.' "$config_file" >/dev/null ; then - config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" - config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" - else - __error "$config_file contains invalid JSON." - exit 1 - fi - elif __machine_has python ; then - if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then - config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" - config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" - else - __error "$config_file contains invalid JSON." - exit 1 - fi - elif __machine_has python3 ; then - if python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then - config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" - config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" - else - __error "$config_file contains invalid JSON." - exit 1 - fi - else - __error 'Missing required command: jq or python. Could not parse the JSON file.' - exit 1 - fi - - [ ! -z "${config_channel:-}" ] && channel="$config_channel" - [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" -fi - -[ -z "$channel" ] && channel='master' -[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' - -get_korebuild -set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" "$ci" -invoke_korebuild_command "$command" "$@" diff --git a/.gitignore b/src/IISIntegration/.gitignore similarity index 100% rename from .gitignore rename to src/IISIntegration/.gitignore diff --git a/Directory.Build.props b/src/IISIntegration/Directory.Build.props similarity index 100% rename from Directory.Build.props rename to src/IISIntegration/Directory.Build.props diff --git a/Directory.Build.targets b/src/IISIntegration/Directory.Build.targets similarity index 100% rename from Directory.Build.targets rename to src/IISIntegration/Directory.Build.targets diff --git a/IISIntegration.NoV1.sln b/src/IISIntegration/IISIntegration.NoV1.sln similarity index 100% rename from IISIntegration.NoV1.sln rename to src/IISIntegration/IISIntegration.NoV1.sln diff --git a/IISIntegration.sln b/src/IISIntegration/IISIntegration.sln similarity index 100% rename from IISIntegration.sln rename to src/IISIntegration/IISIntegration.sln diff --git a/NuGetPackageVerifier.json b/src/IISIntegration/NuGetPackageVerifier.json similarity index 100% rename from NuGetPackageVerifier.json rename to src/IISIntegration/NuGetPackageVerifier.json diff --git a/NuGetPackageVerifier.xplat.json b/src/IISIntegration/NuGetPackageVerifier.xplat.json similarity index 100% rename from NuGetPackageVerifier.xplat.json rename to src/IISIntegration/NuGetPackageVerifier.xplat.json diff --git a/benchmarks/IIS.Performance/FirstRequestConfig.cs b/src/IISIntegration/benchmarks/IIS.Performance/FirstRequestConfig.cs similarity index 100% rename from benchmarks/IIS.Performance/FirstRequestConfig.cs rename to src/IISIntegration/benchmarks/IIS.Performance/FirstRequestConfig.cs diff --git a/benchmarks/IIS.Performance/IIS.Performance.csproj b/src/IISIntegration/benchmarks/IIS.Performance/IIS.Performance.csproj similarity index 100% rename from benchmarks/IIS.Performance/IIS.Performance.csproj rename to src/IISIntegration/benchmarks/IIS.Performance/IIS.Performance.csproj diff --git a/benchmarks/IIS.Performance/PlaintextBenchmark.cs b/src/IISIntegration/benchmarks/IIS.Performance/PlaintextBenchmark.cs similarity index 100% rename from benchmarks/IIS.Performance/PlaintextBenchmark.cs rename to src/IISIntegration/benchmarks/IIS.Performance/PlaintextBenchmark.cs diff --git a/benchmarks/IIS.Performance/StartupTimeBenchmark.cs b/src/IISIntegration/benchmarks/IIS.Performance/StartupTimeBenchmark.cs similarity index 100% rename from benchmarks/IIS.Performance/StartupTimeBenchmark.cs rename to src/IISIntegration/benchmarks/IIS.Performance/StartupTimeBenchmark.cs diff --git a/build/Build.Settings b/src/IISIntegration/build/Build.Settings similarity index 100% rename from build/Build.Settings rename to src/IISIntegration/build/Build.Settings diff --git a/build/Config.Definitions.Props b/src/IISIntegration/build/Config.Definitions.Props similarity index 100% rename from build/Config.Definitions.Props rename to src/IISIntegration/build/Config.Definitions.Props diff --git a/build/Key.snk b/src/IISIntegration/build/Key.snk similarity index 100% rename from build/Key.snk rename to src/IISIntegration/build/Key.snk diff --git a/build/applicationhost.config b/src/IISIntegration/build/applicationhost.config similarity index 100% rename from build/applicationhost.config rename to src/IISIntegration/build/applicationhost.config diff --git a/build/applicationhost.iis.config b/src/IISIntegration/build/applicationhost.iis.config similarity index 100% rename from build/applicationhost.iis.config rename to src/IISIntegration/build/applicationhost.iis.config diff --git a/build/assets.props b/src/IISIntegration/build/assets.props similarity index 100% rename from build/assets.props rename to src/IISIntegration/build/assets.props diff --git a/build/buildpipeline/pipeline.groovy b/src/IISIntegration/build/buildpipeline/pipeline.groovy similarity index 96% rename from build/buildpipeline/pipeline.groovy rename to src/IISIntegration/build/buildpipeline/pipeline.groovy index 7ccbca0b2a..13fd8d9add 100644 --- a/build/buildpipeline/pipeline.groovy +++ b/src/IISIntegration/build/buildpipeline/pipeline.groovy @@ -1,18 +1,18 @@ -import org.dotnet.ci.pipelines.Pipeline - -def windowsPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows.groovy') - -def configurations = [ - 'Debug', - 'Release' -] - -configurations.each { configuration -> - - def params = [ - 'Configuration': configuration - ] - - windowsPipeline.triggerPipelineOnEveryGithubPR("Windows ${configuration} x64 Build", params) - windowsPipeline.triggerPipelineOnGithubPush(params) -} +import org.dotnet.ci.pipelines.Pipeline + +def windowsPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows.groovy') + +def configurations = [ + 'Debug', + 'Release' +] + +configurations.each { configuration -> + + def params = [ + 'Configuration': configuration + ] + + windowsPipeline.triggerPipelineOnEveryGithubPR("Windows ${configuration} x64 Build", params) + windowsPipeline.triggerPipelineOnGithubPush(params) +} diff --git a/build/buildpipeline/windows-appverif.groovy b/src/IISIntegration/build/buildpipeline/windows-appverif.groovy similarity index 100% rename from build/buildpipeline/windows-appverif.groovy rename to src/IISIntegration/build/buildpipeline/windows-appverif.groovy diff --git a/build/buildpipeline/windows.groovy b/src/IISIntegration/build/buildpipeline/windows.groovy similarity index 98% rename from build/buildpipeline/windows.groovy rename to src/IISIntegration/build/buildpipeline/windows.groovy index e3efa6193f..c482e84079 100644 --- a/build/buildpipeline/windows.groovy +++ b/src/IISIntegration/build/buildpipeline/windows.groovy @@ -1,15 +1,15 @@ -@Library('dotnet-ci') _ - -// 'node' indicates to Jenkins that the enclosed block runs on a node that matches -// the label 'windows-with-vs' -simpleNode('Windows.10.Amd64.EnterpriseRS3.ASPNET.Open') { - stage ('Checking out source') { - checkout scm - bat 'git submodule update --init --recursive' - } - stage ('Build') { - def logFolder = getLogFolder() - def environment = "\$env:ASPNETCORE_TEST_LOG_DIR='${WORKSPACE}\\${logFolder}'" - bat "powershell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command \"${environment};&.\\tools\\SetupTestEnvironment.ps1 SetupDumps;&.\\tools\\update_schema.ps1;&.\\tools\\UpdateIISExpressCertificate.ps1;&.\\run.cmd -CI default-build /p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISForwardsCompatibilityTests=true /p:Configuration=${params.Configuration}\";" - } -} +@Library('dotnet-ci') _ + +// 'node' indicates to Jenkins that the enclosed block runs on a node that matches +// the label 'windows-with-vs' +simpleNode('Windows.10.Amd64.EnterpriseRS3.ASPNET.Open') { + stage ('Checking out source') { + checkout scm + bat 'git submodule update --init --recursive' + } + stage ('Build') { + def logFolder = getLogFolder() + def environment = "\$env:ASPNETCORE_TEST_LOG_DIR='${WORKSPACE}\\${logFolder}'" + bat "powershell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command \"${environment};&.\\tools\\SetupTestEnvironment.ps1 SetupDumps;&.\\tools\\update_schema.ps1;&.\\tools\\UpdateIISExpressCertificate.ps1;&.\\run.cmd -CI default-build /p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISForwardsCompatibilityTests=true /p:Configuration=${params.Configuration}\";" + } +} diff --git a/build/dependencies.props b/src/IISIntegration/build/dependencies.props similarity index 100% rename from build/dependencies.props rename to src/IISIntegration/build/dependencies.props diff --git a/build/functional-test-assets.targets b/src/IISIntegration/build/functional-test-assets.targets similarity index 100% rename from build/functional-test-assets.targets rename to src/IISIntegration/build/functional-test-assets.targets diff --git a/build/launchSettings.json b/src/IISIntegration/build/launchSettings.json similarity index 100% rename from build/launchSettings.json rename to src/IISIntegration/build/launchSettings.json diff --git a/build/native.targets b/src/IISIntegration/build/native.targets similarity index 100% rename from build/native.targets rename to src/IISIntegration/build/native.targets diff --git a/build/repo.props b/src/IISIntegration/build/repo.props similarity index 100% rename from build/repo.props rename to src/IISIntegration/build/repo.props diff --git a/build/repo.targets b/src/IISIntegration/build/repo.targets similarity index 100% rename from build/repo.targets rename to src/IISIntegration/build/repo.targets diff --git a/build/sources.props b/src/IISIntegration/build/sources.props similarity index 100% rename from build/sources.props rename to src/IISIntegration/build/sources.props diff --git a/build/testsite.props b/src/IISIntegration/build/testsite.props similarity index 100% rename from build/testsite.props rename to src/IISIntegration/build/testsite.props diff --git a/korebuild.json b/src/IISIntegration/korebuild.json similarity index 100% rename from korebuild.json rename to src/IISIntegration/korebuild.json diff --git a/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec b/src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec similarity index 100% rename from nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec rename to src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModule.nuspec diff --git a/nuget/Microsoft.AspNetCore.AspNetCoreModule.props b/src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModule.props similarity index 100% rename from nuget/Microsoft.AspNetCore.AspNetCoreModule.props rename to src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModule.props diff --git a/nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.nuspec b/src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.nuspec similarity index 100% rename from nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.nuspec rename to src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.nuspec diff --git a/nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.props.in b/src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.props.in similarity index 100% rename from nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.props.in rename to src/IISIntegration/nuget/Microsoft.AspNetCore.AspNetCoreModuleV2.props.in diff --git a/samples/IISSample/IISSample.csproj b/src/IISIntegration/samples/IISSample/IISSample.csproj similarity index 100% rename from samples/IISSample/IISSample.csproj rename to src/IISIntegration/samples/IISSample/IISSample.csproj diff --git a/samples/IISSample/Properties/launchSettings.json b/src/IISIntegration/samples/IISSample/Properties/launchSettings.json similarity index 100% rename from samples/IISSample/Properties/launchSettings.json rename to src/IISIntegration/samples/IISSample/Properties/launchSettings.json diff --git a/samples/IISSample/Startup.cs b/src/IISIntegration/samples/IISSample/Startup.cs similarity index 100% rename from samples/IISSample/Startup.cs rename to src/IISIntegration/samples/IISSample/Startup.cs diff --git a/samples/IISSample/web.config b/src/IISIntegration/samples/IISSample/web.config similarity index 100% rename from samples/IISSample/web.config rename to src/IISIntegration/samples/IISSample/web.config diff --git a/samples/NativeIISSample/NativeIISSample.csproj b/src/IISIntegration/samples/NativeIISSample/NativeIISSample.csproj similarity index 100% rename from samples/NativeIISSample/NativeIISSample.csproj rename to src/IISIntegration/samples/NativeIISSample/NativeIISSample.csproj diff --git a/samples/NativeIISSample/Properties/launchSettings.json b/src/IISIntegration/samples/NativeIISSample/Properties/launchSettings.json similarity index 100% rename from samples/NativeIISSample/Properties/launchSettings.json rename to src/IISIntegration/samples/NativeIISSample/Properties/launchSettings.json diff --git a/samples/NativeIISSample/Startup.cs b/src/IISIntegration/samples/NativeIISSample/Startup.cs similarity index 100% rename from samples/NativeIISSample/Startup.cs rename to src/IISIntegration/samples/NativeIISSample/Startup.cs diff --git a/samples/NativeIISSample/web.config b/src/IISIntegration/samples/NativeIISSample/web.config similarity index 100% rename from samples/NativeIISSample/web.config rename to src/IISIntegration/samples/NativeIISSample/web.config diff --git a/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/AspNetCore.vcxproj diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/application.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/application.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/application.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/application.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/applicationmanager.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/applicationmanager.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/applicationmanager.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/applicationmanager.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/aspnetcoreconfig.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/aspnetcoreconfig.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/aspnetcoreconfig.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/aspnetcoreconfig.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/debugutil.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/debugutil.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/debugutil.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/debugutil.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/environmentvariablehash.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/environmentvariablehash.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/environmentvariablehash.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/environmentvariablehash.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/filewatcher.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/filewatcher.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/filewatcher.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/filewatcher.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/forwarderconnection.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/forwarderconnection.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/forwarderconnection.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/forwarderconnection.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/forwardinghandler.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/forwardinghandler.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/forwardinghandler.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/forwardinghandler.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/path.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/path.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/path.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/path.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/processmanager.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/processmanager.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/processmanager.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/processmanager.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/protocolconfig.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/protocolconfig.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/protocolconfig.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/protocolconfig.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/proxymodule.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/proxymodule.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/proxymodule.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/proxymodule.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/resource.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/resource.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/resource.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/resource.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/responseheaderhash.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/responseheaderhash.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/responseheaderhash.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/responseheaderhash.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/serverprocess.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/serverprocess.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/serverprocess.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/serverprocess.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/sttimer.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/websockethandler.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/websockethandler.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/websockethandler.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/websockethandler.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Inc/winhttphelper.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/winhttphelper.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Inc/winhttphelper.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Inc/winhttphelper.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/Source.def b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Source.def similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/Source.def rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/Source.def diff --git a/src/AspNetCoreModuleV1/AspNetCore/aspnetcore_msg.mc b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/aspnetcore_msg.mc similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/aspnetcore_msg.mc rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/aspnetcore_msg.mc diff --git a/src/AspNetCoreModuleV1/AspNetCore/aspnetcoremodule.rc b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/aspnetcoremodule.rc similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/aspnetcoremodule.rc rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/aspnetcoremodule.rc diff --git a/src/AspNetCoreModuleV1/AspNetCore/resource.h b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/resource.h similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/resource.h rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/resource.h diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/application.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/application.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/application.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/application.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/applicationmanager.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/applicationmanager.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/applicationmanager.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/applicationmanager.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/aspnetcoreconfig.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/aspnetcoreconfig.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/aspnetcoreconfig.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/aspnetcoreconfig.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/filewatcher.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/filewatcher.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/filewatcher.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/filewatcher.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/forwarderconnection.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/forwarderconnection.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/forwarderconnection.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/forwarderconnection.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/forwardinghandler.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/forwardinghandler.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/forwardinghandler.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/forwardinghandler.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/main.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/main.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/main.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/main.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/path.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/path.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/path.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/path.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/precomp.hxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/precomp.hxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/precomp.hxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/precomp.hxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/processmanager.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/processmanager.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/processmanager.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/processmanager.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/protocolconfig.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/protocolconfig.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/protocolconfig.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/protocolconfig.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/proxymodule.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/proxymodule.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/proxymodule.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/proxymodule.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/responseheaderhash.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/responseheaderhash.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/responseheaderhash.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/responseheaderhash.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/serverprocess.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/serverprocess.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/serverprocess.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/serverprocess.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/websockethandler.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/websockethandler.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/websockethandler.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/websockethandler.cxx diff --git a/src/AspNetCoreModuleV1/AspNetCore/src/winhttphelper.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/winhttphelper.cxx similarity index 100% rename from src/AspNetCoreModuleV1/AspNetCore/src/winhttphelper.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/AspNetCore/src/winhttphelper.cxx diff --git a/src/AspNetCoreModuleV1/IISLib/IISLib.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/IISLib.vcxproj similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/IISLib.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/IISLib.vcxproj diff --git a/src/AspNetCoreModuleV1/IISLib/acache.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/acache.cxx similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/acache.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/acache.cxx diff --git a/src/AspNetCoreModuleV1/IISLib/acache.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/acache.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/acache.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/acache.h diff --git a/src/AspNetCoreModuleV1/IISLib/ahutil.cpp b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/ahutil.cpp similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/ahutil.cpp rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/ahutil.cpp diff --git a/src/AspNetCoreModuleV1/IISLib/ahutil.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/ahutil.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/ahutil.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/ahutil.h diff --git a/src/AspNetCoreModuleV1/IISLib/base64.cpp b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/base64.cpp similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/base64.cpp rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/base64.cpp diff --git a/src/AspNetCoreModuleV1/IISLib/base64.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/base64.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/base64.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/base64.h diff --git a/src/AspNetCoreModuleV1/IISLib/buffer.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/buffer.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/buffer.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/buffer.h diff --git a/src/AspNetCoreModuleV1/IISLib/datetime.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/datetime.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/datetime.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/datetime.h diff --git a/src/AspNetCoreModuleV1/IISLib/dbgutil.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/dbgutil.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/dbgutil.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/dbgutil.h diff --git a/src/AspNetCoreModuleV1/IISLib/hashfn.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/hashfn.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/hashfn.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/hashfn.h diff --git a/src/AspNetCoreModuleV1/IISLib/hashtable.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/hashtable.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/hashtable.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/hashtable.h diff --git a/src/AspNetCoreModuleV1/IISLib/listentry.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/listentry.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/listentry.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/listentry.h diff --git a/src/AspNetCoreModuleV1/IISLib/macros.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/macros.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/macros.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/macros.h diff --git a/src/AspNetCoreModuleV1/IISLib/multisz.cpp b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisz.cpp similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/multisz.cpp rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisz.cpp diff --git a/src/AspNetCoreModuleV1/IISLib/multisz.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisz.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/multisz.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisz.h diff --git a/src/AspNetCoreModuleV1/IISLib/multisza.cpp b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisza.cpp similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/multisza.cpp rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisza.cpp diff --git a/src/AspNetCoreModuleV1/IISLib/multisza.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisza.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/multisza.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/multisza.h diff --git a/src/AspNetCoreModuleV1/IISLib/ntassert.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/ntassert.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/ntassert.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/ntassert.h diff --git a/src/AspNetCoreModuleV1/IISLib/percpu.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/percpu.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/percpu.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/percpu.h diff --git a/src/AspNetCoreModuleV1/IISLib/precomp.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/precomp.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/precomp.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/precomp.h diff --git a/src/AspNetCoreModuleV1/IISLib/prime.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/prime.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/prime.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/prime.h diff --git a/src/AspNetCoreModuleV1/IISLib/pudebug.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/pudebug.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/pudebug.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/pudebug.h diff --git a/src/AspNetCoreModuleV1/IISLib/reftrace.c b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/reftrace.c similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/reftrace.c rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/reftrace.c diff --git a/src/AspNetCoreModuleV1/IISLib/reftrace.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/reftrace.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/reftrace.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/reftrace.h diff --git a/src/AspNetCoreModuleV1/IISLib/rwlock.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/rwlock.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/rwlock.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/rwlock.h diff --git a/src/AspNetCoreModuleV1/IISLib/stringa.cpp b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringa.cpp similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/stringa.cpp rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringa.cpp diff --git a/src/AspNetCoreModuleV1/IISLib/stringa.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringa.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/stringa.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringa.h diff --git a/src/AspNetCoreModuleV1/IISLib/stringu.cpp b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringu.cpp similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/stringu.cpp rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringu.cpp diff --git a/src/AspNetCoreModuleV1/IISLib/stringu.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringu.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/stringu.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/stringu.h diff --git a/src/AspNetCoreModuleV1/IISLib/tracelog.c b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/tracelog.c similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/tracelog.c rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/tracelog.c diff --git a/src/AspNetCoreModuleV1/IISLib/tracelog.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/tracelog.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/tracelog.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/tracelog.h diff --git a/src/AspNetCoreModuleV1/IISLib/treehash.h b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/treehash.h similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/treehash.h rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/treehash.h diff --git a/src/AspNetCoreModuleV1/IISLib/util.cxx b/src/IISIntegration/src/AspNetCoreModuleV1/IISLib/util.cxx similarity index 100% rename from src/AspNetCoreModuleV1/IISLib/util.cxx rename to src/IISIntegration/src/AspNetCoreModuleV1/IISLib/util.cxx diff --git a/src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AppOfflineHandler.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ApplicationFactory.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj similarity index 98% rename from src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj index 4b2c6129e8..98c5920ed4 100644 --- a/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj +++ b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/AspNetCore.vcxproj @@ -1,305 +1,305 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {EC82302F-D2F0-4727-99D1-EABC0DD9DC3B} - Win32Proj - AspNetCoreModule - AspNetCore - aspnetcorev2 - false - 10.0.15063.0 - - - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - - Level4 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) - stdafx.h - $(IntDir)$(TargetName).pch - ..\IISLib;.\Inc;..\CommonLib - ProgramDatabase - MultiThreadedDebug - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - true - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - Source.def - UseLinkTimeCodeGeneration - - - ..\Commonlib - - - - - Level4 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) - stdafx.h - $(IntDir)$(TargetName).pch - ..\IISLib;.\Inc;..\CommonLib - ProgramDatabase - MultiThreadedDebug - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - true - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - Source.def - UseLinkTimeCodeGeneration - - - ..\Commonlib - - - - - Level4 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) - ..\IISLib;.\Inc;..\CommonLib - stdafx.h - MultiThreaded - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - false - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - Source.def - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - UseLinkTimeCodeGeneration - - - ..\Commonlib - - - - - Level4 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) - stdafx.h - ..\IISLib;.\Inc;..\CommonLib - MultiThreaded - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - false - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - Source.def - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - UseLinkTimeCodeGeneration - - - ..\Commonlib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - {55494e58-e061-4c4c-a0a8-837008e72f85} - - - {09d9d1d6-2951-4e14-bc35-76a23cf9391a} - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - - - - true - - - true - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {EC82302F-D2F0-4727-99D1-EABC0DD9DC3B} + Win32Proj + AspNetCoreModule + AspNetCore + aspnetcorev2 + false + 10.0.15063.0 + + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + + Level4 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) + stdafx.h + $(IntDir)$(TargetName).pch + ..\IISLib;.\Inc;..\CommonLib + ProgramDatabase + MultiThreadedDebug + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + true + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + Source.def + UseLinkTimeCodeGeneration + + + ..\Commonlib + + + + + Level4 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) + stdafx.h + $(IntDir)$(TargetName).pch + ..\IISLib;.\Inc;..\CommonLib + ProgramDatabase + MultiThreadedDebug + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + true + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + Source.def + UseLinkTimeCodeGeneration + + + ..\Commonlib + + + + + Level4 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) + ..\IISLib;.\Inc;..\CommonLib + stdafx.h + MultiThreaded + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + false + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + Source.def + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + UseLinkTimeCodeGeneration + + + ..\Commonlib + + + + + Level4 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;ASPNETCOREMODULE_EXPORTS;%(PreprocessorDefinitions) + stdafx.h + ..\IISLib;.\Inc;..\CommonLib + MultiThreaded + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + false + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + Source.def + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + UseLinkTimeCodeGeneration + + + ..\Commonlib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + {55494e58-e061-4c4c-a0a8-837008e72f85} + + + {09d9d1d6-2951-4e14-bc35-76a23cf9391a} + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + + + + true + + + true + + + + + + + + + \ No newline at end of file diff --git a/src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/DisconnectHandler.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/HtmlResponses.rc b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/HtmlResponses.rc similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/HtmlResponses.rc rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/HtmlResponses.rc diff --git a/src/AspNetCoreModuleV2/AspNetCore/InProcessShimStaticHtml.htm b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/InProcessShimStaticHtml.htm similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/InProcessShimStaticHtml.htm rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/InProcessShimStaticHtml.htm diff --git a/src/AspNetCoreModuleV2/AspNetCore/OutOfProcessShimStaticHtml.htm b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/OutOfProcessShimStaticHtml.htm similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/OutOfProcessShimStaticHtml.htm rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/OutOfProcessShimStaticHtml.htm diff --git a/src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/PollingAppOfflineApplication.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ServerErrorApplication.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ShimOptions.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/ShimOptions.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ShimOptions.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/ShimOptions.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ShimOptions.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/Source.def b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/Source.def similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/Source.def rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/Source.def diff --git a/src/AspNetCoreModuleV2/AspNetCore/ancm.mof b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ancm.mof similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/ancm.mof rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/ancm.mof diff --git a/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/applicationinfo.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationinfo.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/applicationmanager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/applicationmanager.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/aspnetcore_schema_v2.xml b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/aspnetcore_schema_v2.xml similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/aspnetcore_schema_v2.xml rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/aspnetcore_schema_v2.xml diff --git a/src/AspNetCoreModuleV2/AspNetCore/aspnetcoremodule.rc b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/aspnetcoremodule.rc similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/aspnetcoremodule.rc rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/aspnetcoremodule.rc diff --git a/src/AspNetCoreModuleV2/AspNetCore/dllmain.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/dllmain.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/dllmain.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/dllmain.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/globalmodule.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/globalmodule.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/globalmodule.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/globalmodule.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/proxymodule.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/proxymodule.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/proxymodule.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/proxymodule.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/proxymodule.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/resource.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/resource.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/resource.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/resource.h diff --git a/src/AspNetCoreModuleV2/AspNetCore/stdafx.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/stdafx.cpp similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/stdafx.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/stdafx.cpp diff --git a/src/AspNetCoreModuleV2/AspNetCore/stdafx.h b/src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/stdafx.h similarity index 100% rename from src/AspNetCoreModuleV2/AspNetCore/stdafx.h rename to src/IISIntegration/src/AspNetCoreModuleV2/AspNetCore/stdafx.h diff --git a/src/AspNetCoreModuleV2/CommonLib/BaseOutputManager.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/BaseOutputManager.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/BaseOutputManager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/BaseOutputManager.h diff --git a/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj similarity index 98% rename from src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj index 0ddec2fcb1..2386dfc6ee 100644 --- a/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj +++ b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/CommonLib.vcxproj @@ -1,293 +1,293 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {55494E58-E061-4C4C-A0A8-837008E72F85} - Win32Proj - NewCommon - 10.0.15063.0 - - - - StaticLibrary - true - v141 - Unicode - - - StaticLibrary - false - v141 - true - Unicode - - - StaticLibrary - true - v141 - Unicode - - - StaticLibrary - false - v141 - false - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - true - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - false - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - false - C:\AspNetCoreModule\src\IISLib;$(IncludePath) - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - - Use - Level4 - true - Disabled - false - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - $(IntDir)$(TargetName).pch - stdafx.h - true - MultiThreadedDebug - false - ProgramDatabase - ..\iislib; - true - stdcpp17 - stdafx.h - - - Windows - true - - - - - Use - Level4 - true - Disabled - false - _DEBUG;_LIB;%(PreprocessorDefinitions) - $(IntDir)$(TargetName).pch - stdafx.h - true - ProgramDatabase - false - MultiThreadedDebug - false - ..\iislib; - true - stdcpp17 - stdafx.h - - - Windows - true - - - - - Use - Level4 - true - MaxSpeed - true - true - false - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - $(IntDir)$(TargetName).pch - stdafx.h - true - MultiThreaded - false - ..\iislib; - true - stdcpp17 - stdafx.h - - - Windows - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - true - - - - - Use - Level4 - true - MaxSpeed - true - true - false - NDEBUG;_LIB;%(PreprocessorDefinitions) - $(IntDir)$(TargetName).pch - stdafx.h - true - ..\iislib; - true - - - MultiThreaded - false - stdcpp17 - stdafx.h - - - Windows - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - true - - - ..\iislib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - {4787a64f-9a3e-4867-a55a-70cb4b2b2ffe} - - - - - Document - mc %(FullPath) - Compiling Event Messages ... - %(Filename).rc;%(Filename).h;MSG0409.bin - mc %(FullPath) - Compiling Event Messages ... - %(Filename).rc;%(Filename).h;MSG0409.bin - mc %(FullPath) - Compiling Event Messages ... - %(Filename).rc;%(Filename).h;MSG0409.bin - mc %(FullPath) - Compiling Event Messages ... - %(Filename).rc;%(Filename).h;MSG0409.bin - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {55494E58-E061-4C4C-A0A8-837008E72F85} + Win32Proj + NewCommon + 10.0.15063.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + false + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + true + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + false + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + false + C:\AspNetCoreModule\src\IISLib;$(IncludePath) + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + + Use + Level4 + true + Disabled + false + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + true + MultiThreadedDebug + false + ProgramDatabase + ..\iislib; + true + stdcpp17 + stdafx.h + + + Windows + true + + + + + Use + Level4 + true + Disabled + false + _DEBUG;_LIB;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + true + ProgramDatabase + false + MultiThreadedDebug + false + ..\iislib; + true + stdcpp17 + stdafx.h + + + Windows + true + + + + + Use + Level4 + true + MaxSpeed + true + true + false + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + true + MultiThreaded + false + ..\iislib; + true + stdcpp17 + stdafx.h + + + Windows + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + true + + + + + Use + Level4 + true + MaxSpeed + true + true + false + NDEBUG;_LIB;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + true + ..\iislib; + true + + + MultiThreaded + false + stdcpp17 + stdafx.h + + + Windows + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + true + + + ..\iislib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + {4787a64f-9a3e-4867-a55a-70cb4b2b2ffe} + + + + + Document + mc %(FullPath) + Compiling Event Messages ... + %(Filename).rc;%(Filename).h;MSG0409.bin + mc %(FullPath) + Compiling Event Messages ... + %(Filename).rc;%(Filename).h;MSG0409.bin + mc %(FullPath) + Compiling Event Messages ... + %(Filename).rc;%(Filename).h;MSG0409.bin + mc %(FullPath) + Compiling Event Messages ... + %(Filename).rc;%(Filename).h;MSG0409.bin + + + + + \ No newline at end of file diff --git a/src/AspNetCoreModuleV2/CommonLib/ConfigurationLoadException.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationLoadException.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ConfigurationLoadException.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationLoadException.h diff --git a/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSection.h diff --git a/src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ConfigurationSource.h diff --git a/src/AspNetCoreModuleV2/CommonLib/Environment.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/Environment.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/Environment.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/Environment.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/Environment.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/Environment.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/Environment.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/Environment.h diff --git a/src/AspNetCoreModuleV2/CommonLib/EventLog.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/EventLog.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/EventLog.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/EventLog.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/EventLog.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/EventLog.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/EventLog.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/EventLog.h diff --git a/src/AspNetCoreModuleV2/CommonLib/EventTracing.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/EventTracing.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/EventTracing.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/EventTracing.h diff --git a/src/AspNetCoreModuleV2/CommonLib/FileOutputManager.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/FileOutputManager.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/FileOutputManager.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/FileOutputManager.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/FileOutputManager.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/FileOutputManager.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/FileOutputManager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/FileOutputManager.h diff --git a/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/GlobalVersionUtility.h diff --git a/src/AspNetCoreModuleV2/CommonLib/HandleWrapper.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/HandleWrapper.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/HandleWrapper.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/HandleWrapper.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/HandleWrapper.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/HandleWrapper.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/HandleWrapper.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/HandleWrapper.h diff --git a/src/AspNetCoreModuleV2/CommonLib/IOutputManager.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/IOutputManager.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/IOutputManager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/IOutputManager.h diff --git a/src/AspNetCoreModuleV2/CommonLib/InvalidOperationException.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/InvalidOperationException.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/InvalidOperationException.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/InvalidOperationException.h diff --git a/src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/LoggingHelpers.h diff --git a/src/AspNetCoreModuleV2/CommonLib/ModuleHelpers.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ModuleHelpers.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ModuleHelpers.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ModuleHelpers.h diff --git a/src/AspNetCoreModuleV2/CommonLib/NonCopyable.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/NonCopyable.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/NonCopyable.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/NonCopyable.h diff --git a/src/AspNetCoreModuleV2/CommonLib/NullOutputManager.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/NullOutputManager.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/NullOutputManager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/NullOutputManager.h diff --git a/src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/PipeOutputManager.h diff --git a/src/AspNetCoreModuleV2/CommonLib/ResultException.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ResultException.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ResultException.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ResultException.h diff --git a/src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWExclusiveLock.h diff --git a/src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/SRWSharedLock.h diff --git a/src/AspNetCoreModuleV2/CommonLib/ServerErrorHandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ServerErrorHandler.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/ServerErrorHandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/ServerErrorHandler.h diff --git a/src/AspNetCoreModuleV2/CommonLib/StdWrapper.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StdWrapper.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/StdWrapper.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StdWrapper.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/StdWrapper.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StdWrapper.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/StdWrapper.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StdWrapper.h diff --git a/src/AspNetCoreModuleV2/CommonLib/StringHelpers.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StringHelpers.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/StringHelpers.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StringHelpers.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/StringHelpers.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StringHelpers.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/StringHelpers.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/StringHelpers.h diff --git a/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSection.h diff --git a/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/WebConfigConfigurationSource.h diff --git a/src/AspNetCoreModuleV2/CommonLib/application.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/application.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/application.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/application.h diff --git a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_event.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/aspnetcore_event.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/aspnetcore_event.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/aspnetcore_event.h diff --git a/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/aspnetcore_msg.mc diff --git a/src/AspNetCoreModuleV2/CommonLib/config_utility.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/config_utility.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/config_utility.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/config_utility.h diff --git a/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/debugutil.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/debugutil.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/debugutil.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/debugutil.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/debugutil.h diff --git a/src/AspNetCoreModuleV2/CommonLib/exceptions.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/exceptions.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/exceptions.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/exceptions.h diff --git a/src/AspNetCoreModuleV2/CommonLib/file_utility.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/file_utility.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/file_utility.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/file_utility.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/file_utility.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/file_utility.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/file_utility.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/file_utility.h diff --git a/src/AspNetCoreModuleV2/CommonLib/fx_ver.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/fx_ver.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/fx_ver.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/fx_ver.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/fx_ver.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/fx_ver.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/fx_ver.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/fx_ver.h diff --git a/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxr_utility.h diff --git a/src/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxroptions.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/hostfxroptions.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxroptions.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/hostfxroptions.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/hostfxroptions.h diff --git a/src/AspNetCoreModuleV2/CommonLib/iapplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/iapplication.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/iapplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/iapplication.h diff --git a/src/AspNetCoreModuleV2/CommonLib/irequesthandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/irequesthandler.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/irequesthandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/irequesthandler.h diff --git a/src/AspNetCoreModuleV2/CommonLib/requesthandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/requesthandler.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/requesthandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/requesthandler.h diff --git a/src/AspNetCoreModuleV2/CommonLib/resources.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/resources.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/resources.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/resources.h diff --git a/src/AspNetCoreModuleV2/CommonLib/stdafx.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/stdafx.cpp similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/stdafx.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/stdafx.cpp diff --git a/src/AspNetCoreModuleV2/CommonLib/stdafx.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/stdafx.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/stdafx.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/stdafx.h diff --git a/src/AspNetCoreModuleV2/CommonLib/sttimer.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/sttimer.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/sttimer.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/sttimer.h diff --git a/src/AspNetCoreModuleV2/CommonLib/targetver.h b/src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/targetver.h similarity index 100% rename from src/AspNetCoreModuleV2/CommonLib/targetver.h rename to src/IISIntegration/src/AspNetCoreModuleV2/CommonLib/targetver.h diff --git a/src/AspNetCoreModuleV2/DefaultRules.ruleset b/src/IISIntegration/src/AspNetCoreModuleV2/DefaultRules.ruleset similarity index 100% rename from src/AspNetCoreModuleV2/DefaultRules.ruleset rename to src/IISIntegration/src/AspNetCoreModuleV2/DefaultRules.ruleset diff --git a/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj similarity index 97% rename from src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj index 8a78b19664..15d4ef1317 100644 --- a/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj +++ b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/IISLib.vcxproj @@ -1,206 +1,206 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {09D9D1D6-2951-4E14-BC35-76A23CF9391A} - Win32Proj - IISLib - IISLib - 10.0.15063.0 - - - - StaticLibrary - true - v141 - Unicode - - - StaticLibrary - true - v141 - Unicode - - - StaticLibrary - false - v141 - true - Unicode - - - StaticLibrary - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - ProgramDatabase - MultiThreadedDebug - false - true - true - - - Windows - true - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - ProgramDatabase - MultiThreadedDebug - false - true - true - - - Windows - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - false - true - true - - - Windows - true - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - false - true - true - - - Windows - true - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {09D9D1D6-2951-4E14-BC35-76A23CF9391A} + Win32Proj + IISLib + IISLib + 10.0.15063.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + ProgramDatabase + MultiThreadedDebug + false + true + true + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + ProgramDatabase + MultiThreadedDebug + false + true + true + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + + + Windows + true + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + + + Windows + true + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/AspNetCoreModuleV2/IISLib/acache.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/acache.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/acache.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/acache.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/acache.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/acache.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/acache.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/acache.h diff --git a/src/AspNetCoreModuleV2/IISLib/ahutil.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/ahutil.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/ahutil.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/ahutil.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/ahutil.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/ahutil.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/ahutil.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/ahutil.h diff --git a/src/AspNetCoreModuleV2/IISLib/base64.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/base64.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/base64.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/base64.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/base64.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/base64.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/base64.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/base64.h diff --git a/src/AspNetCoreModuleV2/IISLib/buffer.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/buffer.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/buffer.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/buffer.h diff --git a/src/AspNetCoreModuleV2/IISLib/datetime.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/datetime.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/datetime.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/datetime.h diff --git a/src/AspNetCoreModuleV2/IISLib/dbgutil.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/dbgutil.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/dbgutil.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/dbgutil.h diff --git a/src/AspNetCoreModuleV2/IISLib/hashfn.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/hashfn.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/hashfn.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/hashfn.h diff --git a/src/AspNetCoreModuleV2/IISLib/hashtable.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/hashtable.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/hashtable.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/hashtable.h diff --git a/src/AspNetCoreModuleV2/IISLib/listentry.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/listentry.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/listentry.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/listentry.h diff --git a/src/AspNetCoreModuleV2/IISLib/macros.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/macros.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/macros.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/macros.h diff --git a/src/AspNetCoreModuleV2/IISLib/multisz.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisz.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/multisz.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisz.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/multisz.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisz.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/multisz.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisz.h diff --git a/src/AspNetCoreModuleV2/IISLib/multisza.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisza.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/multisza.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisza.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/multisza.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisza.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/multisza.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/multisza.h diff --git a/src/AspNetCoreModuleV2/IISLib/ntassert.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/ntassert.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/ntassert.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/ntassert.h diff --git a/src/AspNetCoreModuleV2/IISLib/percpu.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/percpu.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/percpu.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/percpu.h diff --git a/src/AspNetCoreModuleV2/IISLib/precomp.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/precomp.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/precomp.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/precomp.h diff --git a/src/AspNetCoreModuleV2/IISLib/prime.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/prime.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/prime.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/prime.h diff --git a/src/AspNetCoreModuleV2/IISLib/reftrace.c b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/reftrace.c similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/reftrace.c rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/reftrace.c diff --git a/src/AspNetCoreModuleV2/IISLib/reftrace.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/reftrace.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/reftrace.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/reftrace.h diff --git a/src/AspNetCoreModuleV2/IISLib/rwlock.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/rwlock.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/rwlock.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/rwlock.h diff --git a/src/AspNetCoreModuleV2/IISLib/stringa.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringa.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/stringa.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringa.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/stringa.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringa.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/stringa.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringa.h diff --git a/src/AspNetCoreModuleV2/IISLib/stringu.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringu.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/stringu.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringu.cpp diff --git a/src/AspNetCoreModuleV2/IISLib/stringu.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringu.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/stringu.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/stringu.h diff --git a/src/AspNetCoreModuleV2/IISLib/tracelog.c b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/tracelog.c similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/tracelog.c rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/tracelog.c diff --git a/src/AspNetCoreModuleV2/IISLib/tracelog.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/tracelog.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/tracelog.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/tracelog.h diff --git a/src/AspNetCoreModuleV2/IISLib/treehash.h b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/treehash.h similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/treehash.h rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/treehash.h diff --git a/src/AspNetCoreModuleV2/IISLib/util.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/IISLib/util.cpp similarity index 100% rename from src/AspNetCoreModuleV2/IISLib/util.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/IISLib/util.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/HtmlResponses.rc b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/HtmlResponses.rc similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/HtmlResponses.rc rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/HtmlResponses.rc diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessOptions.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj similarity index 98% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj index 5e3fe5c6c1..69435f32d6 100644 --- a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj +++ b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRequestHandler.vcxproj @@ -1,276 +1,276 @@ - - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {D57EA297-6DC2-4BC0-8C91-334863327863} - Win32Proj - InProcessRequestHandler - 10.0.15063.0 - InProcessRequestHandler - - - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - - aspnetcorev2_inprocess - - - false - - - false - - - - Use - Level4 - Disabled - WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - stdafx.h - $(IntDir)$(TargetName).pch - ProgramDatabase - MultiThreadedDebug - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - stdcpp17 - stdafx.h - true - - - Windows - true - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - Source.def - UseLinkTimeCodeGeneration - - - - - Use - Level4 - Disabled - WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - stdafx.h - $(IntDir)$(TargetName).pch - ProgramDatabase - MultiThreadedDebug - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - stdcpp17 - stdafx.h - true - - - Windows - true - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - Source.def - UseLinkTimeCodeGeneration - - - - - Level4 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions) - stdafx.h - MultiThreaded - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - stdcpp17 - stdafx.h - true - - - Windows - false - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - Source.def - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - UseLinkTimeCodeGeneration - - - - - Level4 - Use - MaxSpeed - true - true - NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - stdafx.h - MultiThreaded - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - stdcpp17 - stdafx.h - true - - - Windows - false - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - Source.def - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib - UseLinkTimeCodeGeneration - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - {55494e58-e061-4c4c-a0a8-837008e72f85} - - - {09d9d1d6-2951-4e14-bc35-76a23cf9391a} - - - {1533e271-f61b-441b-8b74-59fb61df0552} - - - - - - - - - true - - - - - - - + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {D57EA297-6DC2-4BC0-8C91-334863327863} + Win32Proj + InProcessRequestHandler + 10.0.15063.0 + InProcessRequestHandler + + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + aspnetcorev2_inprocess + + + false + + + false + + + + Use + Level4 + Disabled + WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + stdafx.h + $(IntDir)$(TargetName).pch + ProgramDatabase + MultiThreadedDebug + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + stdcpp17 + stdafx.h + true + + + Windows + true + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + Source.def + UseLinkTimeCodeGeneration + + + + + Use + Level4 + Disabled + WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + stdafx.h + $(IntDir)$(TargetName).pch + ProgramDatabase + MultiThreadedDebug + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + stdcpp17 + stdafx.h + true + + + Windows + true + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + Source.def + UseLinkTimeCodeGeneration + + + + + Level4 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions) + stdafx.h + MultiThreaded + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + stdcpp17 + stdafx.h + true + + + Windows + false + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + Source.def + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + UseLinkTimeCodeGeneration + + + + + Level4 + Use + MaxSpeed + true + true + NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + stdafx.h + MultiThreaded + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + stdcpp17 + stdafx.h + true + + + Windows + false + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + Source.def + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib + UseLinkTimeCodeGeneration + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + {55494e58-e061-4c4c-a0a8-837008e72f85} + + + {09d9d1d6-2951-4e14-bc35-76a23cf9391a} + + + {1533e271-f61b-441b-8b74-59fb61df0552} + + + + + + + + + true + + + + + + + \ No newline at end of file diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRhStaticHtml.htm b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRhStaticHtml.htm similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRhStaticHtml.htm rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/InProcessRhStaticHtml.htm diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/Source.def b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/Source.def similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/Source.def rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/Source.def diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionHandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionHandler.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionHandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionHandler.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/dllmain.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocesshandler.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessrequesthandler.rc b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessrequesthandler.rc similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessrequesthandler.rc rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/inprocessrequesthandler.rc diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/managedexports.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/resource.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/resource.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/resource.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/resource.h diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.cpp diff --git a/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h b/src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h similarity index 100% rename from src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h rename to src/IISIntegration/src/AspNetCoreModuleV2/InProcessRequestHandler/stdafx.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/HtmlResponses.rc b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/HtmlResponses.rc similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/HtmlResponses.rc rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/HtmlResponses.rc diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj similarity index 98% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj index 7d29672fa0..ca2bc0f4aa 100644 --- a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj +++ b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRequestHandler.vcxproj @@ -1,285 +1,285 @@ - - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {7F87406C-A3C8-4139-A68D-E4C344294A67} - Win32Proj - OutOfProcessRequestHandler - 10.0.15063.0 - OutOfProcessRequestHandler - - - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - - aspnetcorev2_outofprocess - - - false - - - false - - - - Use - Level4 - Disabled - WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - stdafx.h - $(IntDir)$(TargetName).pch - ProgramDatabase - MultiThreadedDebug - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - true - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib - Source.def - UseLinkTimeCodeGeneration - - - - - Use - Level4 - Disabled - WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - stdafx.h - $(IntDir)$(TargetName).pch - ProgramDatabase - MultiThreadedDebug - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - true - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib - Source.def - UseLinkTimeCodeGeneration - - - - - Level4 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions) - stdafx.h - MultiThreaded - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - false - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - Source.def - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib - UseLinkTimeCodeGeneration - - - - - Level4 - Use - MaxSpeed - true - true - NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - stdafx.h - MultiThreaded - ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib - true - true - true - false - SyncCThrow - 8Bytes - true - false - true - CompileAsCpp - true - true - stdcpp17 - stdafx.h - - - Windows - false - true - /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) - true - Source.def - kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib - UseLinkTimeCodeGeneration - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - {55494e58-e061-4c4c-a0a8-837008e72f85} - - - {4787a64f-9a3e-4867-a55a-70cb4b2b2ffe} - - - {1533e271-f61b-441b-8b74-59fb61df0552} - - - - - - - - - true - - - - - - - + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {7F87406C-A3C8-4139-A68D-E4C344294A67} + Win32Proj + OutOfProcessRequestHandler + 10.0.15063.0 + OutOfProcessRequestHandler + + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + aspnetcorev2_outofprocess + + + false + + + false + + + + Use + Level4 + Disabled + WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + stdafx.h + $(IntDir)$(TargetName).pch + ProgramDatabase + MultiThreadedDebug + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + true + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib + Source.def + UseLinkTimeCodeGeneration + + + + + Use + Level4 + Disabled + WIN32;_DEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + stdafx.h + $(IntDir)$(TargetName).pch + ProgramDatabase + MultiThreadedDebug + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + true + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib + Source.def + UseLinkTimeCodeGeneration + + + + + Level4 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;REQUESTHANDLER_EXPORTS;%(PreprocessorDefinitions) + stdafx.h + MultiThreaded + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + false + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + Source.def + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib + UseLinkTimeCodeGeneration + + + + + Level4 + Use + MaxSpeed + true + true + NDEBUG;REQUESTHANDLER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + stdafx.h + MultiThreaded + ..\IISLib;..\CommonLib;.\Inc;..\RequestHandlerLib + true + true + true + false + SyncCThrow + 8Bytes + true + false + true + CompileAsCpp + true + true + stdcpp17 + stdafx.h + + + Windows + false + true + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + Source.def + kernel32.lib;user32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;ahadmin.lib;ws2_32.lib;iphlpapi.lib;version.lib;Rpcrt4.lib;winhttp.lib + UseLinkTimeCodeGeneration + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + {55494e58-e061-4c4c-a0a8-837008e72f85} + + + {4787a64f-9a3e-4867-a55a-70cb4b2b2ffe} + + + {1533e271-f61b-441b-8b74-59fb61df0552} + + + + + + + + + true + + + + + + + \ No newline at end of file diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRhStaticHtml.htm b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRhStaticHtml.htm similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRhStaticHtml.htm rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/OutOfProcessRhStaticHtml.htm diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/Source.def b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/Source.def similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/Source.def rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/Source.def diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/dllmain.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwarderconnection.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocessrequesthandler.rc b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocessrequesthandler.rc similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocessrequesthandler.rc rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outofprocessrequesthandler.rc diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/outprocessapplication.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/processmanager.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/protocolconfig.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/resource.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/resource.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/resource.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/resource.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/responseheaderhash.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/serverprocess.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/stdafx.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/url_utility.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/websockethandler.h diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.cpp diff --git a/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h b/src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h similarity index 100% rename from src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h rename to src/IISIntegration/src/AspNetCoreModuleV2/OutOfProcessRequestHandler/winhttphelper.h diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.h diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/RequestHandlerLib.vcxproj b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/RequestHandlerLib.vcxproj similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/RequestHandlerLib.vcxproj rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/RequestHandlerLib.vcxproj diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehash.h diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/environmentvariablehelpers.h diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h diff --git a/src/AspNetCoreModuleV2/RequestHandlerLib/stdafx.h b/src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/stdafx.h similarity index 100% rename from src/AspNetCoreModuleV2/RequestHandlerLib/stdafx.h rename to src/IISIntegration/src/AspNetCoreModuleV2/RequestHandlerLib/stdafx.h diff --git a/src/Directory.Build.props b/src/IISIntegration/src/Directory.Build.props similarity index 100% rename from src/Directory.Build.props rename to src/IISIntegration/src/Directory.Build.props diff --git a/test/Common.FunctionalTests/AppHostConfig/IIS.config b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/AppHostConfig/IIS.config similarity index 100% rename from test/Common.FunctionalTests/AppHostConfig/IIS.config rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/AppHostConfig/IIS.config diff --git a/test/Common.FunctionalTests/AppOfflineTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/AppOfflineTests.cs similarity index 100% rename from test/Common.FunctionalTests/AppOfflineTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/AppOfflineTests.cs diff --git a/test/Common.FunctionalTests/BasicAuthTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/BasicAuthTests.cs similarity index 100% rename from test/Common.FunctionalTests/BasicAuthTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/BasicAuthTests.cs diff --git a/test/Common.FunctionalTests/ClientCertificateFixture.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateFixture.cs similarity index 100% rename from test/Common.FunctionalTests/ClientCertificateFixture.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateFixture.cs diff --git a/test/Common.FunctionalTests/ClientCertificateTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateTests.cs similarity index 100% rename from test/Common.FunctionalTests/ClientCertificateTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateTests.cs diff --git a/test/Common.FunctionalTests/ClientDisconnectStress.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ClientDisconnectStress.cs similarity index 100% rename from test/Common.FunctionalTests/ClientDisconnectStress.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ClientDisconnectStress.cs diff --git a/test/Common.FunctionalTests/CommonStartupTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/CommonStartupTests.cs similarity index 100% rename from test/Common.FunctionalTests/CommonStartupTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/CommonStartupTests.cs diff --git a/test/Common.FunctionalTests/CompressionTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/CompressionTests.cs similarity index 100% rename from test/Common.FunctionalTests/CompressionTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/CompressionTests.cs diff --git a/test/Common.FunctionalTests/ConfigurationChangeTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ConfigurationChangeTests.cs similarity index 100% rename from test/Common.FunctionalTests/ConfigurationChangeTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ConfigurationChangeTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/CompressionTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/CompressionTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/CompressionTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/CompressionTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/EventLogTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EventLogTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/EventLogTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EventLogTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs diff --git a/test/Common.FunctionalTests/Inprocess/FrebTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FrebTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/FrebTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FrebTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/LogPipeTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs diff --git a/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/StartupTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupTests.cs diff --git a/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs similarity index 100% rename from test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs diff --git a/test/Common.FunctionalTests/LogFileTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/LogFileTests.cs similarity index 100% rename from test/Common.FunctionalTests/LogFileTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/LogFileTests.cs diff --git a/test/Common.FunctionalTests/MultiApplicationTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/MultiApplicationTests.cs similarity index 100% rename from test/Common.FunctionalTests/MultiApplicationTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/MultiApplicationTests.cs diff --git a/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs similarity index 100% rename from test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs diff --git a/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs similarity index 100% rename from test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs diff --git a/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs similarity index 100% rename from test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs diff --git a/test/Common.FunctionalTests/PublishedSitesFixture.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/PublishedSitesFixture.cs similarity index 100% rename from test/Common.FunctionalTests/PublishedSitesFixture.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/PublishedSitesFixture.cs diff --git a/test/Common.FunctionalTests/RequiresNewHandler.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/RequiresNewHandler.cs similarity index 100% rename from test/Common.FunctionalTests/RequiresNewHandler.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/RequiresNewHandler.cs diff --git a/test/Common.FunctionalTests/RequiresNewShim.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/RequiresNewShim.cs similarity index 100% rename from test/Common.FunctionalTests/RequiresNewShim.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/RequiresNewShim.cs diff --git a/test/Common.FunctionalTests/ServerAbortTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ServerAbortTests.cs similarity index 100% rename from test/Common.FunctionalTests/ServerAbortTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/ServerAbortTests.cs diff --git a/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs similarity index 100% rename from test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs diff --git a/test/Common.FunctionalTests/SkipVSTSAttribute.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/SkipVSTSAttribute.cs similarity index 100% rename from test/Common.FunctionalTests/SkipVSTSAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/SkipVSTSAttribute.cs diff --git a/test/Common.FunctionalTests/Utilities/AppVerifier.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/AppVerifier.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/AppVerifier.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/AppVerifier.cs diff --git a/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/EventLogHelpers.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs diff --git a/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs diff --git a/test/Common.FunctionalTests/Utilities/Helpers.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/Helpers.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/Helpers.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/Helpers.cs diff --git a/test/Common.FunctionalTests/Utilities/IISCapability.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCapability.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/IISCapability.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCapability.cs diff --git a/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs diff --git a/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs diff --git a/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs diff --git a/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs diff --git a/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs diff --git a/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/LogFileTestBase.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs diff --git a/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs diff --git a/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs similarity index 100% rename from test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs diff --git a/test/Common.FunctionalTests/WindowsAuthTests.cs b/src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/WindowsAuthTests.cs similarity index 100% rename from test/Common.FunctionalTests/WindowsAuthTests.cs rename to src/IISIntegration/src/IISIntegration/test/Common.FunctionalTests/WindowsAuthTests.cs diff --git a/test/Common.Tests/Common.Tests.csproj b/src/IISIntegration/src/IISIntegration/test/Common.Tests/Common.Tests.csproj similarity index 100% rename from test/Common.Tests/Common.Tests.csproj rename to src/IISIntegration/src/IISIntegration/test/Common.Tests/Common.Tests.csproj diff --git a/test/Common.Tests/Utilities/DisposableList.cs b/src/IISIntegration/src/IISIntegration/test/Common.Tests/Utilities/DisposableList.cs similarity index 100% rename from test/Common.Tests/Utilities/DisposableList.cs rename to src/IISIntegration/src/IISIntegration/test/Common.Tests/Utilities/DisposableList.cs diff --git a/test/Common.Tests/Utilities/TestConnections.cs b/src/IISIntegration/src/IISIntegration/test/Common.Tests/Utilities/TestConnections.cs similarity index 100% rename from test/Common.Tests/Utilities/TestConnections.cs rename to src/IISIntegration/src/IISIntegration/test/Common.Tests/Utilities/TestConnections.cs diff --git a/test/Common.Tests/Utilities/TimeoutExtensions.cs b/src/IISIntegration/src/IISIntegration/test/Common.Tests/Utilities/TimeoutExtensions.cs similarity index 100% rename from test/Common.Tests/Utilities/TimeoutExtensions.cs rename to src/IISIntegration/src/IISIntegration/test/Common.Tests/Utilities/TimeoutExtensions.cs diff --git a/test/CommonLibTests/CommonLibTests.vcxproj b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/CommonLibTests.vcxproj similarity index 100% rename from test/CommonLibTests/CommonLibTests.vcxproj rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/CommonLibTests.vcxproj diff --git a/test/CommonLibTests/ConfigUtilityTests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/ConfigUtilityTests.cpp similarity index 100% rename from test/CommonLibTests/ConfigUtilityTests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/ConfigUtilityTests.cpp diff --git a/test/CommonLibTests/FileOutputManagerTests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/FileOutputManagerTests.cpp similarity index 100% rename from test/CommonLibTests/FileOutputManagerTests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/FileOutputManagerTests.cpp diff --git a/test/CommonLibTests/GlobalVersionTests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/GlobalVersionTests.cpp similarity index 100% rename from test/CommonLibTests/GlobalVersionTests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/GlobalVersionTests.cpp diff --git a/test/CommonLibTests/Helpers.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/Helpers.cpp similarity index 100% rename from test/CommonLibTests/Helpers.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/Helpers.cpp diff --git a/test/CommonLibTests/Helpers.h b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/Helpers.h similarity index 100% rename from test/CommonLibTests/Helpers.h rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/Helpers.h diff --git a/test/CommonLibTests/NativeTests.targets b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/NativeTests.targets similarity index 100% rename from test/CommonLibTests/NativeTests.targets rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/NativeTests.targets diff --git a/test/CommonLibTests/PipeOutputManagerTests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/PipeOutputManagerTests.cpp similarity index 100% rename from test/CommonLibTests/PipeOutputManagerTests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/PipeOutputManagerTests.cpp diff --git a/test/CommonLibTests/exception_handler_tests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/exception_handler_tests.cpp similarity index 100% rename from test/CommonLibTests/exception_handler_tests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/exception_handler_tests.cpp diff --git a/test/CommonLibTests/fakeclasses.h b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/fakeclasses.h similarity index 100% rename from test/CommonLibTests/fakeclasses.h rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/fakeclasses.h diff --git a/test/CommonLibTests/hostfxr_utility_tests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/hostfxr_utility_tests.cpp similarity index 100% rename from test/CommonLibTests/hostfxr_utility_tests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/hostfxr_utility_tests.cpp diff --git a/test/CommonLibTests/inprocess_application_tests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/inprocess_application_tests.cpp similarity index 100% rename from test/CommonLibTests/inprocess_application_tests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/inprocess_application_tests.cpp diff --git a/test/CommonLibTests/main.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/main.cpp similarity index 100% rename from test/CommonLibTests/main.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/main.cpp diff --git a/test/CommonLibTests/stdafx.h b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/stdafx.h similarity index 100% rename from test/CommonLibTests/stdafx.h rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/stdafx.h diff --git a/test/CommonLibTests/utility_tests.cpp b/src/IISIntegration/src/IISIntegration/test/CommonLibTests/utility_tests.cpp similarity index 100% rename from test/CommonLibTests/utility_tests.cpp rename to src/IISIntegration/src/IISIntegration/test/CommonLibTests/utility_tests.cpp diff --git a/test/Directory.Build.props b/src/IISIntegration/src/IISIntegration/test/Directory.Build.props similarity index 100% rename from test/Directory.Build.props rename to src/IISIntegration/src/IISIntegration/test/Directory.Build.props diff --git a/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs similarity index 100% rename from test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs diff --git a/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs similarity index 100% rename from test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs diff --git a/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj b/src/IISIntegration/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj similarity index 100% rename from test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj rename to src/IISIntegration/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj diff --git a/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs similarity index 100% rename from test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs diff --git a/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs similarity index 100% rename from test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs diff --git a/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj b/src/IISIntegration/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj similarity index 100% rename from test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj rename to src/IISIntegration/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj diff --git a/test/IIS.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/src/IISIntegration/test/IIS.FunctionalTests/DeployerSelector.cs similarity index 100% rename from test/IIS.FunctionalTests/DeployerSelector.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.FunctionalTests/DeployerSelector.cs diff --git a/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj b/src/IISIntegration/src/IISIntegration/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj similarity index 100% rename from test/IIS.FunctionalTests/IIS.FunctionalTests.csproj rename to src/IISIntegration/src/IISIntegration/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj diff --git a/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs similarity index 100% rename from test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs diff --git a/test/IIS.Shared.FunctionalTests/MofFileTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/MofFileTests.cs similarity index 100% rename from test/IIS.Shared.FunctionalTests/MofFileTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/MofFileTests.cs diff --git a/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs similarity index 100% rename from test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs diff --git a/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs similarity index 100% rename from test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs diff --git a/test/IIS.Shared.FunctionalTests/ServicesTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/ServicesTests.cs similarity index 100% rename from test/IIS.Shared.FunctionalTests/ServicesTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Shared.FunctionalTests/ServicesTests.cs diff --git a/test/IIS.Tests/AppHostConfig/HostableWebCore.config b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/AppHostConfig/HostableWebCore.config similarity index 100% rename from test/IIS.Tests/AppHostConfig/HostableWebCore.config rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/AppHostConfig/HostableWebCore.config diff --git a/test/IIS.Tests/ClientDisconnectTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/ClientDisconnectTests.cs similarity index 100% rename from test/IIS.Tests/ClientDisconnectTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/ClientDisconnectTests.cs diff --git a/test/IIS.Tests/ConnectionIdFeatureTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/ConnectionIdFeatureTests.cs similarity index 100% rename from test/IIS.Tests/ConnectionIdFeatureTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/ConnectionIdFeatureTests.cs diff --git a/test/IIS.Tests/HttpBodyControlFeatureTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/HttpBodyControlFeatureTests.cs similarity index 100% rename from test/IIS.Tests/HttpBodyControlFeatureTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/HttpBodyControlFeatureTests.cs diff --git a/test/IIS.Tests/IIS.Tests.csproj b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/IIS.Tests.csproj similarity index 100% rename from test/IIS.Tests/IIS.Tests.csproj rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/IIS.Tests.csproj diff --git a/test/IIS.Tests/ResponseAbortTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/ResponseAbortTests.cs similarity index 100% rename from test/IIS.Tests/ResponseAbortTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/ResponseAbortTests.cs diff --git a/test/IIS.Tests/StrictTestServerTests.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/StrictTestServerTests.cs similarity index 100% rename from test/IIS.Tests/StrictTestServerTests.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/StrictTestServerTests.cs diff --git a/test/IIS.Tests/TestServerTest.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/TestServerTest.cs similarity index 100% rename from test/IIS.Tests/TestServerTest.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/TestServerTest.cs diff --git a/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs similarity index 100% rename from test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs diff --git a/test/IIS.Tests/Utilities/TestServer.cs b/src/IISIntegration/src/IISIntegration/test/IIS.Tests/Utilities/TestServer.cs similarity index 100% rename from test/IIS.Tests/Utilities/TestServer.cs rename to src/IISIntegration/src/IISIntegration/test/IIS.Tests/Utilities/TestServer.cs diff --git a/test/IISExpress.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/DeployerSelector.cs similarity index 100% rename from test/IISExpress.FunctionalTests/DeployerSelector.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/DeployerSelector.cs diff --git a/test/IISExpress.FunctionalTests/HttpsTests.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/HttpsTests.cs similarity index 100% rename from test/IISExpress.FunctionalTests/HttpsTests.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/HttpsTests.cs diff --git a/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj similarity index 100% rename from test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj diff --git a/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs similarity index 100% rename from test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs diff --git a/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs similarity index 100% rename from test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs diff --git a/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs similarity index 100% rename from test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs diff --git a/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs similarity index 100% rename from test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs diff --git a/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs similarity index 100% rename from test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs diff --git a/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs similarity index 100% rename from test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs diff --git a/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs similarity index 100% rename from test/IISExpress.FunctionalTests/RequiresIISAttribute.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs diff --git a/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs b/src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs similarity index 100% rename from test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs rename to src/IISIntegration/src/IISIntegration/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs diff --git a/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs b/src/IISIntegration/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs rename to src/IISIntegration/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs diff --git a/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs b/src/IISIntegration/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs rename to src/IISIntegration/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs diff --git a/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj b/src/IISIntegration/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj rename to src/IISIntegration/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj diff --git a/test/TestTasks/InjectRequestHandler.cs b/src/IISIntegration/src/IISIntegration/test/TestTasks/InjectRequestHandler.cs similarity index 100% rename from test/TestTasks/InjectRequestHandler.cs rename to src/IISIntegration/src/IISIntegration/test/TestTasks/InjectRequestHandler.cs diff --git a/test/TestTasks/TestTasks.csproj b/src/IISIntegration/src/IISIntegration/test/TestTasks/TestTasks.csproj similarity index 100% rename from test/TestTasks/TestTasks.csproj rename to src/IISIntegration/src/IISIntegration/test/TestTasks/TestTasks.csproj diff --git a/test/WebSites/Directory.Build.props b/src/IISIntegration/src/IISIntegration/test/WebSites/Directory.Build.props similarity index 100% rename from test/WebSites/Directory.Build.props rename to src/IISIntegration/src/IISIntegration/test/WebSites/Directory.Build.props diff --git a/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj similarity index 100% rename from test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj diff --git a/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json similarity index 100% rename from test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json diff --git a/test/WebSites/InProcessWebSite/DummyServer.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/DummyServer.cs similarity index 100% rename from test/WebSites/InProcessWebSite/DummyServer.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/DummyServer.cs diff --git a/test/WebSites/InProcessWebSite/InProcessWebSite.csproj b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/InProcessWebSite.csproj similarity index 100% rename from test/WebSites/InProcessWebSite/InProcessWebSite.csproj rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/InProcessWebSite.csproj diff --git a/test/WebSites/InProcessWebSite/Program.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Program.cs similarity index 100% rename from test/WebSites/InProcessWebSite/Program.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Program.cs diff --git a/test/WebSites/InProcessWebSite/Properties/launchSettings.json b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Properties/launchSettings.json similarity index 100% rename from test/WebSites/InProcessWebSite/Properties/launchSettings.json rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Properties/launchSettings.json diff --git a/test/WebSites/InProcessWebSite/Startup.WebSockets.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.WebSockets.cs similarity index 100% rename from test/WebSites/InProcessWebSite/Startup.WebSockets.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.WebSockets.cs diff --git a/test/WebSites/InProcessWebSite/Startup.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.cs similarity index 100% rename from test/WebSites/InProcessWebSite/Startup.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.cs diff --git a/test/WebSites/InProcessWebSite/web.config b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/web.config similarity index 100% rename from test/WebSites/InProcessWebSite/web.config rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/web.config diff --git a/test/WebSites/InProcessWebSite/wwwroot/static.txt b/src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/wwwroot/static.txt similarity index 100% rename from test/WebSites/InProcessWebSite/wwwroot/static.txt rename to src/IISIntegration/src/IISIntegration/test/WebSites/InProcessWebSite/wwwroot/static.txt diff --git a/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj b/src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj similarity index 100% rename from test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj rename to src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj diff --git a/test/WebSites/OutOfProcessWebSite/Program.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Program.cs similarity index 100% rename from test/WebSites/OutOfProcessWebSite/Program.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Program.cs diff --git a/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json b/src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json similarity index 100% rename from test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json rename to src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json diff --git a/test/WebSites/OutOfProcessWebSite/Startup.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Startup.cs similarity index 100% rename from test/WebSites/OutOfProcessWebSite/Startup.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Startup.cs diff --git a/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt b/src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt similarity index 100% rename from test/WebSites/OutOfProcessWebSite/wwwroot/static.txt rename to src/IISIntegration/src/IISIntegration/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt diff --git a/test/WebSites/StressTestWebSite/Program.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/Program.cs similarity index 100% rename from test/WebSites/StressTestWebSite/Program.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/Program.cs diff --git a/test/WebSites/StressTestWebSite/Properties/launchSettings.json b/src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/Properties/launchSettings.json similarity index 100% rename from test/WebSites/StressTestWebSite/Properties/launchSettings.json rename to src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/Properties/launchSettings.json diff --git a/test/WebSites/StressTestWebSite/Startup.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/Startup.cs similarity index 100% rename from test/WebSites/StressTestWebSite/Startup.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/Startup.cs diff --git a/test/WebSites/StressTestWebSite/StressTestWebSite.csproj b/src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/StressTestWebSite.csproj similarity index 100% rename from test/WebSites/StressTestWebSite/StressTestWebSite.csproj rename to src/IISIntegration/src/IISIntegration/test/WebSites/StressTestWebSite/StressTestWebSite.csproj diff --git a/test/WebSites/shared/SharedStartup/Startup.shared.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/shared/SharedStartup/Startup.shared.cs similarity index 100% rename from test/WebSites/shared/SharedStartup/Startup.shared.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/shared/SharedStartup/Startup.shared.cs diff --git a/test/WebSites/shared/WebSockets/Constants.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/shared/WebSockets/Constants.cs similarity index 100% rename from test/WebSites/shared/WebSockets/Constants.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/shared/WebSockets/Constants.cs diff --git a/test/WebSites/shared/WebSockets/HandshakeHelpers.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/shared/WebSockets/HandshakeHelpers.cs similarity index 100% rename from test/WebSites/shared/WebSockets/HandshakeHelpers.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/shared/WebSockets/HandshakeHelpers.cs diff --git a/test/WebSites/shared/WebSockets/TestStartup.cs b/src/IISIntegration/src/IISIntegration/test/WebSites/shared/WebSockets/TestStartup.cs similarity index 100% rename from test/WebSites/shared/WebSockets/TestStartup.cs rename to src/IISIntegration/src/IISIntegration/test/WebSites/shared/WebSockets/TestStartup.cs diff --git a/test/gtest/gtest.vcxproj b/src/IISIntegration/src/IISIntegration/test/gtest/gtest.vcxproj similarity index 100% rename from test/gtest/gtest.vcxproj rename to src/IISIntegration/src/IISIntegration/test/gtest/gtest.vcxproj diff --git a/src/Microsoft.AspNetCore.Server.IIS/AssemblyInfo.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/AssemblyInfo.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/DuplexStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/DuplexStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/DuplexStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/DuplexStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/EmptyStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/EmptyStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/EmptyStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/EmptyStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/HttpRequestStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpRequestStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/HttpRequestStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpRequestStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/HttpResponseStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpResponseStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/HttpResponseStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpResponseStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/HttpStreamState.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpStreamState.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/HttpStreamState.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpStreamState.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/HttpUpgradeStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpUpgradeStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/HttpUpgradeStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/HttpUpgradeStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISConfigurationData.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.FeatureCollection.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Features.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Features.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Features.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Features.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpConnectionFeature.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpConnectionFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpConnectionFeature.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpConnectionFeature.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestIdentifierFeature.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestIdentifierFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestIdentifierFeature.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestIdentifierFeature.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestLifetimeFeature.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestLifetimeFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestLifetimeFeature.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IHttpRequestLifetimeFeature.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IO.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IO.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IO.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.IO.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Log.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Log.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.Log.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContext.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContextOfT.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContextOfT.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContextOfT.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpContextOfT.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISHttpServer.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISNativeApplication.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISNativeApplication.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISNativeApplication.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISNativeApplication.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerAuthenticationHandler.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerAuthenticationHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISServerAuthenticationHandler.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerAuthenticationHandler.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IISServerSetupFilter.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Flush.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Flush.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Flush.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Flush.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Read.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Read.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Read.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Read.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Write.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Write.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Write.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.Write.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOEngine.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOOperation.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOOperation.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOOperation.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncIOOperation.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncWriteOperationBase.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncWriteOperationBase.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncWriteOperationBase.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/AsyncWriteOperationBase.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/IAsyncIOEngine.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/IAsyncIOEngine.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/IAsyncIOEngine.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/IAsyncIOEngine.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Initialize.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Initialize.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Initialize.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Initialize.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Read.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Read.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Read.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Read.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Write.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Write.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Write.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.Write.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/IO/WebSocketsAsyncIOEngine.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/OutputProducer.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/OutputProducer.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/OutputProducer.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/OutputProducer.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/ReadOnlyStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/ReadOnlyStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/ReadOnlyStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/ReadOnlyStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/Streams.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/Streams.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/Streams.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/Streams.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/ThrowingWasUpgradedWriteOnlyStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/ThrowingWasUpgradedWriteOnlyStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/ThrowingWasUpgradedWriteOnlyStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/ThrowingWasUpgradedWriteOnlyStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/WrappingStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/WrappingStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/WrappingStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/WrappingStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Core/WriteOnlyStream.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/WriteOnlyStream.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Core/WriteOnlyStream.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Core/WriteOnlyStream.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/CoreStrings.resx b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/CoreStrings.resx similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/CoreStrings.resx rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/CoreStrings.resx diff --git a/src/Microsoft.AspNetCore.Server.IIS/HttpContextExtensions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/HttpContextExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/HttpContextExtensions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/HttpContextExtensions.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/IISServerDefaults.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/IISServerDefaults.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/IISServerDefaults.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/IISServerDefaults.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/IISServerOptions.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/IServerVariableFeature.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/IServerVariableFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/IServerVariableFeature.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/IServerVariableFeature.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.csproj diff --git a/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Microsoft.AspNetCore.Server.IIS.targets diff --git a/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/NativeMethods.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/Properties/CoreStrings.Designer.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Properties/CoreStrings.Designer.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/Properties/CoreStrings.Designer.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/Properties/CoreStrings.Designer.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/WebHostBuilderIISExtensions.cs diff --git a/src/Microsoft.AspNetCore.Server.IIS/_._ b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/_._ similarity index 100% rename from src/Microsoft.AspNetCore.Server.IIS/_._ rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IIS/_._ diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/AuthenticationHandler.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/AuthenticationHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/AuthenticationHandler.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/AuthenticationHandler.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/ForwardedTlsConnectionFeature.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/ForwardedTlsConnectionFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/ForwardedTlsConnectionFeature.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/ForwardedTlsConnectionFeature.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/IISDefaults.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISDefaults.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/IISDefaults.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISDefaults.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/IISHostingStartup.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISHostingStartup.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/IISHostingStartup.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISHostingStartup.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/IISMiddleware.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISMiddleware.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/IISMiddleware.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISMiddleware.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/IISOptions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/IISOptions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISOptions.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/IISSetupFilter.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISSetupFilter.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/IISSetupFilter.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/IISSetupFilter.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.csproj diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/Microsoft.AspNetCore.Server.IISIntegration.targets diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/NativeMethods.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/Properties/AssemblyInfo.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/Properties/AssemblyInfo.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/WebHostBuilderIISExtensions.cs diff --git a/src/Microsoft.AspNetCore.Server.IISIntegration/baseline.netcore.json b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.Server.IISIntegration/baseline.netcore.json rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IISIntegration/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ApplicationDeployerFactory.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Http.config diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployerBase.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployerBase.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployerBase.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployerBase.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameterExtensions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameterExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameterExtensions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameterExtensions.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameters.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameters.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameters.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentParameters.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentResult.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentResult.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentResult.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeploymentResult.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISExpressDeployer.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/LoggingHandler.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/Microsoft.AspNetCore.Server.IntegrationTesting.IIS.csproj diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ProcessTracker.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ProcessTracker.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ProcessTracker.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/ProcessTracker.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/RetryHandler.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/RetryHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/RetryHandler.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/RetryHandler.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/WebConfigHelpers.cs diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/XElementExtensions.cs b/src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/XElementExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/XElementExtensions.cs rename to src/IISIntegration/src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/XElementExtensions.cs diff --git a/src/IISIntegration/test/Common.FunctionalTests/AppHostConfig/IIS.config b/src/IISIntegration/test/Common.FunctionalTests/AppHostConfig/IIS.config new file mode 100644 index 0000000000..bc24ef9639 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/AppHostConfig/IIS.config @@ -0,0 +1,740 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/Common.FunctionalTests/AppOfflineTests.cs b/src/IISIntegration/test/Common.FunctionalTests/AppOfflineTests.cs new file mode 100644 index 0000000000..7d8d661ef0 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/AppOfflineTests.cs @@ -0,0 +1,287 @@ +// 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.Net; +using System.Net.Http; +using System.Net.Sockets; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Xunit; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class AppOfflineTests : IISFunctionalTestBase + { + private static readonly TimeSpan RetryDelay = TimeSpan.FromMilliseconds(100); + + private readonly PublishedSitesFixture _fixture; + + public AppOfflineTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task AppOfflineDroppedWhileSiteIsDown_SiteReturns503(HostingModel hostingModel) + { + var deploymentResult = await DeployApp(hostingModel); + + AddAppOffline(deploymentResult.ContentRoot); + + await AssertAppOffline(deploymentResult); + DeletePublishOutput(deploymentResult); + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task LockedAppOfflineDroppedWhileSiteIsDown_SiteReturns503(HostingModel hostingModel) + { + var deploymentResult = await DeployApp(hostingModel); + + // Add app_offline without shared access + using (var stream = File.Open(Path.Combine(deploymentResult.ContentRoot, "app_offline.htm"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None)) + using (var writer = new StreamWriter(stream)) + { + await writer.WriteLineAsync("App if offline but you wouldn't see this message"); + await writer.FlushAsync(); + await AssertAppOffline(deploymentResult, ""); + } + + DeletePublishOutput(deploymentResult); + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess, 500, "500.0")] + [InlineData(HostingModel.OutOfProcess, 502, "502.5")] + public async Task AppOfflineDroppedWhileSiteFailedToStartInShim_AppOfflineServed(HostingModel hostingModel, int statusCode, string content) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel: hostingModel, publish: true); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "nonexistent")); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var result = await deploymentResult.HttpClient.GetAsync("/"); + Assert.Equal(statusCode, (int)result.StatusCode); + Assert.Contains(content, await result.Content.ReadAsStringAsync()); + + AddAppOffline(deploymentResult.ContentRoot); + + await AssertAppOffline(deploymentResult); + DeletePublishOutput(deploymentResult); + } + + [ConditionalFact(Skip = "https://github.com/aspnet/IISIntegration/issues/933")] + public async Task AppOfflineDroppedWhileSiteFailedToStartInRequestHandler_SiteStops_InProcess() + { + var deploymentResult = await DeployApp(HostingModel.InProcess); + + // Set file content to empty so it fails at runtime + File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "Microsoft.AspNetCore.Server.IIS.dll"), ""); + + var result = await deploymentResult.HttpClient.GetAsync("/"); + Assert.Equal(500, (int)result.StatusCode); + Assert.Contains("500.30", await result.Content.ReadAsStringAsync()); + + AddAppOffline(deploymentResult.ContentRoot); + + await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult)); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.ShutdownToken)] + public async Task AppOfflineDroppedWhileSiteStarting_SiteShutsDown_InProcess() + { + // This test often hits a race between debug logging and stdout redirection closing the handle + // we are fine having this race + using (AppVerifier.Disable(DeployerSelector.ServerType, 0x300)) + { + var deploymentResult = await DeployApp(HostingModel.InProcess); + + for (int i = 0; i < 10; i++) + { + // send first request and add app_offline while app is starting + var runningTask = AssertAppOffline(deploymentResult); + + // This test tries to hit a race where we drop app_offline file while + // in process application is starting, application start takes at least 400ms + // so we back off for 100ms to allow request to reach request handler + // Test itself is racy and can result in two scenarios + // 1. ANCM detects app_offline before it starts the request - if AssertAppOffline succeeds we've hit it + // 2. Intended scenario where app starts and then shuts down + // In first case we remove app_offline and try again + await Task.Delay(RetryDelay); + + AddAppOffline(deploymentResult.ContentRoot); + + try + { + await runningTask.DefaultTimeout(); + + // if AssertAppOffline succeeded ANCM have picked up app_offline before starting the app + // try again + RemoveAppOffline(deploymentResult.ContentRoot); + } + catch + { + deploymentResult.AssertWorkerProcessStop(); + return; + } + } + + Assert.True(false); + + } + } + + [ConditionalFact] + public async Task AppOfflineDroppedWhileSiteRunning_SiteShutsDown_InProcess() + { + var deploymentResult = await AssertStarts(HostingModel.InProcess); + + AddAppOffline(deploymentResult.ContentRoot); + + await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult)); + } + + [ConditionalFact] + public async Task AppOfflineDroppedWhileSiteRunning_SiteShutsDown_OutOfProcess() + { + var deploymentResult = await AssertStarts(HostingModel.OutOfProcess); + + // Repeat dropping file and restarting multiple times + for (int i = 0; i < 5; i++) + { + AddAppOffline(deploymentResult.ContentRoot); + await AssertAppOffline(deploymentResult); + RemoveAppOffline(deploymentResult.ContentRoot); + await AssertRunning(deploymentResult); + } + + AddAppOffline(deploymentResult.ContentRoot); + await AssertAppOffline(deploymentResult); + DeletePublishOutput(deploymentResult); + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task AppOfflineDropped_CanRemoveAppOfflineAfterAddingAndSiteWorks(HostingModel hostingModel) + { + var deploymentResult = await DeployApp(hostingModel); + + AddAppOffline(deploymentResult.ContentRoot); + + await AssertAppOffline(deploymentResult); + + RemoveAppOffline(deploymentResult.ContentRoot); + + await AssertRunning(deploymentResult); + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task AppOfflineAddedAndRemovedStress(HostingModel hostingModel) + { + var deploymentResult = await AssertStarts(hostingModel); + + var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => { + var statusCode = (int)response.StatusCode; + Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode); + }); + + for (int i = 0; i < 100; i++) + { + // AddAppOffline might fail if app_offline is being read by ANCM and deleted at the same time + RetryHelper.RetryOperation( + () => AddAppOffline(deploymentResult.ContentRoot), + e => Logger.LogError($"Failed to create app_offline : {e.Message}"), + retryCount: 3, + retryDelayMilliseconds: RetryDelay.Milliseconds); + RemoveAppOffline(deploymentResult.ContentRoot); + } + + try + { + await load; + } + catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException) + { + // IOException in InProcess is fine, just means process stopped + if (hostingModel != HostingModel.InProcess) + { + throw; + } + } + } + + private async Task DeployApp(HostingModel hostingModel = HostingModel.InProcess) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel: hostingModel, publish: true); + + return await DeployAsync(deploymentParameters); + } + + private void AddAppOffline(string appPath, string content = "The app is offline.") + { + File.WriteAllText(Path.Combine(appPath, "app_offline.htm"), content); + } + + private void RemoveAppOffline(string appPath) + { + RetryHelper.RetryOperation( + () => File.Delete(Path.Combine(appPath, "app_offline.htm")), + e => Logger.LogError($"Failed to remove app_offline : {e.Message}"), + retryCount: 3, + retryDelayMilliseconds: RetryDelay.Milliseconds); + } + + private async Task AssertAppOffline(IISDeploymentResult deploymentResult, string expectedResponse = "The app is offline.") + { + var response = await deploymentResult.HttpClient.RetryRequestAsync("HelloWorld", r => r.StatusCode == HttpStatusCode.ServiceUnavailable); + Assert.Equal(expectedResponse, await response.Content.ReadAsStringAsync()); + } + + private async Task AssertStarts(HostingModel hostingModel) + { + var deploymentResult = await DeployApp(hostingModel); + + await AssertRunning(deploymentResult); + + return deploymentResult; + } + + private static async Task AssertRunning(IISDeploymentResult deploymentResult) + { + var response = await deploymentResult.HttpClient.RetryRequestAsync("HelloWorld", r => r.IsSuccessStatusCode); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal("Hello World", responseText); + } + + private void DeletePublishOutput(IISDeploymentResult deploymentResult) + { + foreach (var file in Directory.GetFiles(deploymentResult.ContentRoot, "*", SearchOption.AllDirectories)) + { + // Out of process module dll is allowed to be locked + var name = Path.GetFileName(file); + if (name == "aspnetcore.dll" || name == "aspnetcorev2.dll" || name == "aspnetcorev2_outofprocess.dll") + { + continue; + } + File.Delete(file); + } + } + + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/BasicAuthTests.cs b/src/IISIntegration/test/Common.FunctionalTests/BasicAuthTests.cs new file mode 100644 index 0000000000..d8607db21e --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/BasicAuthTests.cs @@ -0,0 +1,70 @@ +// 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 System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class BasicAuthTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public BasicAuthTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22) + .WithApplicationTypes(ApplicationType.Portable) + .WithAllAncmVersions() + .WithAllHostingModels(); + + [ConditionalTheory] + [RequiresEnvironmentVariable("ASPNETCORE_MODULE_TEST_USER")] + [RequiresIIS(IISCapability.BasicAuthentication)] + [MemberData(nameof(TestVariants))] + public async Task BasicAuthTest(TestVariant variant) + { + var username = Environment.GetEnvironmentVariable("ASPNETCORE_MODULE_TEST_USER"); + var password = Environment.GetEnvironmentVariable("ASPNETCORE_MODULE_TEST_PASSWORD"); + + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.SetAnonymousAuth(enabled: false); + deploymentParameters.SetWindowsAuth(enabled: false); + deploymentParameters.SetBasicAuth(enabled: true); + + // The default in hosting sets windows auth to true. + var deploymentResult = await DeployAsync(deploymentParameters); + var request = new HttpRequestMessage(HttpMethod.Get, "/Auth"); + var byteArray = new UTF8Encoding().GetBytes(username + ":" + password); + request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); + + var response = await deploymentResult.HttpClient.SendAsync(request); + + var responseText = await response.Content.ReadAsStringAsync(); + + if (variant.HostingModel == HostingModel.InProcess) + { + Assert.StartsWith("Windows", responseText); + Assert.Contains(username, responseText); + } + else + { + // We expect out-of-proc not allowing basic auth + Assert.Equal("Windows", responseText); + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateFixture.cs b/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateFixture.cs new file mode 100644 index 0000000000..40b6f2265e --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateFixture.cs @@ -0,0 +1,104 @@ +// 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.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class ClientCertificateFixture : IDisposable + { + private X509Certificate2 _certificate; + private const string _certIssuerPrefix = "CN=IISIntegrationTest_Root"; + + public X509Certificate2 GetOrCreateCertificate() + { + if (_certificate != null) + { + return _certificate; + } + + using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine)) + { + store.Open(OpenFlags.ReadWrite); + var parentKey = CreateKeyMaterial(2048); + + // Create a cert name with a random guid to avoid name conflicts + var parentRequest = new CertificateRequest( + _certIssuerPrefix + Guid.NewGuid().ToString(), + parentKey, HashAlgorithmName.SHA256, + RSASignaturePadding.Pkcs1); + + parentRequest.CertificateExtensions.Add( + new X509BasicConstraintsExtension( + certificateAuthority: true, + hasPathLengthConstraint: false, + pathLengthConstraint: 0, + critical: true)); + + parentRequest.CertificateExtensions.Add( + new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation, critical: true)); + + parentRequest.CertificateExtensions.Add( + new X509SubjectKeyIdentifierExtension(parentRequest.PublicKey, false)); + + var notBefore = DateTimeOffset.Now.AddDays(-1); + var notAfter = DateTimeOffset.Now.AddYears(5); + + var parentCert = parentRequest.CreateSelfSigned(notBefore, notAfter); + + // Need to export/import the certificate to associate the private key with the cert. + var imported = parentCert; + + var export = parentCert.Export(X509ContentType.Pkcs12, ""); + imported = new X509Certificate2(export, "", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); + Array.Clear(export, 0, export.Length); + + // Add the cert to the cert store + _certificate = imported; + + store.Add(certificate: imported); + store.Close(); + return imported; + } + } + + public void Dispose() + { + if (_certificate == null) + { + return; + } + + using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine)) + { + store.Open(OpenFlags.ReadWrite); + store.Remove(_certificate); + + // Remove any extra certs that were left by previous tests. + for (var i = store.Certificates.Count - 1; i >= 0; i--) + { + var cert = store.Certificates[i]; + if (cert.Issuer.StartsWith(_certIssuerPrefix)) + { + store.Remove(cert); + } + } + store.Close(); + } + } + + private RSA CreateKeyMaterial(int minimumKeySize) + { + var rsa = RSA.Create(minimumKeySize); + if (rsa.KeySize < minimumKeySize) + { + throw new InvalidOperationException($"Failed to create a key with a size of {minimumKeySize} bits"); + } + + return rsa; + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateTests.cs b/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateTests.cs new file mode 100644 index 0000000000..43ccc83eff --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/ClientCertificateTests.cs @@ -0,0 +1,108 @@ +// 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 System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.Common; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + [SkipIfNotAdmin] + public class ClientCertificateTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + private readonly ClientCertificateFixture _certFixture; + + public ClientCertificateTests(PublishedSitesFixture fixture, ClientCertificateFixture certFixture) + { + _fixture = fixture; + _certFixture = certFixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) + .WithAllApplicationTypes() + .WithAllAncmVersions() + .WithAllHostingModels(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public Task HttpsNoClientCert_NoClientCert(TestVariant variant) + { + return ClientCertTest(variant, sendClientCert: false); + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public Task HttpsClientCert_GetCertInformation(TestVariant variant) + { + return ClientCertTest(variant, sendClientCert: true); + } + + private async Task ClientCertTest(TestVariant variant, bool sendClientCert) + { + var port = TestPortHelper.GetNextSSLPort(); + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant); + deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/"; + deploymentParameters.AddHttpsToServerConfig(); + + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (a, b, c, d) => true, + ClientCertificateOptions = ClientCertificateOption.Manual, + }; + + X509Certificate2 cert = null; + if (sendClientCert) + { + cert = _certFixture.GetOrCreateCertificate(); + handler.ClientCertificates.Add(cert); + } + + var deploymentResult = await DeployAsync(deploymentParameters); + + var client = deploymentResult.CreateClient(handler); + var response = await client.GetAsync("GetClientCert"); + + var responseText = await response.Content.ReadAsStringAsync(); + + try + { + if (sendClientCert) + { + Assert.Equal($"Enabled;{cert.GetCertHashString()}", responseText); + } + else + { + Assert.Equal("Disabled", responseText); + } + } + catch (Exception ex) + { + Logger.LogError($"Certificate is invalid. Issuer name: {cert.Issuer}"); + using (var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine)) + { + Logger.LogError($"List of current certificates in root store:"); + store.Open(OpenFlags.ReadWrite); + foreach (var otherCert in store.Certificates) + { + Logger.LogError(otherCert.Issuer); + } + store.Close(); + } + throw ex; + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/ClientDisconnectStress.cs b/src/IISIntegration/test/Common.FunctionalTests/ClientDisconnectStress.cs new file mode 100644 index 0000000000..9deeae3f92 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/ClientDisconnectStress.cs @@ -0,0 +1,65 @@ +// 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.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class ClientDisconnectStressTests: FunctionalTestsBase + { + private readonly PublishedSitesFixture _fixture; + + public ClientDisconnectStressTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task ClientDisconnectStress(HostingModel hostingModel) + { + var site = await StartAsync(_fixture.GetBaseDeploymentParameters(hostingModel)); + var maxRequestSize = 1000; + var blockSize = 40; + var random = new Random(); + async Task RunRequests() + { + using (var connection = new TestConnection(site.HttpClient.BaseAddress.Port)) + { + await connection.Send( + "POST /ReadAndFlushEcho HTTP/1.1", + $"Content-Length: {maxRequestSize}", + "Host: localhost", + "Connection: close", + "", + ""); + + var disconnectAfter = random.Next(maxRequestSize); + var data = new byte[blockSize]; + for (int i = 0; i < disconnectAfter / blockSize; i++) + { + await connection.Stream.WriteAsync(data); + } + } + } + + List tasks = new List(); + for (int i = 0; i < 100; i++) + { + tasks.Add(Task.Run(RunRequests)); + } + + await Task.WhenAll(tasks); + + StopServer(); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/CommonStartupTests.cs b/src/IISIntegration/test/Common.FunctionalTests/CommonStartupTests.cs new file mode 100644 index 0000000000..e2bcf2a8f9 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/CommonStartupTests.cs @@ -0,0 +1,44 @@ +// 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.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class CommonStartupTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public CommonStartupTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22) + .WithAllApplicationTypes() + .WithAllAncmVersions() + .WithAllHostingModels(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task StartupStress(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => { + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Hello World", response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); + }); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/CompressionTests.cs b/src/IISIntegration/test/Common.FunctionalTests/CompressionTests.cs new file mode 100644 index 0000000000..c2d0277c4c --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/CompressionTests.cs @@ -0,0 +1,58 @@ +// 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.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISCompressionSiteCollection.Name)] + public abstract class CompressionTests : FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + [Collection(IISTestSiteCollection.Name)] + public class InProc: CompressionTests + { + public InProc(IISTestSiteFixture fixture) : base(fixture) { } + } + + [Collection(OutOfProcessTestSiteCollection.Name)] + public class OutOfProcess: CompressionTests + { + public OutOfProcess(OutOfProcessTestSiteFixture fixture) : base(fixture) { } + } + + [Collection(OutOfProcessV1TestSiteCollection.Name)] + public class OutOfProcessV1: CompressionTests + { + public OutOfProcessV1(OutOfProcessV1TestSiteFixture fixture) : base(fixture) { } + } + + protected CompressionTests(IISTestSiteFixture fixture) : base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task PassesThroughCompression() + { + var request = new HttpRequestMessage(HttpMethod.Get, "/CompressedData"); + + request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); + + var response = await _fixture.Client.SendAsync(request); + Assert.Equal("gzip", response.Content.Headers.ContentEncoding.Single()); + Assert.Equal( + new byte[] { + 0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x0B, 0x63, 0x60, 0xA0, 0x3D, 0x00, 0x00, + 0xCA, 0xC6, 0x88, 0x99, 0x64, 0x00, 0x00, 0x00 }, + await response.Content.ReadAsByteArrayAsync()); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/ConfigurationChangeTests.cs b/src/IISIntegration/test/Common.FunctionalTests/ConfigurationChangeTests.cs new file mode 100644 index 0000000000..099cefb97a --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/ConfigurationChangeTests.cs @@ -0,0 +1,126 @@ +// 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.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Sockets; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class ConfigurationChangeTests : IISFunctionalTestBase + { + private static readonly TimeSpan RetryDelay = TimeSpan.FromMilliseconds(100); + private readonly PublishedSitesFixture _fixture; + + public ConfigurationChangeTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task ConfigurationChangeStopsInProcess() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.InProcess, publish: true); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await deploymentResult.AssertStarts(); + + // Just "touching" web.config should be enough + deploymentResult.ModifyWebConfig(element => {}); + + await deploymentResult.AssertRecycledAsync(); + } + + [ConditionalTheory] + [InlineData(AncmVersion.AspNetCoreModule)] + [InlineData(AncmVersion.AspNetCoreModuleV2)] + public async Task ConfigurationChangeForcesChildProcessRestart(AncmVersion version) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); + deploymentParameters.AncmVersion = version; + + var deploymentResult = await DeployAsync(deploymentParameters); + + var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId"); + + // Just "touching" web.config should be enough + deploymentResult.ModifyWebConfig(element => {}); + + // Have to retry here to allow ANCM to receive notification and react to it + // Verify that worker process gets restarted with new process id + await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore); + } + + [ConditionalFact] + public async Task OutOfProcessToInProcessHostingModelSwitchWorks() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await deploymentResult.AssertStarts(); + + deploymentResult.ModifyWebConfig(element => element + .Descendants("system.webServer") + .Single() + .GetOrAdd("aspNetCore") + .SetAttributeValue("hostingModel", "inprocess")); + + // Have to retry here to allow ANCM to receive notification and react to it + // Verify that inprocess application was created and tried to start + await deploymentResult.HttpClient.RetryRequestAsync("/HelloWorld", r => r.StatusCode == HttpStatusCode.InternalServerError); + + StopServer(); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not find the assembly 'aspnetcorev2_inprocess.dll'", Logger); + } + + [ConditionalTheory] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task ConfigurationTouchedStress(HostingModel hostingModel) + { + var deploymentResult = await DeployAsync(_fixture.GetBaseDeploymentParameters(hostingModel, publish: true)); + + await deploymentResult.AssertStarts(); + var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => { + var statusCode = (int)response.StatusCode; + Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode); + }); + + for (int i = 0; i < 100; i++) + { + // ModifyWebConfig might fail if web.config is being read by IIS + RetryHelper.RetryOperation( + () => deploymentResult.ModifyWebConfig(element => {}), + e => Logger.LogError($"Failed to touch web.config : {e.Message}"), + retryCount: 3, + retryDelayMilliseconds: RetryDelay.Milliseconds); + } + + try + { + await load; + } + catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException) + { + // IOException in InProcess is fine, just means process stopped + if (hostingModel != HostingModel.InProcess) + { + throw; + } + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs new file mode 100644 index 0000000000..6e2d1bc752 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ClientDisconnectTests.cs @@ -0,0 +1,108 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class ClientDisconnectTests: FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public ClientDisconnectTests(IISTestSiteFixture fixture): base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task ServerWorksAfterClientDisconnect() + { + using (var connection = _fixture.CreateTestConnection()) + { + var message = "Hello"; + await connection.Send( + "POST /ReadAndWriteSynchronously HTTP/1.1", + $"Content-Length: {100000}", + "Host: localhost", + "Connection: close", + "", + ""); + + await connection.Send(message); + + await connection.Receive( + "HTTP/1.1 200 OK", + ""); + } + + var response = await _fixture.Client.GetAsync("HelloWorld"); + + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal("Hello World", responseText); + } + + [ConditionalFact] + public async Task RequestAbortedTokenFires() + { + using (var connection = _fixture.CreateTestConnection()) + { + await connection.Send( + "GET /WaitForAbort HTTP/1.1", + "Host: localhost", + "Connection: close", + "", + ""); + + await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "1"); + } + + await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "0"); + } + + [ConditionalFact] + public async Task ClientDisconnectCallbackStress() + { + // Fixture initialization fails if inside of the Task.Run, so send an + // initial request to initialize the fixture. + var response = await _fixture.Client.GetAsync("HelloWorld"); + var numTotalRequests = 0; + for (var j = 0; j < 20; j++) + { + // Windows has a max connection limit of 10 for the IIS server, + // so setting limit fairly low. + const int numRequests = 5; + async Task RunRequests() + { + using (var connection = _fixture.CreateTestConnection()) + { + await connection.Send( + "GET /WaitForAbort HTTP/1.1", + "Host: localhost", + "Connection: close", + "", + ""); + await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() != "0"); + Interlocked.Increment(ref numTotalRequests); + } + } + + List tasks = new List(); + for (int i = 0; i < numRequests; i++) + { + tasks.Add(Task.Run(RunRequests)); + } + + await Task.WhenAll(tasks); + + await _fixture.Client.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "0"); + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/CompressionTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/CompressionTests.cs new file mode 100644 index 0000000000..ce1c84e609 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/CompressionTests.cs @@ -0,0 +1,96 @@ +// 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.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISCompressionSiteCollection.Name)] + public class CompressionModuleTests : FixtureLoggedTest + { + private readonly IISCompressionSiteFixture _fixture; + + public CompressionModuleTests(IISCompressionSiteFixture fixture): base(fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.DynamicCompression)] + [InlineData(true)] + [InlineData(false)] + public async Task BufferingDisabled(bool compression) + { + using (var connection = _fixture.CreateTestConnection()) + { + var requestLength = 0; + var messages = new List(); + for (var i = 1; i < 100; i++) + { + var message = i + Environment.NewLine; + requestLength += message.Length; + messages.Add(message); + } + + await connection.Send( + "POST /ReadAndWriteEchoLinesNoBuffering HTTP/1.1", + $"Content-Length: {requestLength}", + "Accept-Encoding: " + (compression ? "gzip": "identity"), + "Response-Content-Type: text/event-stream", + "Host: localhost", + "Connection: close", + "", + ""); + + await connection.Receive( + "HTTP/1.1 200 OK", + ""); + await connection.ReceiveHeaders(); + + foreach (var message in messages) + { + await connection.Send(message); + await connection.ReceiveChunk(message); + } + + await connection.Send("\r\n"); + await connection.ReceiveChunk(""); + await connection.WaitForConnectionClose(); + } + } + + [ConditionalFact] + [RequiresIIS(IISCapability.DynamicCompression)] + public async Task DynamicResponsesAreCompressed() + { + var handler = new HttpClientHandler + { + AutomaticDecompression = DecompressionMethods.GZip + }; + var client = new HttpClient(handler) + { + BaseAddress = _fixture.Client.BaseAddress, + }; + client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); + client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("identity", 0)); + client.DefaultRequestHeaders.Add("Response-Content-Type", "text/event-stream"); + var messages = "Message1\r\nMessage2\r\n"; + + // Send messages with terminator + var response = await client.PostAsync("ReadAndWriteEchoLines", new StringContent(messages + "\r\n")); + Assert.Equal(messages, await response.Content.ReadAsStringAsync()); + Assert.True(response.Content.Headers.TryGetValues("Content-Type", out var contentTypes)); + Assert.Single(contentTypes, "text/event-stream"); + // Not the cleanest check but I wasn't able to figure out other way to check + // that response was compressed + Assert.Contains("gzip", response.Content.GetType().FullName, StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs new file mode 100644 index 0000000000..ae8fde39ed --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EnvironmentVariableTests.cs @@ -0,0 +1,51 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class EnvironmentVariableTests: FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public EnvironmentVariableTests(IISTestSiteFixture fixture): base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task GetUniqueEnvironmentVariable() + { + Assert.Equal("foobar", await _fixture.Client.GetStringAsync("/CheckEnvironmentVariable")); + } + + [ConditionalFact] + public async Task GetLongEnvironmentVariable() + { + Assert.Equal( + "AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" + + "AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" + + "AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" + + "AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" + + "AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative" + + "AReallyLongValueThatIsGreaterThan300CharactersToForceResizeInNative", + await _fixture.Client.GetStringAsync("/CheckEnvironmentLongValueVariable")); + } + + [ConditionalFact] + public async Task GetExistingEnvironmentVariable() + { + Assert.Contains(";foobarbaz", await _fixture.Client.GetStringAsync("/CheckAppendedEnvironmentVariable")); + } + + [ConditionalFact] + public async Task AuthHeaderEnvironmentVariableRemoved() + { + Assert.DoesNotContain("shouldberemoved", await _fixture.Client.GetStringAsync("/CheckRemoveAuthEnvironmentVariable")); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs new file mode 100644 index 0000000000..bf45949491 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ErrorPagesTests.cs @@ -0,0 +1,131 @@ +// 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.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class ErrorPagesTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public ErrorPagesTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + public async Task IncludesAdditionalErrorPageTextInProcessHandlerLoadFailure_CorrectString() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + var response = await DeployAppWithStartupFailure(deploymentParameters); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + var responseString = await response.Content.ReadAsStringAsync(); + Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", responseString); + VerifyNoExtraTrailingBytes(responseString); + + await AssertLink(response); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + public async Task IncludesAdditionalErrorPageTextOutOfProcessStartupFailure_CorrectString() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); + var response = await DeployAppWithStartupFailure(deploymentParameters); + + Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode); + + StopServer(); + + var responseString = await response.Content.ReadAsStringAsync(); + Assert.Contains("HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure", responseString); + VerifyNoExtraTrailingBytes(responseString); + + await AssertLink(response); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + public async Task IncludesAdditionalErrorPageTextOutOfProcessHandlerLoadFailure_CorrectString() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); + deploymentParameters.HandlerSettings["handlerVersion"] = "88.93"; + deploymentParameters.EnvironmentVariables["ANCM_ADDITIONAL_ERROR_PAGE_LINK"] = "http://example"; + + var deploymentResult = await DeployAsync(deploymentParameters); + var response = await deploymentResult.HttpClient.GetAsync("HelloWorld"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + var responseString = await response.Content.ReadAsStringAsync(); + Assert.Contains("HTTP Error 500.0 - ANCM Out-Of-Process Handler Load Failure", responseString); + VerifyNoExtraTrailingBytes(responseString); + + await AssertLink(response); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [RequiresNewHandler] + public async Task IncludesAdditionalErrorPageTextInProcessStartupFailure_CorrectString() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} EarlyReturn"); + deploymentParameters.EnvironmentVariables["ANCM_ADDITIONAL_ERROR_PAGE_LINK"] = "http://example"; + + var deploymentResult = await DeployAsync(deploymentParameters); + var response = await deploymentResult.HttpClient.GetAsync("HelloWorld"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + var responseString = await response.Content.ReadAsStringAsync(); + Assert.Contains("HTTP Error 500.30 - ANCM In-Process Start Failure", responseString); + VerifyNoExtraTrailingBytes(responseString); + + await AssertLink(response); + } + + private static void VerifyNoExtraTrailingBytes(string responseString) + { + if (!DeployerSelector.IsBackwardsCompatiblityTest) + { + Assert.EndsWith("\r\n", responseString); + } + } + + private static async Task AssertLink(HttpResponseMessage response) + { + Assert.Contains(" http://example and ", await response.Content.ReadAsStringAsync()); + } + + private async Task DeployAppWithStartupFailure(IISDeploymentParameters deploymentParameters) + { + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "doesnot")); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("arguments", "start")); + + deploymentParameters.EnvironmentVariables["ANCM_ADDITIONAL_ERROR_PAGE_LINK"] = "http://example"; + + var deploymentResult = await DeployAsync(deploymentParameters); + + return await deploymentResult.HttpClient.GetAsync("HelloWorld"); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EventLogTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EventLogTests.cs new file mode 100644 index 0000000000..1df7f3c077 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/EventLogTests.cs @@ -0,0 +1,46 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class EventLogTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public EventLogTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task CheckStartupEventLogMessage() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + + var deploymentResult = await DeployAsync(deploymentParameters); + await deploymentResult.AssertStarts(); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Application '.+' started the coreclr in-process successfully."); + } + + [ConditionalFact] + public async Task CheckShutdownEventLogMessage() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + var deploymentResult = await DeployAsync(deploymentParameters); + await deploymentResult.AssertStarts(); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Application '.+' has shutdown."); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs new file mode 100644 index 0000000000..e31dc3dbaa --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FeatureCollectionTests.cs @@ -0,0 +1,29 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class FeatureCollectionTest + { + private readonly IISTestSiteFixture _fixture; + + public FeatureCollectionTest(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData("FeatureCollectionSetRequestFeatures")] + [InlineData("FeatureCollectionSetResponseFeatures")] + [InlineData("FeatureCollectionSetConnectionFeatures")] + public async Task FeatureCollectionTest_SetHttpContextFeatures(string path) + { + Assert.Equal("Success", await _fixture.Client.GetStringAsync(path + "/path" + "?query")); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs new file mode 100644 index 0000000000..705af2b213 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FixtureLoggedTest.cs @@ -0,0 +1,31 @@ +// 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.Reflection; +using Microsoft.Extensions.Logging.Testing; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class FixtureLoggedTest: LoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public FixtureLoggedTest(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + public override void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) + { + base.Initialize(methodInfo, testMethodArguments, testOutputHelper); + _fixture.Attach(this); + } + + public override void Dispose() + { + _fixture.Detach(this); + base.Dispose(); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FrebTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FrebTests.cs new file mode 100644 index 0000000000..12e2f6ae53 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/FrebTests.cs @@ -0,0 +1,181 @@ +// 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.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class FrebTests : LogFileTestBase + { + private readonly PublishedSitesFixture _fixture; + public FrebTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static IList FrebChecks() + { + var list = new List(); + list.Add(new FrebLogItem("ANCM_INPROC_EXECUTE_REQUEST_START")); + list.Add(new FrebLogItem("ANCM_INPROC_EXECUTE_REQUEST_COMPLETION", "1")); + list.Add(new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_START")); + list.Add(new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_COMPLETION", "0")); + list.Add(new FrebLogItem("ANCM_INPROC_MANAGED_REQUEST_COMPLETION")); + return list; + } + + [ConditionalFact] + [RequiresIIS(IISCapability.FailedRequestTracingModule)] + public async Task CheckCommonFrebEvents() + { + var result = await SetupFrebApp(); + + await result.HttpClient.GetAsync("HelloWorld"); + + StopServer(); + + AssertFrebLogs(result, FrebChecks()); + } + + [ConditionalFact] + [RequiresNewShim] + [RequiresIIS(IISCapability.FailedRequestTracingModule)] + public async Task FrebIncludesHResultFailures() + { + var parameters = _fixture.GetBaseDeploymentParameters(publish: true); + parameters.TransformArguments((args, _) => string.Empty); + var result = await SetupFrebApp(parameters); + + await result.HttpClient.GetAsync("HelloWorld"); + + StopServer(); + + AssertFrebLogs(result, new FrebLogItem("ANCM_HRESULT_FAILED"), new FrebLogItem("ANCM_EXCEPTION_CAUGHT")); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.FailedRequestTracingModule)] + public async Task CheckFailedRequestEvents() + { + var result = await SetupFrebApp(); + + await result.HttpClient.GetAsync("Throw"); + + StopServer(); + + AssertFrebLogs(result, new FrebLogItem("ANCM_INPROC_ASYNC_COMPLETION_COMPLETION", "2")); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.FailedRequestTracingModule)] + public async Task CheckFrebDisconnect() + { + var result = await SetupFrebApp(); + + using (var connection = new TestConnection(result.HttpClient.BaseAddress.Port)) + { + await connection.Send( + "GET /WaitForAbort HTTP/1.1", + "Host: localhost", + "Connection: close", + "", + ""); + await result.HttpClient.RetryRequestAsync("/WaitingRequestCount", async message => await message.Content.ReadAsStringAsync() == "1"); + } + + StopServer(); + + // The order of freb logs is based on when the requests are complete. + // This is non-deterministic here, so we need to check both freb files for a request that was disconnected. + AssertFrebLogs(result, new FrebLogItem("ANCM_INPROC_REQUEST_DISCONNECT"), new FrebLogItem("ANCM_INPROC_MANAGED_REQUEST_COMPLETION")); + } + + private async Task SetupFrebApp(IISDeploymentParameters parameters = null) + { + parameters = parameters ?? _fixture.GetBaseDeploymentParameters(publish: true); + parameters.EnableFreb("Verbose", _logFolderPath); + + Directory.CreateDirectory(_logFolderPath); + var result = await DeployAsync(parameters); + return result; + } + + private void AssertFrebLogs(IISDeploymentResult result, params FrebLogItem[] expectedFrebEvents) + { + AssertFrebLogs(result, (IEnumerable)expectedFrebEvents); + } + + private void AssertFrebLogs(IISDeploymentResult result, IEnumerable expectedFrebEvents) + { + var frebEvent = GetFrebLogItems(result); + foreach (var expectedEvent in expectedFrebEvents) + { + Assert.Contains(expectedEvent, frebEvent); + } + } + + private IEnumerable GetFrebLogItems(IISDeploymentResult result) + { + var folderPath = Helpers.GetFrebFolder(_logFolderPath, result); + var xmlFiles = Directory.GetFiles(folderPath).Where(f => f.EndsWith("xml")); + var frebEvents = new List(); + + foreach (var xmlFile in xmlFiles) + { + var xDocument = XDocument.Load(xmlFile).Root; + var nameSpace = (XNamespace)"http://schemas.microsoft.com/win/2004/08/events/event"; + var eventElements = xDocument.Descendants(nameSpace + "Event"); + foreach (var eventElement in eventElements) + { + var eventElementWithOpCode = eventElement.Descendants(nameSpace + "RenderingInfo").Single().Descendants(nameSpace + "Opcode").Single(); + var requestStatus = eventElement.Element(nameSpace + "EventData").Descendants().Where(el => el.Attribute("Name").Value == "requestStatus").SingleOrDefault(); + frebEvents.Add(new FrebLogItem(eventElementWithOpCode.Value, requestStatus?.Value)); + } + } + + return frebEvents; + } + + public class FrebLogItem + { + private string _opCode; + private string _requestStatus; + + public FrebLogItem(string opCode) + { + _opCode = opCode; + } + + public FrebLogItem(string opCode, string requestStatus) + { + _opCode = opCode; + _requestStatus = requestStatus; + } + + public override bool Equals(object obj) + { + var item = obj as FrebLogItem; + return item != null && + _opCode == item._opCode && + _requestStatus == item._requestStatus; + } + + public override int GetHashCode() + { + return HashCode.Combine(_opCode, _requestStatus); + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs new file mode 100644 index 0000000000..1b2ad70600 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HelloWorldTests.cs @@ -0,0 +1,30 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class HelloWorldInProcessTests + { + private readonly IISTestSiteFixture _fixture; + + public HelloWorldInProcessTests(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task HelloWorld_InProcess() + { + Assert.Equal("Hello World", await _fixture.Client.GetStringAsync("/HelloWorld")); + + Assert.Equal("/Path??", await _fixture.Client.GetStringAsync("/HelloWorld/Path%3F%3F?query")); + + Assert.Equal("?query", await _fixture.Client.GetStringAsync("/HelloWorld/Query%3F%3F?query")); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs new file mode 100644 index 0000000000..061b828a6c --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/HostingEnvironmentTests.cs @@ -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.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class HostingEnvironmentTests: FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public HostingEnvironmentTests(IISTestSiteFixture fixture): base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + [RequiresIIS(IISCapability.ShutdownToken)] + public async Task HostingEnvironmentIsCorrect() + { + Assert.Equal( + $"ContentRootPath {_fixture.DeploymentResult.ContentRoot}" + Environment.NewLine + + $"WebRootPath {_fixture.DeploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine + + $"CurrentDirectory {Path.GetDirectoryName(_fixture.DeploymentResult.HostProcess.MainModule.FileName)}", + await _fixture.Client.GetStringAsync("/HostingEnvironment")); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs new file mode 100644 index 0000000000..95c05308bd --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/InvalidReadWriteOperationTests.cs @@ -0,0 +1,84 @@ +// 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.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class InvalidReadWriteOperationTests + { + private readonly IISTestSiteFixture _fixture; + + public InvalidReadWriteOperationTests(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task TestReadOffsetWorks() + { + var result = await _fixture.Client.PostAsync($"/TestReadOffsetWorks", new StringContent("Hello World")); + Assert.Equal("Hello World", await result.Content.ReadAsStringAsync()); + } + + [ConditionalTheory] + [InlineData("/InvalidOffsetSmall")] + [InlineData("/InvalidOffsetLarge")] + [InlineData("/InvalidCountSmall")] + [InlineData("/InvalidCountLarge")] + [InlineData("/InvalidCountWithOffset")] + public async Task TestInvalidReadOperations(string operation) + { + var result = await _fixture.Client.GetStringAsync($"/TestInvalidReadOperations{operation}"); + Assert.Equal("Success", result); + } + + [ConditionalTheory] + [InlineData("/NullBuffer")] + [InlineData("/InvalidCountZeroRead")] + public async Task TestValidReadOperations(string operation) + { + var result = await _fixture.Client.GetStringAsync($"/TestValidReadOperations{operation}"); + Assert.Equal("Success", result); + } + + [ConditionalTheory] + [InlineData("/NullBufferPost")] + [InlineData("/InvalidCountZeroReadPost")] + public async Task TestValidReadOperationsPost(string operation) + { + var result = await _fixture.Client.PostAsync($"/TestValidReadOperations{operation}", new StringContent("hello")); + Assert.Equal("Success", await result.Content.ReadAsStringAsync()); + } + + [ConditionalTheory] + [InlineData("/InvalidOffsetSmall")] + [InlineData("/InvalidOffsetLarge")] + [InlineData("/InvalidCountSmall")] + [InlineData("/InvalidCountLarge")] + [InlineData("/InvalidCountWithOffset")] + public async Task TestInvalidWriteOperations(string operation) + { + var result = await _fixture.Client.GetStringAsync($"/TestInvalidWriteOperations{operation}"); + Assert.Equal("Success", result); + } + + [ConditionalFact] + public async Task TestValidWriteOperations() + { + var result = await _fixture.Client.GetStringAsync($"/TestValidWriteOperations/NullBuffer"); + Assert.Equal("Success", result); + } + + [ConditionalFact] + public async Task TestValidWriteOperationsPost() + { + var result = await _fixture.Client.PostAsync($"/TestValidWriteOperations/NullBufferPost", new StringContent("hello")); + Assert.Equal("Success", await result.Content.ReadAsStringAsync()); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs new file mode 100644 index 0000000000..40db2cfdb8 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LargeResponseBodyTests.cs @@ -0,0 +1,36 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class LargeResponseBodyTests + { + private readonly IISTestSiteFixture _fixture; + + public LargeResponseBodyTests(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData(65000)] + [InlineData(1000000)] + [InlineData(10000000)] + [InlineData(100000000)] + public async Task LargeResponseBodyTest_CheckAllResponseBodyBytesWritten(int query) + { + Assert.Equal(new string('a', query), await _fixture.Client.GetStringAsync($"/LargeResponseBody?length={query}")); + } + + [ConditionalFact] + public async Task LargeResponseBodyFromFile_CheckAllResponseBodyBytesWritten() + { + Assert.Equal(200000000, (await _fixture.Client.GetStringAsync($"/LargeResponseFile")).Length); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs new file mode 100644 index 0000000000..4d34c3154f --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/LogPipeTests.cs @@ -0,0 +1,83 @@ +// 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.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class LogPipeTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public LogPipeTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData("ConsoleErrorWrite")] + [InlineData("ConsoleWrite")] + public async Task CheckStdoutLoggingToPipe_DoesNotCrashProcess(string path) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + var deploymentResult = await DeployAsync(deploymentParameters); + + await Helpers.AssertStarts(deploymentResult, path); + + StopServer(); + + if (deploymentParameters.ServerType == ServerType.IISExpress) + { + Assert.Contains(TestSink.Writes, context => context.Message.Contains("TEST MESSAGE")); + } + } + + [ConditionalTheory] + [InlineData("ConsoleErrorWriteStartServer")] + [InlineData("ConsoleWriteStartServer")] + public async Task CheckStdoutLoggingToPipeWithFirstWrite(string path) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + + var firstWriteString = "TEST MESSAGE"; + + deploymentParameters.TransformArguments((a, _) => $"{a} {path}"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await Helpers.AssertStarts(deploymentResult); + + StopServer(); + + if (deploymentParameters.ServerType == ServerType.IISExpress) + { + // We can't read stdout logs from IIS as they aren't redirected. + Assert.Contains(TestSink.Writes, context => context.Message.Contains(firstWriteString)); + } + } + + [ConditionalFact] + public async Task CheckUnicodePipe() + { + var path = "CheckConsoleFunctions"; + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} {path}"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync(path); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", "(.*)彡⾔(.*)")); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs new file mode 100644 index 0000000000..fec5c227ec --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseHeaderTests.cs @@ -0,0 +1,85 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Net.Http.Headers; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class ResponseHeaders + { + private readonly IISTestSiteFixture _fixture; + + public ResponseHeaders(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task AddResponseHeaders_HeaderValuesAreSetCorrectly() + { + var response = await _fixture.Client.GetAsync("ResponseHeaders"); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Request Complete", responseText); + + Assert.True(response.Headers.TryGetValues("UnknownHeader", out var headerValues)); + Assert.Equal("test123=foo", headerValues.First()); + + Assert.True(response.Content.Headers.TryGetValues(HeaderNames.ContentType, out headerValues)); + Assert.Equal("text/plain", headerValues.First()); + + Assert.True(response.Headers.TryGetValues("MultiHeader", out headerValues)); + Assert.Equal(2, headerValues.Count()); + Assert.Equal("1", headerValues.First()); + Assert.Equal("2", headerValues.Last()); + } + + [ConditionalFact] + public async Task ErrorCodeIsSetForExceptionDuringRequest() + { + var response = await _fixture.Client.GetAsync("Throw"); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + Assert.Equal("Internal Server Error", response.ReasonPhrase); + } + + [ConditionalTheory] + [InlineData(200, "custom", "custom", null)] + [InlineData(200, "custom", "custom", "Custom body")] + [InlineData(200, "custom", "custom", "")] + + + [InlineData(500, "", "Internal Server Error", null)] + [InlineData(500, "", "Internal Server Error", "Custom body")] + [InlineData(500, "", "Internal Server Error", "")] + + [InlineData(400, "custom", "custom", null)] + [InlineData(400, "", "Bad Request", "Custom body")] + [InlineData(400, "", "Bad Request", "")] + + [InlineData(999, "", "", null)] + [InlineData(999, "", "", "Custom body")] + [InlineData(999, "", "", "")] + public async Task CustomErrorCodeWorks(int code, string reason, string expectedReason, string body) + { + var response = await _fixture.Client.GetAsync($"SetCustomErorCode?code={code}&reason={reason}&writeBody={body != null}&body={body}"); + Assert.Equal((HttpStatusCode)code, response.StatusCode); + Assert.Equal(expectedReason, response.ReasonPhrase); + + // ReadAsStringAsync returns empty string for empty results + Assert.Equal(body ?? string.Empty, await response.Content.ReadAsStringAsync()); + } + + [ConditionalFact] + public async Task ServerHeaderIsOverriden() + { + var response = await _fixture.Client.GetAsync("OverrideServer"); + Assert.Equal("MyServer/7.8", response.Headers.Server.Single().Product.ToString()); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs new file mode 100644 index 0000000000..c39e155e77 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ResponseInvalidOrderingTests.cs @@ -0,0 +1,29 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class ResponseInvalidOrderingTest + { + private readonly IISTestSiteFixture _fixture; + + public ResponseInvalidOrderingTest(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData("SetStatusCodeAfterWrite")] + [InlineData("SetHeaderAfterWrite")] + public async Task ResponseInvalidOrderingTests_ExpectFailure(string path) + { + Assert.Equal($"Started_{path}Threw_Finished", await _fixture.Client.GetStringAsync("/ResponseInvalidOrdering/" + path)); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs new file mode 100644 index 0000000000..d18c4c7f09 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/ServerVariablesTest.cs @@ -0,0 +1,59 @@ +// 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.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class ServerVariablesTest + { + private readonly IISTestSiteFixture _fixture; + + public ServerVariablesTest(IISTestSiteFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task ProvidesAccessToServerVariables() + { + var port = _fixture.Client.BaseAddress.Port; + Assert.Equal("SERVER_PORT: " + port, await _fixture.Client.GetStringAsync("/ServerVariable?q=SERVER_PORT")); + Assert.Equal("QUERY_STRING: q=QUERY_STRING", await _fixture.Client.GetStringAsync("/ServerVariable?q=QUERY_STRING")); + } + + [ConditionalFact] + public async Task ReturnsNullForUndefinedServerVariable() + { + Assert.Equal("THIS_VAR_IS_UNDEFINED: (null)", await _fixture.Client.GetStringAsync("/ServerVariable?q=THIS_VAR_IS_UNDEFINED")); + } + + [ConditionalFact] + public async Task CanSetAndReadVariable() + { + Assert.Equal("ROUNDTRIP: 1", await _fixture.Client.GetStringAsync("/ServerVariable?v=1&q=ROUNDTRIP")); + } + + [ConditionalFact] + public async Task BasePathIsNotPrefixedBySlashSlashQuestionMark() + { + Assert.DoesNotContain(@"\\?\", await _fixture.Client.GetStringAsync("/BasePath")); + } + + [ConditionalFact] + public async Task GetServerVariableDoesNotCrash() + { + await Helpers.StressLoad(_fixture.Client, "/GetServerVariableStress", response => { + var text = response.Content.ReadAsStringAsync().Result; + Assert.StartsWith("Response Begin", text); + Assert.EndsWith("Response End", text); + }); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs new file mode 100644 index 0000000000..cadfed9781 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupExceptionTests.cs @@ -0,0 +1,100 @@ +// 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.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class StartupExceptionTests : LogFileTestBase + { + private readonly PublishedSitesFixture _fixture; + + public StartupExceptionTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData("CheckLargeStdErrWrites")] + [InlineData("CheckLargeStdOutWrites")] + [InlineData("CheckOversizedStdErrWrites")] + [InlineData("CheckOversizedStdOutWrites")] + public async Task CheckStdoutWithLargeWrites_TestSink(string mode) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} {mode}"); + var deploymentResult = await DeployAsync(deploymentParameters); + + await AssertFailsToStart(deploymentResult); + var expectedString = new string('a', 30000); + Assert.Contains(TestSink.Writes, context => context.Message.Contains(expectedString)); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", expectedString)); + } + + [ConditionalTheory] + [InlineData("CheckLargeStdErrWrites")] + [InlineData("CheckLargeStdOutWrites")] + [InlineData("CheckOversizedStdErrWrites")] + [InlineData("CheckOversizedStdOutWrites")] + public async Task CheckStdoutWithLargeWrites_LogFile(string mode) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} {mode}"); + deploymentParameters.EnableLogging(_logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await AssertFailsToStart(deploymentResult); + + var contents = GetLogFileContent(deploymentResult); + var expectedString = new string('a', 30000); + + Assert.Contains(expectedString, contents); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", expectedString)); + } + + [ConditionalFact] + public async Task CheckValidConsoleFunctions() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} CheckConsoleFunctions"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await AssertFailsToStart(deploymentResult); + + Assert.Contains(TestSink.Writes, context => context.Message.Contains("Is Console redirection: True")); + } + + private async Task AssertFailsToStart(IISDeploymentResult deploymentResult) + { + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + } + + [ConditionalFact] + public async Task Gets500_30_ErrorPage() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} EarlyReturn"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.False(response.IsSuccessStatusCode); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Contains("500.30 - ANCM In-Process Start Failure", responseText); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupTests.cs new file mode 100644 index 0000000000..3bcc134cb2 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -0,0 +1,479 @@ +// 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; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class StartupTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public StartupTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + private readonly string _dotnetLocation = DotNetCommands.GetDotNetExecutable(RuntimeArchitecture.x64); + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + public async Task ExpandEnvironmentVariableInWebConfig() + { + // Point to dotnet installed in user profile. + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + deploymentParameters.EnvironmentVariables["DotnetPath"] = _dotnetLocation; + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "%DotnetPath%")); + await StartAsync(deploymentParameters); + } + + [ConditionalTheory] + [InlineData("bogus", "", @"Executable was not found at '.*?\\bogus.exe")] + [InlineData("c:\\random files\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\dotnet.exe'")] + [InlineData(".\\dotnet.exe", "something.dll", @"Could not find dotnet.exe at '.*?\\.\\dotnet.exe'")] + [InlineData("dotnet.exe", "", @"Application arguments are empty.")] + [InlineData("dotnet.zip", "", @"Process path 'dotnet.zip' doesn't have '.exe' extension.")] + public async Task InvalidProcessPath_ExpectServerError(string path, string arguments, string subError) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", path)); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("arguments", arguments)); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("HelloWorld"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, $@"Application '{Regex.Escape(deploymentResult.ContentRoot)}\\' wasn't able to start. {subError}"); + + Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", await response.Content.ReadAsStringAsync()); + } + + [ConditionalFact] + public async Task StartsWithDotnetLocationWithoutExe() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + + var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf(".")); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension)); + + await StartAsync(deploymentParameters); + } + + [ConditionalFact] + public async Task StartsWithDotnetLocationUppercase() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + + var dotnetLocationWithoutExtension = _dotnetLocation.Substring(0, _dotnetLocation.LastIndexOf(".")).ToUpperInvariant(); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", dotnetLocationWithoutExtension)); + + await StartAsync(deploymentParameters); + } + + [ConditionalTheory] + [InlineData("dotnet")] + [InlineData("dotnet.EXE")] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + public async Task StartsWithDotnetOnThePath(string path) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + + deploymentParameters.EnvironmentVariables["PATH"] = Path.GetDirectoryName(_dotnetLocation); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", path)); + + var deploymentResult = await DeployAsync(deploymentParameters); + await deploymentResult.AssertStarts(); + + StopServer(); + // Verify that in this scenario where.exe was invoked only once by shim and request handler uses cached value + Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains("Invoking where.exe to find dotnet.exe"))); + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22) + .WithAllApplicationTypes() + .WithAncmV2InProcess(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task HelloWorld(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + await StartAsync(deploymentParameters); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + public async Task StartsWithPortableAndBootstraperExe() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + // We need the right dotnet on the path in IIS + deploymentParameters.EnvironmentVariables["PATH"] = Path.GetDirectoryName(DotNetCommands.GetDotNetExecutable(deploymentParameters.RuntimeArchitecture)); + + // rest publisher as it doesn't support additional parameters + deploymentParameters.ApplicationPublisher = null; + // ReferenceTestTasks is workaround for https://github.com/dotnet/sdk/issues/2482 + deploymentParameters.AdditionalPublishParameters = "-p:RuntimeIdentifier=win7-x64 -p:UseAppHost=true -p:SelfContained=false -p:ReferenceTestTasks=false"; + var deploymentResult = await DeployAsync(deploymentParameters); + + Assert.True(File.Exists(Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.exe"))); + Assert.False(File.Exists(Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"))); + Assert.Contains("InProcessWebSite.exe", Helpers.ReadAllTextFromFile(Path.Combine(deploymentResult.ContentRoot, "web.config"), Logger)); + + await deploymentResult.AssertStarts(); + } + + [ConditionalFact] + public async Task DetectsOverriddenServer() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} OverriddenServer"); + + var deploymentResult = await DeployAsync(deploymentParameters); + var response = await deploymentResult.HttpClient.GetAsync("/"); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"), + EventLogHelpers.InProcessThreadException(deploymentResult, ".*?Application is running inside IIS process but is not configured to use IIS server")); + } + + [ConditionalFact] + public async Task LogsStartupExceptionExitError() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} Throw"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/"); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"), + EventLogHelpers.InProcessThreadException(deploymentResult, ", exception code = '0xe0434352'")); + } + + [ConditionalFact] + public async Task LogsUnexpectedThreadExitError() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} EarlyReturn"); + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"), + EventLogHelpers.InProcessThreadExit(deploymentResult, "12")); + } + + [ConditionalFact] + public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.ApplicationType = ApplicationType.Standalone; + var deploymentResult = await DeployAsync(deploymentParameters); + + File.Copy( + Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll"), + Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"), + true); + await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger); + } + + [ConditionalFact] + public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + var deploymentResult = await DeployAsync(deploymentParameters); + + Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult); + await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger); + } + + [ConditionalFact] + public async Task RemoveInProcessReference_FailedToFindRequestHandler() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.ApplicationType = ApplicationType.Standalone; + var deploymentResult = await DeployAsync(deploymentParameters); + + File.Delete(Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll")); + + await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult); + + if (DeployerSelector.IsForwardsCompatibilityTest) + { + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindNativeDependencies(deploymentResult), Logger); + } + else + { + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessFailedToFindRequestHandler(deploymentResult), Logger); + } + } + + [ConditionalFact] + public async Task StartupTimeoutIsApplied() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} Hang"); + deploymentParameters.WebConfigActionList.Add( + WebConfigHelpers.AddOrModifyAspNetCoreSection("startupTimeLimit", "1")); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/"); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.InProcessFailedToStart(deploymentResult, "Managed server didn't initialize after 1000 ms.") + ); + } + + [ConditionalFact] + public async Task ShutdownTimeoutIsApplied() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} HangOnStop"); + deploymentParameters.WebConfigActionList.Add( + WebConfigHelpers.AddOrModifyAspNetCoreSection("shutdownTimeLimit", "1")); + + var deploymentResult = await DeployAsync(deploymentParameters); + + Assert.Equal("Hello World", await deploymentResult.HttpClient.GetStringAsync("/HelloWorld")); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.InProcessStarted(deploymentResult), + EventLogHelpers.InProcessFailedToStop(deploymentResult, "")); + } + + [ConditionalFact] + public async Task CheckInvalidHostingModelParameter() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("hostingModel", "bogus")); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("HelloWorld"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.ConfigurationLoadError(deploymentResult, "Unknown hosting model 'bogus'. Please specify either hostingModel=\"inprocess\" or hostingModel=\"outofprocess\" in the web.config file.") + ); + } + + private static Dictionary)> InvalidConfigTransformations = InitInvalidConfigTransformations(); + public static IEnumerable InvalidConfigTransformationsScenarios => InvalidConfigTransformations.ToTheoryData(); + + [ConditionalTheory] + [MemberData(nameof(InvalidConfigTransformationsScenarios))] + public async Task ReportsWebConfigAuthoringErrors(string scenario) + { + var (expectedError, action) = InvalidConfigTransformations[scenario]; + var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + iisDeploymentParameters.WebConfigActionList.Add((element, _) => action(element)); + var deploymentResult = await DeployAsync(iisDeploymentParameters); + var result = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode); + + // Config load errors might not allow us to initialize log file + deploymentResult.AllowNoLogs(); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvents(deploymentResult, + EventLogHelpers.ConfigurationLoadError(deploymentResult, expectedError) + ); + } + + public static Dictionary)> InitInvalidConfigTransformations() + { + var dictionary = new Dictionary)>(); + dictionary.Add("Empty process path", + ( + "Attribute 'processPath' is required.", + element => element.Descendants("aspNetCore").Single().SetAttributeValue("processPath", "") + )); + dictionary.Add("Unknown hostingModel", + ( + "Unknown hosting model 'asdf'.", + element => element.Descendants("aspNetCore").Single().SetAttributeValue("hostingModel", "asdf") + )); + dictionary.Add("environmentVariables with add", + ( + "Unable to get required configuration section 'system.webServer/aspNetCore'. Possible reason is web.config authoring error.", + element => element.Descendants("aspNetCore").Single().GetOrAdd("environmentVariables").GetOrAdd("add") + )); + return dictionary; + } + + private static Dictionary> PortableConfigTransformations = InitPortableWebConfigTransformations(); + public static IEnumerable PortableConfigTransformationsScenarios => PortableConfigTransformations.ToTheoryData(); + + [ConditionalTheory] + [MemberData(nameof(PortableConfigTransformationsScenarios))] + public async Task StartsWithWebConfigVariationsPortable(string scenario) + { + var action = PortableConfigTransformations[scenario]; + var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + var expectedArguments = action(iisDeploymentParameters); + var result = await DeployAsync(iisDeploymentParameters); + Assert.Equal(expectedArguments, await result.HttpClient.GetStringAsync("/CommandLineArgs")); + } + + public static Dictionary> InitPortableWebConfigTransformations() + { + var dictionary = new Dictionary>(); + var pathWithSpace = "\u03c0 \u2260 3\u00b714"; + + dictionary.Add("App in bin subdirectory full path to dll using exec and quotes", + parameters => { + MoveApplication(parameters, "bin"); + parameters.TransformArguments((arguments, root) => "exec " + Path.Combine(root, "bin", arguments)); + return ""; + }); + + dictionary.Add("App in subdirectory with space", + parameters => { + MoveApplication(parameters, pathWithSpace); + parameters.TransformArguments((arguments, root) => Path.Combine(pathWithSpace, arguments)); + return ""; + }); + + dictionary.Add("App in subdirectory with space and full path to dll", + parameters => { + MoveApplication(parameters, pathWithSpace); + parameters.TransformArguments((arguments, root) => Path.Combine(root, pathWithSpace, arguments)); + return ""; + }); + + dictionary.Add("App in bin subdirectory with space full path to dll using exec and quotes", + parameters => { + MoveApplication(parameters, pathWithSpace); + parameters.TransformArguments((arguments, root) => "exec \"" + Path.Combine(root, pathWithSpace, arguments) + "\" extra arguments"); + return "extra|arguments"; + }); + + dictionary.Add("App in bin subdirectory and quoted argument", + parameters => { + MoveApplication(parameters, "bin"); + parameters.TransformArguments((arguments, root) => Path.Combine("bin", arguments) + " \"extra argument\""); + return "extra argument"; + }); + + dictionary.Add("App in bin subdirectory full path to dll", + parameters => { + MoveApplication(parameters, "bin"); + parameters.TransformArguments((arguments, root) => Path.Combine(root, "bin", arguments) + " extra arguments"); + return "extra|arguments"; + }); + return dictionary; + } + + + private static Dictionary> StandaloneConfigTransformations = InitStandaloneConfigTransformations(); + public static IEnumerable StandaloneConfigTransformationsScenarios => StandaloneConfigTransformations.ToTheoryData(); + + [ConditionalTheory] + [MemberData(nameof(StandaloneConfigTransformationsScenarios))] + public async Task StartsWithWebConfigVariationsStandalone(string scenario) + { + var action = StandaloneConfigTransformations[scenario]; + var iisDeploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + iisDeploymentParameters.ApplicationType = ApplicationType.Standalone; + var expectedArguments = action(iisDeploymentParameters); + var result = await DeployAsync(iisDeploymentParameters); + Assert.Equal(expectedArguments, await result.HttpClient.GetStringAsync("/CommandLineArgs")); + } + + public static Dictionary> InitStandaloneConfigTransformations() + { + var dictionary = new Dictionary>(); + var pathWithSpace = "\u03c0 \u2260 3\u00b714"; + + dictionary.Add("App in subdirectory", + parameters => { + MoveApplication(parameters, pathWithSpace); + parameters.TransformPath((path, root) => Path.Combine(pathWithSpace, path)); + parameters.TransformArguments((arguments, root) => "\"additional argument\""); + return "additional argument"; + }); + + dictionary.Add("App in bin subdirectory full path", + parameters => { + MoveApplication(parameters, pathWithSpace); + parameters.TransformPath((path, root) => Path.Combine(root, pathWithSpace, path)); + parameters.TransformArguments((arguments, root) => "additional arguments"); + return "additional|arguments"; + }); + + return dictionary; + } + + private static void MoveApplication( + IISDeploymentParameters parameters, + string subdirectory) + { + parameters.WebConfigActionList.Add((config, contentRoot) => + { + var source = new DirectoryInfo(contentRoot); + var subDirectoryPath = source.CreateSubdirectory(subdirectory); + + // Copy everything into a subfolder + Helpers.CopyFiles(source, subDirectoryPath, null); + // Cleanup files + foreach (var fileSystemInfo in source.GetFiles()) + { + fileSystemInfo.Delete(); + } + }); + } + + private async Task AssertSiteFailsToStartWithInProcessStaticContent(IISDeploymentResult deploymentResult) + { + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + Assert.Contains("HTTP Error 500.0 - ANCM In-Process Handler Load Failure", await response.Content.ReadAsStringAsync()); + StopServer(); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs new file mode 100644 index 0000000000..03aa0e16e6 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs @@ -0,0 +1,197 @@ +// 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.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class SynchronousReadAndWriteTests: FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public SynchronousReadAndWriteTests(IISTestSiteFixture fixture): base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task ReadAndWriteSynchronously() + { + for (int i = 0; i < 100; i++) + { + var content = new StringContent(new string('a', 100000)); + var response = await _fixture.Client.PostAsync("ReadAndWriteSynchronously", content); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(expected: 110000, actual: responseText.Length); + } + } + + [ConditionalFact] + public async Task ReadAndWriteEcho() + { + var body = new string('a', 100000); + var content = new StringContent(body); + var response = await _fixture.Client.PostAsync("ReadAndWriteEcho", content); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(body, responseText); + } + + [ConditionalFact] + public async Task ReadAndWriteCopyToAsync() + { + var body = new string('a', 100000); + var content = new StringContent(body); + var response = await _fixture.Client.PostAsync("ReadAndWriteCopyToAsync", content); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(body, responseText); + } + + [ConditionalFact] + public async Task ReadAndWriteEchoTwice() + { + var requestBody = new string('a', 10000); + var content = new StringContent(requestBody); + var response = await _fixture.Client.PostAsync("ReadAndWriteEchoTwice", content); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(requestBody.Length * 2, responseText.Length); + } + + [ConditionalFact] + public async Task ReadSetHeaderWrite() + { + var body = "Body text"; + var content = new StringContent(body); + var response = await _fixture.Client.PostAsync("SetHeaderFromBody", content); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(body, response.Headers.GetValues("BodyAsString").Single()); + Assert.Equal(body, responseText); + } + + [ConditionalFact] + public async Task ReadAndWriteSlowConnection() + { + using (var connection = _fixture.CreateTestConnection()) + { + var testString = "hello world"; + var request = $"POST /ReadAndWriteSlowConnection HTTP/1.0\r\n" + + $"Content-Length: {testString.Length}\r\n" + + "Host: " + "localhost\r\n" + + "\r\n" + testString; + + foreach (var c in request) + { + await connection.Send(c.ToString()); + await Task.Delay(10); + } + + await connection.Receive( + "HTTP/1.1 200 OK", + ""); + await connection.ReceiveHeaders(); + + for (int i = 0; i < 100; i++) + { + foreach (var c in testString) + { + await connection.Receive(c.ToString()); + } + await Task.Delay(10); + } + await connection.WaitForConnectionClose(); + } + } + + [ConditionalFact] + public async Task ReadAndWriteInterleaved() + { + using (var connection = _fixture.CreateTestConnection()) + { + var requestLength = 0; + var messages = new List(); + for (var i = 1; i < 100; i++) + { + var message = i + Environment.NewLine; + requestLength += message.Length; + messages.Add(message); + } + + await connection.Send( + "POST /ReadAndWriteEchoLines HTTP/1.0", + $"Content-Length: {requestLength}", + "Host: localhost", + "", + ""); + + await connection.Receive( + "HTTP/1.1 200 OK", + ""); + await connection.ReceiveHeaders(); + + foreach (var message in messages) + { + await connection.Send(message); + await connection.Receive(message); + } + + await connection.Send("\r\n"); + await connection.WaitForConnectionClose(); + } + } + + [ConditionalFact] + public async Task ConsumePartialBody() + { + using (var connection = _fixture.CreateTestConnection()) + { + var message = "Hello"; + await connection.Send( + "POST /ReadPartialBody HTTP/1.1", + $"Content-Length: {100}", + "Host: localhost", + "Connection: close", + "", + ""); + + await connection.Send(message); + + await connection.Receive( + "HTTP/1.1 200 OK", + ""); + + // This test can return both content length or chunked response + // depending on if appfunc managed to complete before write was + // issued + var headers = await connection.ReceiveHeaders(); + if (headers.Contains("Content-Length: 5")) + { + await connection.Receive("Hello"); + } + else + { + await connection.Receive( + "5", + message, + ""); + await connection.Receive( + "0", + "", + ""); + } + + await connection.WaitForConnectionClose(); + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/LogFileTests.cs b/src/IISIntegration/test/Common.FunctionalTests/LogFileTests.cs new file mode 100644 index 0000000000..1e15cde5c2 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/LogFileTests.cs @@ -0,0 +1,242 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class LoggingTests : LogFileTestBase + { + private readonly PublishedSitesFixture _fixture; + + public LoggingTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22) + .WithAllApplicationTypes() + .WithAncmVersions(AncmVersion.AspNetCoreModuleV2) + .WithAllHostingModels(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task CheckStdoutLoggingToFile(TestVariant variant) + { + await CheckStdoutToFile(variant, "ConsoleWrite"); + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task CheckStdoutErrLoggingToFile(TestVariant variant) + { + await CheckStdoutToFile(variant, "ConsoleErrorWrite"); + } + + private async Task CheckStdoutToFile(TestVariant variant, string path) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.EnableLogging(_logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await Helpers.AssertStarts(deploymentResult, path); + + StopServer(); + + var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, _logFolderPath), Logger); + + Assert.Contains("TEST MESSAGE", contents); + } + + // Move to separate file + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task InvalidFilePathForLogs_ServerStillRuns(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + + deploymentParameters.WebConfigActionList.Add( + WebConfigHelpers.AddOrModifyAspNetCoreSection("stdoutLogEnabled", "true")); + deploymentParameters.WebConfigActionList.Add( + WebConfigHelpers.AddOrModifyAspNetCoreSection("stdoutLogFile", Path.Combine("Q:", "std"))); + + var deploymentResult = await DeployAsync(deploymentParameters); + + await Helpers.AssertStarts(deploymentResult, "HelloWorld"); + + StopServer(); + if (variant.HostingModel == HostingModel.InProcess) + { + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not start stdout redirection in (.*)aspnetcorev2.dll. Exception message: HRESULT 0x80070003"); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Could not stop stdout redirection in (.*)aspnetcorev2.dll. Exception message: HRESULT 0x80070002"); + } + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task StartupMessagesAreLoggedIntoDebugLogFile(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.HandlerSettings["debugLevel"] = "file"; + deploymentParameters.HandlerSettings["debugFile"] = "debug.txt"; + + var deploymentResult = await DeployAsync(deploymentParameters); + + await deploymentResult.HttpClient.GetAsync("/"); + + AssertLogs(Path.Combine(deploymentResult.ContentRoot, "debug.txt")); + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task StartupMessagesAreLoggedIntoDefaultDebugLogFile(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.HandlerSettings["debugLevel"] = "file"; + + var deploymentResult = await DeployAsync(deploymentParameters); + + await deploymentResult.HttpClient.GetAsync("/"); + + AssertLogs(Path.Combine(deploymentResult.ContentRoot, "aspnetcore-debug.log")); + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [MemberData(nameof(TestVariants))] + public async Task StartupMessagesAreLoggedIntoDefaultDebugLogFileWhenEnabledWithEnvVar(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG"] = "file"; + // Add empty debugFile handler setting to prevent IIS deployer from overriding debug settings + deploymentParameters.HandlerSettings["debugFile"] = ""; + var deploymentResult = await DeployAsync(deploymentParameters); + + await deploymentResult.HttpClient.GetAsync("/"); + + AssertLogs(Path.Combine(deploymentResult.ContentRoot, "aspnetcore-debug.log")); + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [MemberData(nameof(TestVariants))] + public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig(TestVariant variant) + { + var firstTempFile = Path.GetTempFileName(); + var secondTempFile = Path.GetTempFileName(); + + try + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_DEBUG_FILE"] = firstTempFile; + deploymentParameters.AddDebugLogToWebConfig(secondTempFile); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/"); + + StopServer(); + var logContents = Helpers.ReadAllTextFromFile(firstTempFile, Logger); + + Assert.Contains("Switching debug log files to", logContents); + + AssertLogs(secondTempFile); + } + finally + { + File.Delete(firstTempFile); + File.Delete(secondTempFile); + } + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + + public async Task DebugLogsAreWrittenToEventLog(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.HandlerSettings["debugLevel"] = "file,eventlog"; + var deploymentResult = await StartAsync(deploymentParameters); + StopServer(); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, @"\[aspnetcorev2.dll\] Initializing logs for .*?Description: IIS ASP.NET Core Module V2"); + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task CheckUTF8File(TestVariant variant) + { + var path = "CheckConsoleFunctions"; + + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, variant.HostingModel, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} {path}"); // For standalone this will need to remove space + + var logFolderPath = _logFolderPath + "\\彡⾔"; + deploymentParameters.EnableLogging(logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync(path); + + Assert.False(response.IsSuccessStatusCode); + + StopServer(); + + var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, logFolderPath), Logger); + Assert.Contains("彡⾔", contents); + + if (variant.HostingModel == HostingModel.InProcess) + { + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessThreadExitStdOut(deploymentResult, "12", "(.*)彡⾔(.*)")); + } + else + { + EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.OutOfProcessFailedToStart(deploymentResult)); + } + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task OnlyOneFileCreatedWithProcessStartTime(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + + deploymentParameters.EnableLogging(_logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + await Helpers.AssertStarts(deploymentResult, "ConsoleWrite"); + + StopServer(); + + Assert.Single(Directory.GetFiles(_logFolderPath), Helpers.GetExpectedLogName(deploymentResult, _logFolderPath)); + } + + private static string ReadLogs(string logPath) + { + using (var stream = File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (var streamReader = new StreamReader(stream)) + { + return streamReader.ReadToEnd(); + } + } + + private static void AssertLogs(string logPath) + { + var logContents = ReadLogs(logPath); + Assert.Contains("[aspnetcorev2.dll]", logContents); + Assert.True(logContents.Contains("[aspnetcorev2_inprocess.dll]") || logContents.Contains("[aspnetcorev2_outofprocess.dll]")); + Assert.Contains("Description: IIS ASP.NET Core Module V2. Commit:", logContents); + Assert.Contains("Description: IIS ASP.NET Core Module V2 Request Handler. Commit:", logContents); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/MultiApplicationTests.cs b/src/IISIntegration/test/Common.FunctionalTests/MultiApplicationTests.cs new file mode 100644 index 0000000000..3723369c89 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/MultiApplicationTests.cs @@ -0,0 +1,144 @@ +// 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.Linq; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class MultiApplicationTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + private PublishedApplication _publishedApplication; + private PublishedApplication _rootApplication; + + public MultiApplicationTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task RunsTwoOutOfProcessApps() + { + var parameters = _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); + parameters.ServerConfigActionList.Add(DuplicateApplication); + var result = await DeployAsync(parameters); + var id1 = await result.HttpClient.GetStringAsync("/app1/ProcessId"); + var id2 = await result.HttpClient.GetStringAsync("/app2/ProcessId"); + Assert.NotEqual(id2, id1); + } + + [ConditionalFact] + public async Task FailsAndLogsWhenRunningTwoInProcessApps() + { + var parameters = _fixture.GetBaseDeploymentParameters(HostingModel.InProcess, publish: true); + parameters.ServerConfigActionList.Add(DuplicateApplication); + + var result = await DeployAsync(parameters); + var result1 = await result.HttpClient.GetAsync("/app1/HelloWorld"); + var result2 = await result.HttpClient.GetAsync("/app2/HelloWorld"); + Assert.Equal(200, (int)result1.StatusCode); + Assert.Equal(500, (int)result2.StatusCode); + StopServer(); + EventLogHelpers.VerifyEventLogEvent(result, "Only one inprocess application is allowed per IIS application pool"); + } + + [ConditionalTheory] + [InlineData(HostingModel.OutOfProcess)] + [InlineData(HostingModel.InProcess)] + public async Task FailsAndLogsEventLogForMixedHostingModel(HostingModel firstApp) + { + var parameters = _fixture.GetBaseDeploymentParameters(firstApp, publish: true); + parameters.ServerConfigActionList.Add(DuplicateApplication); + var result = await DeployAsync(parameters); + + // Modify hosting model of other app to be the opposite + var otherApp = firstApp == HostingModel.InProcess ? HostingModel.OutOfProcess : HostingModel.InProcess; + SetHostingModel(_publishedApplication.Path, otherApp); + + var result1 = await result.HttpClient.GetAsync("/app1/HelloWorld"); + var result2 = await result.HttpClient.GetAsync("/app2/HelloWorld"); + Assert.Equal(200, (int)result1.StatusCode); + Assert.Equal(500, (int)result2.StatusCode); + StopServer(); + EventLogHelpers.VerifyEventLogEvent(result, "Mixed hosting model is not supported."); + } + + private void SetHostingModel(string directory, HostingModel model) + { + var webConfigLocation = GetWebConfigLocation(directory); + XDocument webConfig = XDocument.Load(webConfigLocation); + webConfig.Root + .Descendants("system.webServer") + .Single() + .GetOrAdd("aspNetCore") + .SetAttributeValue("hostingModel", model.ToString()); + webConfig.Save(webConfigLocation); + } + + private void DuplicateApplication(XElement config, string contentRoot) + { + var siteElement = config + .RequiredElement("system.applicationHost") + .RequiredElement("sites") + .RequiredElement("site"); + + var application = siteElement + .RequiredElement("application"); + + application.SetAttributeValue("path", "/app1"); + + var source = new DirectoryInfo(contentRoot); + + var destination = new DirectoryInfo(contentRoot + "anotherApp"); + destination.Create(); + Helpers.CopyFiles(source, destination, Logger); + + _publishedApplication = new PublishedApplication(destination.FullName, Logger); + + var newApplication = new XElement(application); + newApplication.SetAttributeValue("path", "/app2"); + newApplication.RequiredElement("virtualDirectory") + .SetAttributeValue("physicalPath", destination.FullName); + + siteElement.Add(newApplication); + + // IIS Express requires root application to exist + var rootApplicationDirectory = new DirectoryInfo(contentRoot + "rootApp"); + rootApplicationDirectory.Create(); + + _rootApplication = new PublishedApplication(rootApplicationDirectory.FullName, Logger); + File.WriteAllText(GetWebConfigLocation(rootApplicationDirectory.FullName), ""); + + var rootApplication = new XElement(application); + rootApplication.SetAttributeValue("path", "/"); + rootApplication.RequiredElement("virtualDirectory") + .SetAttributeValue("physicalPath", rootApplicationDirectory.FullName); + + siteElement.Add(rootApplication); + } + + private static string GetWebConfigLocation(string siteRoot) + { + return Path.Combine(siteRoot, "web.config"); + } + + public override void Dispose() + { + base.Dispose(); + _rootApplication.Dispose(); + _publishedApplication.Dispose(); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs b/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs new file mode 100644 index 0000000000..3b86662717 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs @@ -0,0 +1,125 @@ +// 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.Linq; +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; +using Xunit; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class AspNetCorePortTests : IISFunctionalTestBase + { + // Port range allowed by ANCM config + private const int _minPort = 1025; + private const int _maxPort = 48000; + + private static readonly Random _random = new Random(); + + private readonly PublishedSitesFixture _fixture; + + public AspNetCorePortTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22) + .WithApplicationTypes(ApplicationType.Portable) + .WithAllAncmVersions(); + + public static IEnumerable InvalidTestVariants + => from v in TestVariants.Select(v => v.Single()) + from s in new string[] { (_minPort - 1).ToString(), (_maxPort + 1).ToString(), "noninteger" } + select new object[] { v, s }; + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task EnvVarInWebConfig_Valid(TestVariant variant) + { + // Must publish to set env vars in web.config + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + var port = GetUnusedRandomPort(); + deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = port.ToString(); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var responseText = await deploymentResult.HttpClient.GetStringAsync("/ServerAddresses"); + + Assert.Equal(port, new Uri(responseText).Port); + } + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task EnvVarInWebConfig_Empty(TestVariant variant) + { + // Must publish to set env vars in web.config + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = string.Empty; + + var deploymentResult = await DeployAsync(deploymentParameters); + + var responseText = await deploymentResult.HttpClient.GetStringAsync("/ServerAddresses"); + + // If env var is empty, ANCM should assign a random port (same as no env var) + Assert.InRange(new Uri(responseText).Port, _minPort, _maxPort); + } + + [ConditionalTheory] + [MemberData(nameof(InvalidTestVariants))] + public async Task EnvVarInWebConfig_Invalid(TestVariant variant, string port) + { + // Must publish to set env vars in web.config + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant, publish: true); + deploymentParameters.WebConfigBasedEnvironmentVariables["ASPNETCORE_PORT"] = port; + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/ServerAddresses"); + + Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode); + } + + private static int GetUnusedRandomPort() + { + // Large number of retries to prevent test failures due to port collisions, but not infinite + // to prevent infinite loop in case Bind() fails repeatedly for some other reason. + const int retries = 100; + + List exceptions = null; + + for (var i = 0; i < retries; i++) + { + var port = _random.Next(_minPort, _maxPort); + + using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + try + { + socket.Bind(new IPEndPoint(IPAddress.Loopback, port)); + return port; + } + catch (Exception e) + { + // Bind failed, most likely because port is in use. Save exception and retry. + if (exceptions == null) + { + exceptions = new List(retries); + } + exceptions.Add(e); + } + } + } + + throw new AggregateException($"Unable to find unused random port after {retries} retries.", exceptions); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs b/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs new file mode 100644 index 0000000000..f9e6836b6f --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/GlobalVersionTests.cs @@ -0,0 +1,252 @@ +// 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.Linq; +using System.Net; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class GlobalVersionTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public GlobalVersionTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + private const string _handlerVersion20 = "2.0.0"; + private const string _helloWorldRequest = "HelloWorld"; + private const string _helloWorldResponse = "Hello World"; + + [ConditionalFact] + public async Task GlobalVersion_DefaultWorks() + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + + deploymentParameters.HandlerSettings["handlerVersion"] = _handlerVersion20; + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(_helloWorldResponse, responseText); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [RequiresNewShim] + public async Task GlobalVersion_EnvironmentVariableWorks() + { + var temporaryFile = Path.GetTempFileName(); + try + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + CopyShimToOutput(deploymentParameters); + deploymentParameters.PublishApplicationBeforeDeployment = true; + deploymentParameters.EnvironmentVariables["ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER"] = temporaryFile; + + var deploymentResult = await DeployAsync(deploymentParameters); + var requestHandlerPath = Path.Combine(GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20), "aspnetcorev2_outofprocess.dll"); + + File.Delete(temporaryFile); + File.Move(requestHandlerPath, temporaryFile); + + var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(_helloWorldResponse, responseText); + StopServer(); + } + finally + { + File.Delete(temporaryFile); + } + } + + [ConditionalTheory] + [InlineData("2.1.0")] + [InlineData("2.1.0-preview")] + public async Task GlobalVersion_NewVersionNumber_Fails(string version) + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + deploymentParameters.HandlerSettings["handlerVersion"] = version; + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest); + Assert.False(response.IsSuccessStatusCode); + var responseString = await response.Content.ReadAsStringAsync(); + Assert.Contains("HTTP Error 500.0 - ANCM Out-Of-Process Handler Load Failure", responseString); + } + + [ConditionalTheory] + [InlineData("2.1.0")] + [InlineData("2.1.0-preview")] + public async Task GlobalVersion_NewVersionNumber(string version) + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + CopyShimToOutput(deploymentParameters); + deploymentParameters.HandlerSettings["handlerVersion"] = version; + + var deploymentResult = await DeployAsync(deploymentParameters); + + var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20); + var newANCMPath = GetANCMRequestHandlerPath(deploymentResult, version); + Directory.Move(originalANCMPath, newANCMPath); + + var response = await deploymentResult.HttpClient.GetAsync(_helloWorldRequest); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(_helloWorldResponse, responseText); + AssertLoadedVersion(version); + } + + [ConditionalTheory] + [InlineData("2.1.0")] + [InlineData("2.1.0-preview")] + public async Task GlobalVersion_MultipleRequestHandlers_PicksHighestOne(string version) + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + CopyShimToOutput(deploymentParameters); + var deploymentResult = await DeployAsync(deploymentParameters); + + var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20); + + var newANCMPath = GetANCMRequestHandlerPath(deploymentResult, version); + + CopyDirectory(originalANCMPath, newANCMPath); + + deploymentResult.HttpClient.DefaultRequestHeaders.Add("ANCMRHPath", newANCMPath); + var response = await deploymentResult.HttpClient.GetAsync("CheckRequestHandlerVersion"); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(_helloWorldResponse, responseText); + AssertLoadedVersion(version); + } + + [ConditionalTheory] + [InlineData("2.1.0")] + [InlineData("2.1.0-preview")] + public async Task GlobalVersion_MultipleRequestHandlers_UpgradeWorks(string version) + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + CopyShimToOutput(deploymentParameters); + var deploymentResult = await DeployAsync(deploymentParameters); + + var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20); + + deploymentResult.HttpClient.DefaultRequestHeaders.Add("ANCMRHPath", originalANCMPath); + var response = await deploymentResult.HttpClient.GetAsync("CheckRequestHandlerVersion"); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(_helloWorldResponse, responseText); + + StopServer(); + + deploymentResult = await DeployAsync(deploymentParameters); + + originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20); + + var newANCMPath = GetANCMRequestHandlerPath(deploymentResult, version); + + CopyDirectory(originalANCMPath, newANCMPath); + + deploymentResult.HttpClient.DefaultRequestHeaders.Add("ANCMRHPath", newANCMPath); + response = await deploymentResult.HttpClient.GetAsync("CheckRequestHandlerVersion"); + responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal(_helloWorldResponse, responseText); + AssertLoadedVersion(version); + } + + [ConditionalFact] + public async Task DoesNotCrashWhenNoVersionsAvailable() + { + var deploymentParameters = GetGlobalVersionBaseDeploymentParameters(); + CopyShimToOutput(deploymentParameters); + var deploymentResult = await DeployAsync(deploymentParameters); + + var originalANCMPath = GetANCMRequestHandlerPath(deploymentResult, _handlerVersion20); + Directory.Delete(originalANCMPath, true); + var response = await deploymentResult.HttpClient.GetAsync("HelloWorld"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + } + + private IISDeploymentParameters GetGlobalVersionBaseDeploymentParameters() + { + return _fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess, publish: true); + } + + private void CopyDirectory(string from, string to) + { + var toInfo = new DirectoryInfo(to); + toInfo.Create(); + + foreach (var file in new DirectoryInfo(from).GetFiles()) + { + file.CopyTo(Path.Combine(toInfo.FullName, file.Name)); + } + } + + private string GetANCMRequestHandlerPath(IISDeploymentResult deploymentResult, string version) + { + return Path.Combine(deploymentResult.ContentRoot, + deploymentResult.DeploymentParameters.RuntimeArchitecture.ToString(), + version); + } + + private void AssertLoadedVersion(string version) + { + StopServer(); + Assert.Contains(TestSink.Writes, context => context.Message.Contains(version + @"\aspnetcorev2_outofprocess.dll")); + } + + private static void CopyShimToOutput(IISDeploymentParameters parameters) + { + parameters.AddServerConfigAction( + (config, contentRoot) => { + var moduleNodes = config.DescendantNodesAndSelf() + .OfType() + .Where(element => + element.Name == "add" && + element.Attribute("name")?.Value.StartsWith("AspNetCoreModule") == true && + element.Attribute("image") != null); + + var sourceDirectory = new DirectoryInfo(Path.GetDirectoryName(moduleNodes.First().Attribute("image").Value)); + var destinationDirectory = new DirectoryInfo(Path.Combine(contentRoot, sourceDirectory.Name)); + destinationDirectory.Create(); + foreach (var element in moduleNodes) + { + var imageAttribute = element.Attribute("image"); + imageAttribute.Value = imageAttribute.Value.Replace(sourceDirectory.FullName, destinationDirectory.FullName); + } + CopyFiles(sourceDirectory, destinationDirectory); + }); + } + + private static void CopyFiles(DirectoryInfo source, DirectoryInfo target) + { + foreach (DirectoryInfo directoryInfo in source.GetDirectories()) + { + CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name)); + } + + foreach (FileInfo fileInfo in source.GetFiles()) + { + var destFileName = Path.Combine(target.FullName, fileInfo.Name); + fileInfo.CopyTo(destFileName); + } + } + + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs b/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs new file mode 100644 index 0000000000..f6e36613d7 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs @@ -0,0 +1,81 @@ +// 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.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class HelloWorldTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public HelloWorldTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) + .WithAllApplicationTypes() + .WithAllAncmVersions(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task HelloWorld(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant); + deploymentParameters.ServerConfigActionList.Add( + (element, _) => { + element + .RequiredElement("system.webServer") + .RequiredElement("security") + .RequiredElement("authentication") + .Element("windowsAuthentication") + ?.SetAttributeValue("enabled", "false"); + }); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal("Hello World", responseText); + + response = await deploymentResult.HttpClient.GetAsync("/Path/%3F%3F?query"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal("/??", responseText); + + response = await deploymentResult.HttpClient.GetAsync("/Query/%3FPath?query?"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal("?query?", responseText); + + response = await deploymentResult.HttpClient.GetAsync("/BodyLimit"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal("null", responseText); + + response = await deploymentResult.HttpClient.GetAsync("/Auth"); + responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal("null", responseText); + + Assert.Equal( + $"ContentRootPath {deploymentResult.ContentRoot}" + Environment.NewLine + + $"WebRootPath {deploymentResult.ContentRoot}\\wwwroot" + Environment.NewLine + + $"CurrentDirectory {deploymentResult.ContentRoot}", + await deploymentResult.HttpClient.GetStringAsync("/HostingEnvironment")); + + var expectedDll = variant.AncmVersion == AncmVersion.AspNetCoreModule ? "aspnetcore.dll" : "aspnetcorev2.dll"; + Assert.Contains(deploymentResult.HostProcess.Modules.OfType(), m=> m.FileName.Contains(expectedDll)); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/PublishedSitesFixture.cs b/src/IISIntegration/test/Common.FunctionalTests/PublishedSitesFixture.cs new file mode 100644 index 0000000000..282ee26109 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/PublishedSitesFixture.cs @@ -0,0 +1,65 @@ +// 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.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + /// + /// This type just maps collection names to available fixtures + /// + [CollectionDefinition(Name)] + public class PublishedSitesCollection : ICollectionFixture, ICollectionFixture + { + public const string Name = nameof(PublishedSitesCollection); + } + + public class PublishedSitesFixture : IDisposable + { + public CachingApplicationPublisher InProcessTestSite { get; } = new CachingApplicationPublisher(Helpers.GetInProcessTestSitesPath()); + public CachingApplicationPublisher OutOfProcessTestSite { get; } = new CachingApplicationPublisher(Helpers.GetOutOfProcessTestSitesPath()); + + public void Dispose() + { + InProcessTestSite.Dispose(); + OutOfProcessTestSite.Dispose(); + } + + public IISDeploymentParameters GetBaseDeploymentParameters(HostingModel hostingModel = HostingModel.InProcess, bool publish = false) + { + var publisher = hostingModel == HostingModel.InProcess ? InProcessTestSite : OutOfProcessTestSite; + return GetBaseDeploymentParameters(publisher, hostingModel, publish); + } + public IISDeploymentParameters GetBaseDeploymentParameters(TestVariant variant, bool publish = false) + { + var publisher = variant.HostingModel == HostingModel.InProcess ? InProcessTestSite : OutOfProcessTestSite; + return GetBaseDeploymentParameters(publisher, new DeploymentParameters(variant), publish); + } + + public IISDeploymentParameters GetBaseDeploymentParameters(ApplicationPublisher publisher, HostingModel hostingModel = HostingModel.InProcess, bool publish = false) + { + return GetBaseDeploymentParameters( + publisher, + new DeploymentParameters(publisher.ApplicationPath, DeployerSelector.ServerType, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) + { + HostingModel = hostingModel, + TargetFramework = "netcoreapp2.2", + AncmVersion = AncmVersion.AspNetCoreModuleV2 + }, + publish); + } + + public IISDeploymentParameters GetBaseDeploymentParameters(ApplicationPublisher publisher, DeploymentParameters baseParameters, bool publish = false) + { + return new IISDeploymentParameters(baseParameters) + { + ApplicationPublisher = publisher, + ApplicationPath = publisher.ApplicationPath, + PublishApplicationBeforeDeployment = publish + }; + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/RequiresNewHandler.cs b/src/IISIntegration/test/Common.FunctionalTests/RequiresNewHandler.cs new file mode 100644 index 0000000000..cbe43ec0c7 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/RequiresNewHandler.cs @@ -0,0 +1,16 @@ +// 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.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class RequiresNewHandlerAttribute : Attribute, ITestCondition + { + public bool IsMet => !DeployerSelector.IsForwardsCompatibilityTest; + + public string SkipReason => "Test verifies new behavior in the aspnetcorev2_inprocess.dll that isn't supported in earlier versions."; + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/RequiresNewShim.cs b/src/IISIntegration/test/Common.FunctionalTests/RequiresNewShim.cs new file mode 100644 index 0000000000..b0bc50a83b --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/RequiresNewShim.cs @@ -0,0 +1,16 @@ +// 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.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class RequiresNewShimAttribute : Attribute, ITestCondition + { + public bool IsMet => !DeployerSelector.IsBackwardsCompatiblityTest; + + public string SkipReason => "Test verifies new behavior in the aspnetcorev2.dll that isn't supported in earlier versions."; + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/ServerAbortTests.cs b/src/IISIntegration/test/Common.FunctionalTests/ServerAbortTests.cs new file mode 100644 index 0000000000..8ebd70db12 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/ServerAbortTests.cs @@ -0,0 +1,65 @@ +// 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.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public abstract class ServerAbortTests: FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + [Collection(IISTestSiteCollection.Name)] + public class InProc: ServerAbortTests + { + public InProc(IISTestSiteFixture fixture) : base(fixture) { } + } + + [Collection(OutOfProcessTestSiteCollection.Name)] + public class OutOfProcess: ServerAbortTests + { + public OutOfProcess(OutOfProcessTestSiteFixture fixture) : base(fixture) { } + } + + [Collection(OutOfProcessV1TestSiteCollection.Name)] + public class OutOfProcessV1: ServerAbortTests + { + public OutOfProcessV1(OutOfProcessV1TestSiteFixture fixture) : base(fixture) { } + } + + protected ServerAbortTests(IISTestSiteFixture fixture) : base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task ClosesConnectionOnServerAbort() + { + try + { + var response = await _fixture.Client.GetAsync("/Abort").DefaultTimeout(); + + // 502 is expected for outofproc but not for inproc + if (_fixture.DeploymentResult.DeploymentParameters.HostingModel == HostingModel.OutOfProcess) + { + Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode); + // 0x80072f78 ERROR_HTTP_INVALID_SERVER_RESPONSE The server returned an invalid or unrecognized response + Assert.Contains("0x80072f78", await response.Content.ReadAsStringAsync()); + } + else + { + Assert.True(false, "Should not reach here"); + } + } + catch (HttpRequestException) + { + // Connection reset is expected both for outofproc and inproc + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs b/src/IISIntegration/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs new file mode 100644 index 0000000000..d2acb70415 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/SkipIfNotAdminAttribute.cs @@ -0,0 +1,25 @@ +// 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.Security.Principal; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class SkipIfNotAdminAttribute : Attribute, ITestCondition + { + public bool IsMet + { + get + { + var identity = WindowsIdentity.GetCurrent(); + var principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } + + public string SkipReason => "The current process is not running as admin."; + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/SkipVSTSAttribute.cs b/src/IISIntegration/test/Common.FunctionalTests/SkipVSTSAttribute.cs new file mode 100644 index 0000000000..8e88fc8c26 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/SkipVSTSAttribute.cs @@ -0,0 +1,17 @@ +// 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.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class SkipInVSTSAttribute : Attribute, ITestCondition + { + public bool IsMet => string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SYSTEM_TASKDEFINITIONSURI")); + + public string SkipReason => "Running in VSTS"; + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/AppVerifier.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/AppVerifier.cs new file mode 100644 index 0000000000..7984193e29 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/AppVerifier.cs @@ -0,0 +1,83 @@ +// 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.Diagnostics; +using System.Linq; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class AppVerifier + { + private static readonly TimeSpan AppVerifierCommandTimeout = TimeSpan.FromSeconds(5); + + public static IDisposable Disable(ServerType serverType, int code) + { + // Set in SetupTestEnvironment.ps1 + var enabledCodes = (Environment.GetEnvironmentVariable("APPVERIFIER_ENABLED_CODES") ?? "").Split(' '); + string processName; + switch (serverType) + { + case ServerType.IISExpress: + processName = "iisexpress.exe"; + break; + case ServerType.IIS: + processName = "w3wp.exe"; + break; + default: + throw new ArgumentOutOfRangeException(nameof(serverType), serverType, null); + } + + if (!enabledCodes.Contains(code.ToString())) + { + return null; + } + + RunProcessAndWaitForExit("appverif.exe", $"-configure {code} -for {processName} -with ErrorReport=0", AppVerifierCommandTimeout); + return new AppVerifierToken(processName, code.ToString()); + } + + private static void RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout) + { + var startInfo = new ProcessStartInfo + { + FileName = fileName, + Arguments = arguments, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + }; + + var process = Process.Start(startInfo); + + if (!process.WaitForExit((int)timeout.TotalMilliseconds)) + { + process.Kill(); + } + + if (process.ExitCode != 0) + { + throw new InvalidOperationException($"Exit code {process.ExitCode} when running {fileName} {arguments}. Stdout: {process.StandardOutput.ReadToEnd()} Stderr: {process.StandardError.ReadToEnd()}"); + } + } + + public class AppVerifierToken : IDisposable + { + private readonly string _processName; + + private readonly string _codes; + + public AppVerifierToken(string processName, string codes) + { + _processName = processName; + _codes = codes; + } + + public void Dispose() + { + // + RunProcessAndWaitForExit("appverif.exe", $"-configure {_codes} -for {_processName} -with ErrorReport={Environment.GetEnvironmentVariable("APPVERIFIER_LEVEL")}", AppVerifierCommandTimeout); + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs new file mode 100644 index 0000000000..78c77fd2ca --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/EventLogHelpers.cs @@ -0,0 +1,210 @@ +// 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.Diagnostics; +using System.Linq; +using System.Text.RegularExpressions; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.Extensions.Logging; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class EventLogHelpers + { + public static void VerifyEventLogEvent(IISDeploymentResult deploymentResult, string expectedRegexMatchString) + { + Assert.True(deploymentResult.HostProcess.HasExited); + + var entries = GetEntries(deploymentResult); + AssertSingleEntry(expectedRegexMatchString, entries); + } + + public static void VerifyEventLogEvent(IISDeploymentResult deploymentResult, string expectedRegexMatchString, ILogger logger) + { + Assert.True(deploymentResult.HostProcess.HasExited); + + var entries = GetEntries(deploymentResult); + try + { + AssertSingleEntry(expectedRegexMatchString, entries); + } + catch (Exception ex) + { + foreach (var entry in entries) + { + logger.LogInformation(entry.Message); + } + throw ex; + } + } + + public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, params string[] expectedRegexMatchString) + { + Assert.True(deploymentResult.HostProcess.HasExited); + + var entries = GetEntries(deploymentResult).ToList(); + foreach (var regexString in expectedRegexMatchString) + { + var matchedEntries = AssertSingleEntry(regexString, entries); + + foreach (var matchedEntry in matchedEntries) + { + entries.Remove(matchedEntry); + } + } + + Assert.True(0 == entries.Count, $"Some entries were not matched by any regex {FormatEntries(entries)}"); + } + + private static EventLogEntry[] AssertSingleEntry(string regexString, IEnumerable entries) + { + var expectedRegex = new Regex(regexString, RegexOptions.Singleline); + var matchedEntries = entries.Where(entry => expectedRegex.IsMatch(entry.Message)).ToArray(); + Assert.True(matchedEntries.Length > 0, $"No entries matched by '{regexString}'"); + Assert.True(matchedEntries.Length < 2, $"Multiple entries matched by '{regexString}': {FormatEntries(matchedEntries)}"); + return matchedEntries; + } + + private static string FormatEntries(IEnumerable entries) + { + return string.Join(",", entries.Select(e => e.Message)); + } + + private static IEnumerable GetEntries(IISDeploymentResult deploymentResult) + { + var eventLog = new EventLog("Application"); + + // Eventlog is already sorted based on time of event in ascending time. + // Check results in reverse order. + var processIdString = $"Process Id: {deploymentResult.HostProcess.Id}."; + + // Event log messages round down to the nearest second, so subtract a second + var processStartTime = deploymentResult.HostProcess.StartTime.AddSeconds(-1); + for (var i = eventLog.Entries.Count - 1; i >= 0; i--) + { + var eventLogEntry = eventLog.Entries[i]; + if (eventLogEntry.TimeGenerated < processStartTime) + { + // If event logs is older than the process start time, we didn't find a match. + break; + } + + if (eventLogEntry.ReplacementStrings == null || + eventLogEntry.ReplacementStrings.Length < 3) + { + continue; + } + + // ReplacementStings == EventData collection in EventLog + // This is unaffected if event providers are not registered correctly + if (eventLogEntry.Source == AncmVersionToMatch(deploymentResult) && + processIdString == eventLogEntry.ReplacementStrings[1]) + { + yield return eventLogEntry; + } + } + } + + private static string AncmVersionToMatch(IISDeploymentResult deploymentResult) + { + return "IIS " + + (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress ? "Express " : "") + + "AspNetCore Module" + + (deploymentResult.DeploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2 ? " V2" : ""); + } + + public static string Started(IISDeploymentResult deploymentResult) + { + if (deploymentResult.DeploymentParameters.HostingModel == HostingModel.InProcess) + { + return InProcessStarted(deploymentResult); + } + else + { + return OutOfProcessStarted(deploymentResult); + } + } + + public static string InProcessStarted(IISDeploymentResult deploymentResult) + { + return $"Application '{EscapedContentRoot(deploymentResult)}' started the coreclr in-process successfully"; + } + + public static string OutOfProcessStarted(IISDeploymentResult deploymentResult) + { + return $"Application '/LM/W3SVC/1/ROOT' started process '\\d+' successfully and process '\\d+' is listening on port '\\d+'."; + } + + public static string InProcessFailedToStart(IISDeploymentResult deploymentResult, string reason) + { + return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to load clr and managed application. {reason}"; + } + + public static string InProcessFailedToStop(IISDeploymentResult deploymentResult, string reason) + { + return "Failed to gracefully shutdown application 'MACHINE/WEBROOT/APPHOST/.*?'."; + } + + public static string InProcessThreadException(IISDeploymentResult deploymentResult, string reason) + { + return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' hit unexpected managed exception{reason}"; + } + + public static string InProcessThreadExit(IISDeploymentResult deploymentResult, string code) + { + return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' hit unexpected managed background thread exit, exit code = '{code}'."; + } + public static string InProcessThreadExitStdOut(IISDeploymentResult deploymentResult, string code, string output) + { + return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' hit unexpected managed background thread exit, exit code = '{code}'. Last 4KB characters of captured stdout and stderr logs:\r\n{output}"; + } + + public static string FailedToStartApplication(IISDeploymentResult deploymentResult, string code) + { + return $"Failed to start application '/LM/W3SVC/1/ROOT', ErrorCode '{code}'."; + } + + public static string ConfigurationLoadError(IISDeploymentResult deploymentResult, string reason) + { + return $"Could not load configuration. Exception message: {reason}"; + } + + public static string OutOfProcessFailedToStart(IISDeploymentResult deploymentResult) + { + return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to start process with " + + $"commandline '(.*)' with multiple retries. " + + $"The last try of listening port is '(.*)'. See previous warnings for details."; + } + + public static string InProcessHostfxrInvalid(IISDeploymentResult deploymentResult) + { + return $"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '(.*)'."; + } + + public static string InProcessFailedToFindNativeDependencies(IISDeploymentResult deploymentResult) + { + return "Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. " + + "This most likely means the app is misconfigured, please check the versions of Microsoft.NetCore.App and Microsoft.AspNetCore.App that " + + "are targeted by the application and are installed on the machine."; + } + + public static string InProcessFailedToFindRequestHandler(IISDeploymentResult deploymentResult) + { + return "Could not find the assembly '(.*)' referenced for the in-process application. Please confirm the Microsoft.AspNetCore.Server.IIS package is referenced in your application."; + } + + private static string EscapedContentRoot(IISDeploymentResult deploymentResult) + { + var contentRoot = deploymentResult.ContentRoot; + if (!contentRoot.EndsWith('\\')) + { + contentRoot += '\\'; + } + return Regex.Escape(contentRoot); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs new file mode 100644 index 0000000000..1a1a4ce490 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/FunctionalTestsBase.cs @@ -0,0 +1,59 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.Extensions.Logging.Testing; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class FunctionalTestsBase : LoggedTest + { + private const string DebugEnvironmentVariable = "ASPNETCORE_MODULE_DEBUG"; + + public FunctionalTestsBase(ITestOutputHelper output = null) : base(output) + { + } + + protected IISDeployerBase _deployer; + + protected ApplicationDeployer CreateDeployer(IISDeploymentParameters parameters) + { + if (parameters.ServerType == ServerType.IISExpress && + !parameters.EnvironmentVariables.ContainsKey(DebugEnvironmentVariable)) + { + parameters.EnvironmentVariables[DebugEnvironmentVariable] = "console"; + } + + return IISApplicationDeployerFactory.Create(parameters, LoggerFactory); + } + + protected virtual async Task DeployAsync(IISDeploymentParameters parameters) + { + _deployer = (IISDeployerBase)CreateDeployer(parameters); + return (IISDeploymentResult)await _deployer.DeployAsync(); + } + + protected virtual async Task StartAsync(IISDeploymentParameters parameters) + { + var result = await DeployAsync(parameters); + await result.AssertStarts(); + return result; + } + + public override void Dispose() + { + StopServer(false); + } + + public void StopServer(bool gracefulShutdown = true) + { + _deployer?.Dispose(gracefulShutdown); + _deployer = null; + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/Helpers.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/Helpers.cs new file mode 100644 index 0000000000..1e31126eab --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/Helpers.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.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class Helpers + { + private static readonly TimeSpan RetryRequestDelay = TimeSpan.FromMilliseconds(100); + private static readonly int RetryRequestCount = 10; + + public static string GetTestWebSitePath(string name) + { + return Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"),"test", "WebSites", name); + } + + public static string GetInProcessTestSitesPath() + { + return DeployerSelector.IsForwardsCompatibilityTest ? GetTestWebSitePath("InProcessForwardsCompatWebSite") : GetTestWebSitePath("InProcessWebSite"); + } + + public static string GetOutOfProcessTestSitesPath() => GetTestWebSitePath("OutOfProcessWebSite"); + + public static async Task AssertStarts(this IISDeploymentResult deploymentResult, string path = "/HelloWorld") + { + var response = await deploymentResult.HttpClient.GetAsync(path); + + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.Equal("Hello World", responseText); + } + + public static async Task StressLoad(HttpClient httpClient, string path, Action action) + { + async Task RunRequests() + { + var connection = new HttpClient() { BaseAddress = httpClient.BaseAddress }; + + for (int j = 0; j < 10; j++) + { + var response = await connection.GetAsync(path); + action(response); + } + } + + List tasks = new List(); + for (int i = 0; i < 10; i++) + { + tasks.Add(Task.Run(RunRequests)); + } + + await Task.WhenAll(tasks); + } + + public static string GetFrebFolder(string folder, IISDeploymentResult result) + { + if (result.DeploymentParameters.ServerType == ServerType.IISExpress) + { + return Path.Combine(folder, result.DeploymentParameters.SiteName); + } + else + { + return Path.Combine(folder, "W3SVC1"); + } + } + + public static void CopyFiles(DirectoryInfo source, DirectoryInfo target, ILogger logger) + { + foreach (DirectoryInfo directoryInfo in source.GetDirectories()) + { + if (directoryInfo.FullName != target.FullName) + { + CopyFiles(directoryInfo, target.CreateSubdirectory(directoryInfo.Name), logger); + } + } + logger?.LogDebug($"Processing {target.FullName}"); + foreach (FileInfo fileInfo in source.GetFiles()) + { + logger?.LogDebug($" Copying {fileInfo.Name}"); + var destFileName = Path.Combine(target.FullName, fileInfo.Name); + fileInfo.CopyTo(destFileName); + } + } + + public static void ModifyWebConfig(this DeploymentResult deploymentResult, Action action) + { + var webConfigPath = Path.Combine(deploymentResult.ContentRoot, "web.config"); + var document = XDocument.Load(webConfigPath); + action(document.Root); + document.Save(webConfigPath); + } + + public static Task RetryRequestAsync(this HttpClient client, string uri, Func predicate) + { + return RetryRequestAsync(client, uri, message => Task.FromResult(predicate(message))); + } + + public static async Task RetryRequestAsync(this HttpClient client, string uri, Func> predicate) + { + HttpResponseMessage response = await client.GetAsync(uri); + + for (var i = 0; i < RetryRequestCount && !await predicate(response); i++) + { + // Keep retrying until app_offline is present. + response = await client.GetAsync(uri); + await Task.Delay(RetryRequestDelay); + } + + if (!await predicate(response)) + { + throw new InvalidOperationException($"Didn't get response that satisfies predicate after {RetryRequestCount} retries"); + } + + return response; + } + + public static async Task Retry(Func func, int attempts, int msDelay) + { + var exceptions = new List(); + + for (var attempt = 0; attempt < attempts; attempt++) + { + try + { + await func(); + return; + } + catch (Exception e) + { + exceptions.Add(e); + } + await Task.Delay(msDelay); + } + + throw new AggregateException(exceptions); + } + + public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult, int? timeout = null) + { + var hostProcess = deploymentResult.HostProcess; + Assert.True(hostProcess.WaitForExit(timeout ?? (int)TimeoutExtensions.DefaultTimeoutValue.TotalMilliseconds)); + + if (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress) + { + Assert.Equal(0, hostProcess.ExitCode); + } + } + + + public static async Task AssertRecycledAsync(this IISDeploymentResult deploymentResult, Func verificationAction = null) + { + if (deploymentResult.DeploymentParameters.HostingModel != HostingModel.InProcess) + { + throw new NotSupportedException(); + } + + deploymentResult.AssertWorkerProcessStop(); + if (deploymentResult.DeploymentParameters.ServerType == ServerType.IIS) + { + verificationAction = verificationAction ?? (() => deploymentResult.AssertStarts()); + await verificationAction(); + } + } + + public static IEnumerable ToTheoryData(this Dictionary dictionary) + { + return dictionary.Keys.Select(k => new[] { k }); + } + + public static string GetExpectedLogName(IISDeploymentResult deploymentResult, string logFolderPath) + { + var startTime = deploymentResult.HostProcess.StartTime.ToUniversalTime(); + + if (deploymentResult.DeploymentParameters.HostingModel == HostingModel.InProcess) + { + return Path.Combine(logFolderPath, $"std_{startTime.Year}{startTime.Month:D2}" + + $"{startTime.Day:D2}{startTime.Hour:D2}" + + $"{startTime.Minute:D2}{startTime.Second:D2}_" + + $"{deploymentResult.HostProcess.Id}.log"); + } + else + { + return Directory.GetFiles(logFolderPath).Single(); + } + } + + public static void ModifyFrameworkVersionInRuntimeConfig(IISDeploymentResult deploymentResult) + { + var path = Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.runtimeconfig.json"); + dynamic depsFileContent = JsonConvert.DeserializeObject(File.ReadAllText(path)); + depsFileContent["runtimeOptions"]["framework"]["version"] = "2.9.9"; + var output = JsonConvert.SerializeObject(depsFileContent); + File.WriteAllText(path, output); + } + + public static void AllowNoLogs(this IISDeploymentResult deploymentResult) + { + File.AppendAllText( + Path.Combine(deploymentResult.DeploymentParameters.PublishedApplicationRootPath, "aspnetcore-debug.log"), + "Running test allowed log file to be empty." + Environment.NewLine); + } + + public static string ReadAllTextFromFile(string filename, ILogger logger) + { + try + { + return File.ReadAllText(filename); + } + catch (Exception ex) + { + // check if there is a dotnet.exe, iisexpress.exe, or w3wp.exe processes still running. + var hostingProcesses = Process.GetProcessesByName("dotnet") + .Concat(Process.GetProcessesByName("iisexpress")) + .Concat(Process.GetProcessesByName("w3wp")); + + logger.LogError($"Could not read file content. Exception message {ex.Message}"); + logger.LogError("Current hosting exes running:"); + + foreach (var hostingProcess in hostingProcesses) + { + logger.LogError($"{hostingProcess.ProcessName} pid: {hostingProcess.Id} hasExited: {hostingProcess.HasExited.ToString()}"); + } + throw ex; + } + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCapability.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCapability.cs new file mode 100644 index 0000000000..0a080bb702 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCapability.cs @@ -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 System; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Flags] + public enum IISCapability + { + None = 0, + Websockets = 1, + WindowsAuthentication = 2, + PoolEnvironmentVariables = 4, + ShutdownToken = 8, + DynamicCompression = 16, + ApplicationInitialization = 32, + TracingModule = 64, + FailedRequestTracingModule = 128, + BasicAuthentication = 256 + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs new file mode 100644 index 0000000000..2c424943f3 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteCollection.cs @@ -0,0 +1,13 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [CollectionDefinition(Name)] + public class IISCompressionSiteCollection : ICollectionFixture + { + public const string Name = nameof(IISCompressionSiteCollection); + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs new file mode 100644 index 0000000000..3aff68d11b --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISCompressionSiteFixture.cs @@ -0,0 +1,44 @@ +// 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.Net.Http; +using System.Threading; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class IISCompressionSiteFixture : IISTestSiteFixture + { + public IISCompressionSiteFixture() : base(Configure) + { + } + + private static void Configure(IISDeploymentParameters deploymentParameters) + { + // Enable dynamic compression + deploymentParameters.ServerConfigActionList.Add( + (element, _) => { + var webServerElement = element + .RequiredElement("system.webServer"); + + webServerElement + .GetOrAdd("urlCompression") + .SetAttributeValue("doDynamicCompression", "true"); + + webServerElement + .GetOrAdd("httpCompression") + .GetOrAdd("dynamicTypes") + .GetOrAdd("add", "mimeType", "text/*") + .SetAttributeValue("enabled", "true"); + + }); + + deploymentParameters.EnableModule("DynamicCompressionModule", "%IIS_BIN%\\compdyn.dll"); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs new file mode 100644 index 0000000000..a20a5e2e0e --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISFunctionalTestBase.cs @@ -0,0 +1,15 @@ +// 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.Server.IntegrationTesting; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities +{ + public class IISFunctionalTestBase : FunctionalTestsBase + { + public IISFunctionalTestBase(ITestOutputHelper output = null) : base(output) + { + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs new file mode 100644 index 0000000000..562d63adbe --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteCollection.cs @@ -0,0 +1,29 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + /// + /// This type just maps collection names to available fixtures + /// + [CollectionDefinition(Name)] + public class IISTestSiteCollection : ICollectionFixture + { + public const string Name = nameof(IISTestSiteCollection); + } + + [CollectionDefinition(Name)] + public class OutOfProcessTestSiteCollection : ICollectionFixture + { + public const string Name = nameof(OutOfProcessTestSiteCollection); + } + + [CollectionDefinition(Name)] + public class OutOfProcessV1TestSiteCollection : ICollectionFixture + { + public const string Name = nameof(OutOfProcessV1TestSiteCollection); + } + +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs new file mode 100644 index 0000000000..e8cfd8f641 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs @@ -0,0 +1,191 @@ +// 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.Net.Http; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class OutOfProcessTestSiteFixture : IISTestSiteFixture + { + public OutOfProcessTestSiteFixture() : base(Configure) + { + } + + private static void Configure(IISDeploymentParameters deploymentParameters) + { + deploymentParameters.ApplicationPath = Helpers.GetOutOfProcessTestSitesPath(); + deploymentParameters.HostingModel = HostingModel.OutOfProcess; + } + } + + public class OutOfProcessV1TestSiteFixture : IISTestSiteFixture + { + public OutOfProcessV1TestSiteFixture() : base(Configure) + { + } + + private static void Configure(IISDeploymentParameters deploymentParameters) + { + deploymentParameters.ApplicationPath = Helpers.GetOutOfProcessTestSitesPath(); + deploymentParameters.HostingModel = HostingModel.OutOfProcess; + deploymentParameters.AncmVersion = AncmVersion.AspNetCoreModule; + } + } + + public class IISTestSiteFixture : IDisposable + { + private ApplicationDeployer _deployer; + private ILoggerFactory _loggerFactory; + private ForwardingProvider _forwardingProvider; + private IISDeploymentResult _deploymentResult; + private readonly Action _configure; + + public IISTestSiteFixture() : this(_ => { }) + { + } + + public IISTestSiteFixture(Action configure) + { + var logging = AssemblyTestLog.ForAssembly(typeof(IISTestSiteFixture).Assembly); + _loggerFactory = logging.CreateLoggerFactory(null, nameof(IISTestSiteFixture)); + + _forwardingProvider = new ForwardingProvider(); + _loggerFactory.AddProvider(_forwardingProvider); + + _configure = configure; + } + + public HttpClient Client => DeploymentResult.HttpClient; + public IISDeploymentResult DeploymentResult + { + get + { + EnsureInitialized(); + return _deploymentResult; + } + } + + public TestConnection CreateTestConnection() + { + return new TestConnection(Client.BaseAddress.Port); + } + + public void Dispose() + { + _deployer?.Dispose(); + } + + public void Attach(LoggedTest test) + { + if (_forwardingProvider.LoggerFactory != null) + { + throw new InvalidOperationException("Test instance is already attached to this fixture"); + } + + _forwardingProvider.LoggerFactory = test.LoggerFactory; + } + + public void Detach(LoggedTest test) + { + if (_forwardingProvider.LoggerFactory != test.LoggerFactory) + { + throw new InvalidOperationException("Different test is attached to this fixture"); + } + + _forwardingProvider.LoggerFactory = null; + } + + private void EnsureInitialized() + { + if (_deployer != null) + { + return; + } + + var deploymentParameters = new IISDeploymentParameters(Helpers.GetInProcessTestSitesPath(), + DeployerSelector.ServerType, + RuntimeFlavor.CoreClr, + RuntimeArchitecture.x64) + { + TargetFramework = Tfm.NetCoreApp22, + AncmVersion = AncmVersion.AspNetCoreModuleV2, + HostingModel = HostingModel.InProcess, + PublishApplicationBeforeDeployment = true, + }; + + _configure(deploymentParameters); + + _deployer = IISApplicationDeployerFactory.Create(deploymentParameters, _loggerFactory); + _deploymentResult = (IISDeploymentResult)_deployer.DeployAsync().Result; + } + + private class ForwardingProvider : ILoggerProvider + { + private readonly List _loggers = new List(); + + private ILoggerFactory _loggerFactory; + + public ILoggerFactory LoggerFactory + { + get => _loggerFactory; + set + { + + lock (_loggers) + { + _loggerFactory = value; + foreach (var logger in _loggers) + { + logger.Logger = _loggerFactory?.CreateLogger("FIXTURE:" + logger.Name); + } + } + } + } + + public void Dispose() + { + lock (_loggers) + { + _loggers.Clear(); + } + } + + public ILogger CreateLogger(string categoryName) + { + lock (_loggers) + { + var logger = new ForwardingLogger(categoryName); + _loggers.Add(logger); + return logger; + } + } + } + + internal class ForwardingLogger : ILogger + { + public ForwardingLogger(string name) + { + Name = name; + } + + public ILogger Logger { get; set; } + public string Name { get; set; } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + Logger?.Log(logLevel, eventId, state, exception, formatter); + } + + public bool IsEnabled(LogLevel logLevel) => Logger?.IsEnabled(logLevel) == true; + + public IDisposable BeginScope(TState state) => Logger?.BeginScope(state); + } + } + +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs new file mode 100644 index 0000000000..17885f3547 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/LogFileTestBase.cs @@ -0,0 +1,34 @@ +// 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.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities +{ + public class LogFileTestBase : IISFunctionalTestBase + { + protected string _logFolderPath; + + public LogFileTestBase(ITestOutputHelper output = null) : base(output) + { + _logFolderPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + } + public override void Dispose() + { + base.Dispose(); + if (Directory.Exists(_logFolderPath)) + { + Directory.Delete(_logFolderPath, true); + } + } + + public string GetLogFileContent(IISDeploymentResult deploymentResult) + { + return Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, _logFolderPath), Logger); + } + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs new file mode 100644 index 0000000000..d2749db547 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/RequiresEnvironmentVariableAttribute.cs @@ -0,0 +1,24 @@ +// 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.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class RequiresEnvironmentVariableAttribute : Attribute, ITestCondition + { + private readonly string _name; + + public RequiresEnvironmentVariableAttribute(string name) + { + _name = name; + } + + public bool IsMet => !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(_name)); + + public string SkipReason => $"Environment variable {_name} is required to run this test."; + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs b/src/IISIntegration/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs new file mode 100644 index 0000000000..6cdd725392 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/Utilities/SkipIfDebugAttribute.cs @@ -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 System; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class SkipIfDebugAttribute : Attribute, ITestCondition + { + public bool IsMet => + #if DEBUG + false; + #else + true; + #endif + + public string SkipReason => "Test cannot be run in Debug mode."; + } +} diff --git a/src/IISIntegration/test/Common.FunctionalTests/WindowsAuthTests.cs b/src/IISIntegration/test/Common.FunctionalTests/WindowsAuthTests.cs new file mode 100644 index 0000000000..8431b15801 --- /dev/null +++ b/src/IISIntegration/test/Common.FunctionalTests/WindowsAuthTests.cs @@ -0,0 +1,52 @@ +// 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 System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class WindowsAuthTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public WindowsAuthTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) + .WithApplicationTypes(ApplicationType.Portable) + .WithAllAncmVersions() + .WithAllHostingModels(); + + [ConditionalTheory] + [RequiresIIS(IISCapability.WindowsAuthentication)] + [MemberData(nameof(TestVariants))] + public async Task WindowsAuthTest(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant); + deploymentParameters.SetAnonymousAuth(enabled: false); + deploymentParameters.SetWindowsAuth(); + + // The default in hosting sets windows auth to true. + var deploymentResult = await DeployAsync(deploymentParameters); + + var client = deploymentResult.CreateClient(new HttpClientHandler { UseDefaultCredentials = true }); + var response = await client.GetAsync("/Auth"); + var responseText = await response.Content.ReadAsStringAsync(); + + Assert.StartsWith("Windows:", responseText); + Assert.Contains(Environment.UserName, responseText); + } + } +} diff --git a/src/IISIntegration/test/Common.Tests/Common.Tests.csproj b/src/IISIntegration/test/Common.Tests/Common.Tests.csproj new file mode 100644 index 0000000000..ede80732ee --- /dev/null +++ b/src/IISIntegration/test/Common.Tests/Common.Tests.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp2.2 + false + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/Common.Tests/Utilities/DisposableList.cs b/src/IISIntegration/test/Common.Tests/Utilities/DisposableList.cs new file mode 100644 index 0000000000..78f76e41c2 --- /dev/null +++ b/src/IISIntegration/test/Common.Tests/Utilities/DisposableList.cs @@ -0,0 +1,25 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + public class DisposableList : List, IDisposable where T : IDisposable + { + public DisposableList() : base() { } + + public DisposableList(IEnumerable collection) : base(collection) { } + + public DisposableList(int capacity) : base(capacity) { } + + public void Dispose() + { + foreach (var item in this) + { + item?.Dispose(); + } + } + } +} diff --git a/src/IISIntegration/test/Common.Tests/Utilities/TestConnections.cs b/src/IISIntegration/test/Common.Tests/Utilities/TestConnections.cs new file mode 100644 index 0000000000..3b7a870cf3 --- /dev/null +++ b/src/IISIntegration/test/Common.Tests/Utilities/TestConnections.cs @@ -0,0 +1,252 @@ +// 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.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + /// + /// Summary description for TestConnection + /// + public class TestConnection : IDisposable + { + private static readonly TimeSpan Timeout = TimeSpan.FromMinutes(1); + + private readonly bool _ownsSocket; + private readonly Socket _socket; + private readonly NetworkStream _stream; + + public TestConnection(int port) + : this(port, AddressFamily.InterNetwork) + { + } + + public TestConnection(int port, AddressFamily addressFamily) + : this(CreateConnectedLoopbackSocket(port, addressFamily), ownsSocket: true) + { + } + + public TestConnection(Socket socket) + : this(socket, ownsSocket: false) + { + } + + private TestConnection(Socket socket, bool ownsSocket) + { + _ownsSocket = ownsSocket; + _socket = socket; + _stream = new NetworkStream(_socket, ownsSocket: false); + } + + public Socket Socket => _socket; + public Stream Stream => _stream; + + public void Dispose() + { + _stream.Dispose(); + + if (_ownsSocket) + { + _socket.Dispose(); + } + } + + public async Task Send(params string[] lines) + { + var bytes = Encoding.ASCII.GetBytes(string.Join("\r\n", lines)); + + for (var index = 0; index < bytes.Length; index++) + { + await _stream.WriteAsync(bytes, index, 1).ConfigureAwait(false); + await _stream.FlushAsync().ConfigureAwait(false); + // Re-add delay to help find socket input consumption bugs more consistently + //await Task.Delay(TimeSpan.FromMilliseconds(5)); + } + } + + public async Task ReadCharAsync() + { + var bytes = new byte[1]; + return (await _stream.ReadAsync(bytes, 0, 1) == 1) ? bytes[0] : -1; + } + + public async Task ReadLineAsync() + { + var builder = new StringBuilder(); + var current = await ReadCharAsync(); + while (current != '\r') + { + builder.Append((char)current); + current = await ReadCharAsync(); + } + + // Consume \n + await ReadCharAsync(); + + return builder.ToString(); + } + + public async Task> ReceiveChunk() + { + var length = int.Parse(await ReadLineAsync(), System.Globalization.NumberStyles.HexNumber); + + var bytes = await Receive(length); + + await ReadLineAsync(); + + return bytes; + } + + public async Task ReceiveChunk(string expected) + { + Assert.Equal(expected, Encoding.ASCII.GetString((await ReceiveChunk()).Span)); + } + + public async Task Receive(params string[] lines) + { + var expected = string.Join("\r\n", lines); + var actual = await Receive(expected.Length); + + Assert.Equal(expected, Encoding.ASCII.GetString(actual.Span)); + } + + private async Task> Receive(int length) + { + var actual = new byte[length]; + int offset = 0; + try + { + while (offset < length) + { + var task = _stream.ReadAsync(actual, offset, actual.Length - offset); + if (!Debugger.IsAttached) + { + task = task.TimeoutAfter(Timeout); + } + + var count = await task.ConfigureAwait(false); + if (count == 0) + { + break; + } + + offset += count; + } + } + catch (TimeoutException ex) when (offset != 0) + { + throw new TimeoutException( + $"Did not receive a complete response within {Timeout}.{Environment.NewLine}{Environment.NewLine}" + + $"Expected:{Environment.NewLine}{length} bytes of data{Environment.NewLine}{Environment.NewLine}" + + $"Actual:{Environment.NewLine}{Encoding.ASCII.GetString(actual, 0, offset)}{Environment.NewLine}", + ex); + } + + return actual.AsMemory(0, offset); + } + + public async Task ReceiveStartsWith(string prefix, int maxLineLength = 1024) + { + var actual = new byte[maxLineLength]; + var offset = 0; + + while (offset < maxLineLength) + { + // Read one char at a time so we don't read past the end of the line. + var task = _stream.ReadAsync(actual, offset, 1); + if (!Debugger.IsAttached) + { + Assert.True(task.Wait(4000), "timeout"); + } + var count = await task.ConfigureAwait(false); + if (count == 0) + { + break; + } + + Assert.True(count == 1); + offset++; + + if (actual[offset - 1] == '\n') + { + break; + } + } + + var actualLine = Encoding.ASCII.GetString(actual, 0, offset); + Assert.StartsWith(prefix, actualLine); + } + + public async Task ReceiveHeaders(params string[] lines) + { + List headers = new List(); + string line; + do + { + line = await ReadLineAsync(); + headers.Add(line); + } while (line != ""); + + foreach (var s in lines) + { + Assert.Contains(s, headers); + } + + return headers.ToArray(); + } + + public Task WaitForConnectionClose() + { + var tcs = new TaskCompletionSource(); + var eventArgs = new SocketAsyncEventArgs(); + eventArgs.SetBuffer(new byte[128], 0, 128); + eventArgs.Completed += ReceiveAsyncCompleted; + eventArgs.UserToken = tcs; + + if (!_socket.ReceiveAsync(eventArgs)) + { + ReceiveAsyncCompleted(this, eventArgs); + } + + return tcs.Task; + } + + private void ReceiveAsyncCompleted(object sender, SocketAsyncEventArgs e) + { + var tcs = (TaskCompletionSource)e.UserToken; + if (e.BytesTransferred == 0) + { + tcs.SetResult(null); + } + else + { + tcs.SetException(new IOException( + $"Expected connection close, received data instead: \"{Encoding.ASCII.GetString(e.Buffer, 0, e.BytesTransferred)}\"")); + } + } + + public static Socket CreateConnectedLoopbackSocket(int port, AddressFamily addressFamily) + { + if (addressFamily != AddressFamily.InterNetwork && addressFamily != AddressFamily.InterNetworkV6) + { + throw new ArgumentException($"TestConnection does not support address family of type {addressFamily}", nameof(addressFamily)); + } + + var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); + var address = addressFamily == AddressFamily.InterNetworkV6 + ? IPAddress.IPv6Loopback + : IPAddress.Loopback; + socket.Connect(new IPEndPoint(address, port)); + return socket; + } + } +} diff --git a/src/IISIntegration/test/Common.Tests/Utilities/TimeoutExtensions.cs b/src/IISIntegration/test/Common.Tests/Utilities/TimeoutExtensions.cs new file mode 100644 index 0000000000..ce7175dff9 --- /dev/null +++ b/src/IISIntegration/test/Common.Tests/Utilities/TimeoutExtensions.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 System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; + +namespace Microsoft.AspNetCore.Server.IntegrationTesting +{ + + public static class TimeoutExtensions + { + public static TimeSpan DefaultTimeoutValue = TimeSpan.FromSeconds(300); + + public static Task DefaultTimeout(this Task task, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = -1) + { + return task.TimeoutAfter(DefaultTimeoutValue, filePath, lineNumber); + } + + public static Task DefaultTimeout(this Task task, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = -1) + { + return task.TimeoutAfter(DefaultTimeoutValue, filePath, lineNumber); + } + } +} diff --git a/src/IISIntegration/test/CommonLibTests/CommonLibTests.vcxproj b/src/IISIntegration/test/CommonLibTests/CommonLibTests.vcxproj new file mode 100644 index 0000000000..87dbd16675 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/CommonLibTests.vcxproj @@ -0,0 +1,196 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {1eac8125-1765-4e2d-8cbe-56dc98a1c8c1} + Win32Proj + 10.0.15063.0 + Application + v141 + Unicode + + + + + + + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + + + + + + + + + + + + + + + + + + {ec82302f-d2f0-4727-99d1-eabc0dd9dc3b} + + + {55494e58-e061-4c4c-a0a8-837008e72f85} + + + {09d9d1d6-2951-4e14-bc35-76a23cf9391a} + + + {1533e271-f61b-441b-8b74-59fb61df0552} + + + {cac1267b-8778-4257-aac6-caf481723b01} + + + {d57ea297-6dc2-4bc0-8c91-334863327863} + + + + + + + NotUsing + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + true + EnableFastChecks + MultiThreadedDebug + Level3 + $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\ + /D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" + stdcpp17 + + + true + Console + ..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\; + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + + + + NotUsing + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + true + EnableFastChecks + MultiThreadedDebug + Level3 + $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\ + /D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" + stdcpp17 + + + true + Console + ..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\; + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + + + + NotUsing + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + MultiThreaded + Level3 + ProgramDatabase + $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\ + /D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" + stdcpp17 + + + true + Console + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + true + ..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\$(Configuration)\; + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + + + + NotUsing + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(IntDir)$(TargetName).pch + stdafx.h + MultiThreaded + Level3 + ProgramDatabase + $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories);..\..\src\AspNetCoreModuleV2\RequestHandlerLib;..\..\src\AspNetCoreModuleV2\IISLib;..\..\src\AspNetCoreModuleV2\CommonLib;..\gtest\googletest\googletest\include;..\gtest\googletest\googlemock\include;...\..\src\AspNetCoreModuleV2\AspNetCore\Inc;..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\ + /D "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING" + stdcpp17 + + + true + Console + /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib %(AdditionalOptions) + true + true + ..\..\src\AspNetCoreModuleV2\InProcessRequestHandler\x64\$(Configuration)\; + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;inprocessapplication.obj;inprocesshandler.obj;ahadmin.lib;Rpcrt4.lib;inprocessapplicationbase.obj;stdafx.obj;version.lib;inprocessoptions.obj;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + + + \ No newline at end of file diff --git a/src/IISIntegration/test/CommonLibTests/ConfigUtilityTests.cpp b/src/IISIntegration/test/CommonLibTests/ConfigUtilityTests.cpp new file mode 100644 index 0000000000..9b5bf6e9e6 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/ConfigUtilityTests.cpp @@ -0,0 +1,123 @@ +// 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. + +#include "stdafx.h" +#include "gmock/gmock.h" +using ::testing::_; +using ::testing::NiceMock; + +namespace ConfigUtilityTests +{ + using ::testing::Test; + + class ConfigUtilityTest : public Test + { + protected: + void TestHandlerVersion(std::wstring key, std::wstring value, std::wstring expected, HRESULT(*func)(IAppHostElement*, STRU&)) + { + IAppHostElement* retElement = NULL; + + STRU handlerVersion; + + // NiceMock removes warnings about "uninteresting calls", + auto element = std::make_unique>(); + auto innerElement = std::make_unique>(); + auto collection = std::make_unique>(); + auto nameElement = std::make_unique>(); + auto mockProperty = std::make_unique>(); + + ON_CALL(*element, GetElementByName(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(innerElement.get()), testing::Return(S_OK))); + ON_CALL(*innerElement, get_Collection(_)) + .WillByDefault(testing::DoAll(testing::SetArgPointee<0>(collection.get()), testing::Return(S_OK))); + ON_CALL(*collection, get_Count(_)) + .WillByDefault(DoAll(testing::SetArgPointee<0>(1), testing::Return(S_OK))); + ON_CALL(*collection, get_Item(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(nameElement.get()), testing::Return(S_OK))); + ON_CALL(*nameElement, GetPropertyByName(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(mockProperty.get()), testing::Return(S_OK))); + EXPECT_CALL(*mockProperty, get_StringValue(_)) + .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(key.c_str())), testing::Return(S_OK))) + .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(value.c_str())), testing::Return(S_OK))); + + HRESULT hr = func(element.get(), handlerVersion); + + EXPECT_EQ(hr, S_OK); + EXPECT_STREQ(handlerVersion.QueryStr(), expected.c_str()); + } + }; + + TEST_F(ConfigUtilityTest, CheckHandlerVersionKeysAndValues) + { + auto func = ConfigUtility::FindHandlerVersion; + TestHandlerVersion(L"handlerVersion", L"value", L"value", func); + TestHandlerVersion(L"handlerversion", L"value", L"value", func); + TestHandlerVersion(L"HandlerversioN", L"value", L"value", func); + TestHandlerVersion(L"randomvalue", L"value", L"", func); + TestHandlerVersion(L"", L"value", L"", func); + TestHandlerVersion(L"", L"", L"", func); + } + + TEST_F(ConfigUtilityTest, CheckDebugLogFile) + { + auto func = ConfigUtility::FindDebugFile; + + TestHandlerVersion(L"debugFile", L"value", L"value", func); + TestHandlerVersion(L"debugFILE", L"value", L"value", func); + } + + TEST_F(ConfigUtilityTest, CheckDebugLevel) + { + auto func = ConfigUtility::FindDebugLevel; + + TestHandlerVersion(L"debugLevel", L"value", L"value", func); + TestHandlerVersion(L"debugLEVEL", L"value", L"value", func); + } + + TEST(ConfigUtilityTestSingle, MultipleElements) + { + IAppHostElement* retElement = NULL; + STRU handlerVersion; + + auto element = std::make_unique>(); + auto innerElement = std::make_unique>(); + auto collection = std::make_unique>(); + auto nameElement = std::make_unique>(); + auto mockProperty = std::make_unique>(); + + ON_CALL(*element, GetElementByName(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(innerElement.get()), testing::Return(S_OK))); + ON_CALL(*innerElement, get_Collection(_)) + .WillByDefault(testing::DoAll(testing::SetArgPointee<0>(collection.get()), testing::Return(S_OK))); + ON_CALL(*collection, get_Count(_)) + .WillByDefault(DoAll(testing::SetArgPointee<0>(2), testing::Return(S_OK))); + ON_CALL(*collection, get_Item(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(nameElement.get()), testing::Return(S_OK))); + ON_CALL(*nameElement, GetPropertyByName(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(mockProperty.get()), testing::Return(S_OK))); + EXPECT_CALL(*mockProperty, get_StringValue(_)) + .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"key")), testing::Return(S_OK))) + .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"value")), testing::Return(S_OK))) + .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"handlerVersion")), testing::Return(S_OK))) + .WillOnce(DoAll(testing::SetArgPointee<0>(SysAllocString(L"value2")), testing::Return(S_OK))); + + HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), handlerVersion); + + EXPECT_EQ(hr, S_OK); + EXPECT_STREQ(handlerVersion.QueryStr(), L"value2"); + } + + TEST(ConfigUtilityTestSingle, IgnoresFailedGetElement) + { + STRU handlerVersion; + + auto element = std::make_unique>(); + ON_CALL(*element, GetElementByName(_, _)) + .WillByDefault(DoAll(testing::SetArgPointee<1>(nullptr), testing::Return(HRESULT_FROM_WIN32( ERROR_INVALID_INDEX )))); + + HRESULT hr = ConfigUtility::FindHandlerVersion(element.get(), handlerVersion); + + EXPECT_EQ(hr, S_OK); + EXPECT_STREQ(handlerVersion.QueryStr(), L""); + } +} diff --git a/src/IISIntegration/test/CommonLibTests/FileOutputManagerTests.cpp b/src/IISIntegration/test/CommonLibTests/FileOutputManagerTests.cpp new file mode 100644 index 0000000000..66a9ff7f0b --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/FileOutputManagerTests.cpp @@ -0,0 +1,152 @@ +// 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. + +#include "stdafx.h" +#include "gtest/internal/gtest-port.h" +#include "FileOutputManager.h" + +class FileManagerWrapper +{ +public: + FileOutputManager* manager; + FileManagerWrapper(FileOutputManager* m) + : manager(m) + { + manager->Start(); + } + + ~FileManagerWrapper() + { + delete manager; + } +}; + +namespace FileOutManagerStartupTests +{ + using ::testing::Test; + class FileOutputManagerTest : public Test + { + protected: + void + Test(std::wstring fileNamePrefix, FILE* out) + { + PCWSTR expected = L"test"; + + auto tempDirectory = TempDirectory(); + FileOutputManager* pManager = new FileOutputManager(fileNamePrefix, tempDirectory.path()); + + { + FileManagerWrapper wrapper(pManager); + + wprintf(expected, out); + } + + for (auto & p : std::filesystem::directory_iterator(tempDirectory.path())) + { + std::wstring filename(p.path().filename()); + ASSERT_EQ(filename.substr(0, fileNamePrefix.size()), fileNamePrefix); + + std::wstring content = Helpers::ReadFileContent(std::wstring(p.path())); + } + } + }; + + TEST_F(FileOutputManagerTest, WriteToFileCheckContentsWritten) + { + Test(L"", stdout); + Test(L"log", stdout); + } + + TEST_F(FileOutputManagerTest, WriteToFileCheckContentsWrittenErr) + { + Test(L"", stderr); + Test(L"log", stderr); + } +} + +namespace FileOutManagerOutputTests +{ + TEST(FileOutManagerOutputTest, StdOut) + { + PCWSTR expected = L"test"; + + auto tempDirectory = TempDirectory(); + + FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path()); + { + FileManagerWrapper wrapper(pManager); + + fwprintf(stdout, expected); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_FALSE(output.empty()); + + ASSERT_STREQ(output.c_str(), expected); + } + } + + TEST(FileOutManagerOutputTest, StdErr) + { + PCWSTR expected = L"test"; + + auto tempDirectory = TempDirectory(); + + FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path().c_str()); + { + FileManagerWrapper wrapper(pManager); + + fwprintf(stderr, expected); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_FALSE(output.empty()); + + ASSERT_STREQ(output.c_str(), expected); + } + } + + TEST(FileOutManagerOutputTest, CapAt30KB) + { + PCWSTR expected = L"hello world"; + + auto tempDirectory = TempDirectory(); + + FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path()); + { + FileManagerWrapper wrapper(pManager); + + for (int i = 0; i < 3000; i++) + { + wprintf(expected); + } + pManager->Stop(); + auto output = pManager->GetStdOutContent(); + ASSERT_FALSE(output.empty()); + + ASSERT_EQ(output.size(), 30000); + } + } + + TEST(FileOutManagerOutputTest, StartStopRestoresCorrectly) + { + PCWSTR expected = L"test"; + + auto tempDirectory = TempDirectory(); + + for (int i = 0; i < 10; i++) + { + FileOutputManager* pManager = new FileOutputManager(L"", tempDirectory.path()); + { + FileManagerWrapper wrapper(pManager); + + wprintf(expected); + pManager->Stop(); + auto output = pManager->GetStdOutContent(); + ASSERT_FALSE(output.empty()); + + ASSERT_STREQ(output.c_str(), expected); + } + } + } +} diff --git a/src/IISIntegration/test/CommonLibTests/GlobalVersionTests.cpp b/src/IISIntegration/test/CommonLibTests/GlobalVersionTests.cpp new file mode 100644 index 0000000000..f38c9361d2 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/GlobalVersionTests.cpp @@ -0,0 +1,153 @@ +// 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. + +#include "stdafx.h" +#include "gtest/internal/gtest-port.h" + +namespace GlobalVersionTests +{ + using ::testing::Test; + namespace fs = std::filesystem; + + class GlobalVersionTest : public Test + { + protected: + void + RemoveFileNamePath(PCWSTR dllPath, PCWSTR expected) + { + std::wstring res = GlobalVersionUtility::RemoveFileNameFromFolderPath(dllPath); + EXPECT_STREQ(res.c_str(), expected); + } + }; + + TEST_F(GlobalVersionTest, RemovesPathCorrectly) + { + RemoveFileNamePath(L"test\\log.txt", L"test"); + RemoveFileNamePath(L"test\\log", L"test"); + RemoveFileNamePath(L"C:\\Program Files\\IIS\\aspnetcorev2.dll", L"C:\\Program Files\\IIS"); + RemoveFileNamePath(L"test\\log.txt", L"test"); + } + + TEST(GetRequestHandlerVersions, GetFolders) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / L"2.0.0")); + + auto res = GlobalVersionUtility::GetRequestHandlerVersions(tempPath.path().c_str()); + EXPECT_EQ(res.size(), 1); + EXPECT_EQ(res.at(0), fx_ver_t(2, 0, 0, std::wstring())); + } + + TEST(GetRequestHandlerVersions, GetFolderPreview) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / L"2.0.0-preview")); + + auto res = GlobalVersionUtility::GetRequestHandlerVersions(tempPath.path().c_str()); + EXPECT_EQ(res.size(), 1); + EXPECT_EQ(res.at(0), fx_ver_t(2, 0, 0, std::wstring(L"-preview"))); + } + + TEST(GetRequestHandlerVersions, GetFolderManyVersions) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / + L"2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / + L"1.9.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / + L"2.1.0")); + + auto res = GlobalVersionUtility::GetRequestHandlerVersions(tempPath.path().c_str()); + EXPECT_EQ(res.size(), 3); + EXPECT_TRUE(std::find(res.begin(), res.end(), fx_ver_t(1, 9, 0, std::wstring())) != std::end(res)); + EXPECT_TRUE(std::find(res.begin(), res.end(), fx_ver_t(2, 0, 0, std::wstring())) != std::end(res)); + EXPECT_TRUE(std::find(res.begin(), res.end(), fx_ver_t(2, 1, 0, std::wstring())) != std::end(res)); + } + + TEST(FindHighestGlobalVersion, HighestVersionWithSingleFolder) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + + auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str()); + + EXPECT_STREQ(res.c_str(), L"2.0.0"); + } + + TEST(FindHighestGlobalVersion, HighestVersionWithMultipleVersions) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0")); + + auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str()); + + EXPECT_STREQ(res.c_str(), L"2.1.0"); + } + + TEST(FindHighestGlobalVersion, HighestVersionWithMultipleVersionsPreview) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.2.0-preview")); + + auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str()); + + EXPECT_STREQ(res.c_str(), L"2.2.0-preview"); + } + + TEST(FindHighestGlobalVersion, HighestVersionWithMultipleVersionNoPreview) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0")); + + auto res = GlobalVersionUtility::FindHighestGlobalVersion(tempPath.path().c_str()); + + EXPECT_STREQ(res.c_str(), L"2.1.0"); + } + + TEST(GetGlobalRequestHandlerPath, FindHighestVersionNoHandlerName) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"", L"aspnetcorev2_outofprocess.dll"); + + EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.0.0\\aspnetcorev2_outofprocess.dll").c_str()); + } + + TEST(GetGlobalRequestHandlerPath, FindHighestVersionPreviewWins) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview")); + + auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"", L"aspnetcorev2_outofprocess.dll"); + + EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.1.0-preview\\aspnetcorev2_outofprocess.dll").c_str()); + } + + TEST(GetGlobalRequestHandlerPath, FindHighestVersionSpecificVersion) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview")); + + auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"2.0.0", L"aspnetcorev2_outofprocess.dll"); + + EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.0.0\\aspnetcorev2_outofprocess.dll").c_str()); + } + + TEST(GetGlobalRequestHandlerPath, FindHighestVersionSpecificPreview) + { + auto tempPath = TempDirectory(); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.0.0")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.1.0-preview")); + EXPECT_TRUE(fs::create_directories(tempPath.path() / "2.2.0")); + + + auto result = GlobalVersionUtility::GetGlobalRequestHandlerPath(tempPath.path().c_str(), L"2.1.0-preview", L"aspnetcorev2_outofprocess.dll"); + + EXPECT_STREQ(result.c_str(), (tempPath.path() / L"2.1.0-preview\\aspnetcorev2_outofprocess.dll").c_str()); + } +} diff --git a/src/IISIntegration/test/CommonLibTests/Helpers.cpp b/src/IISIntegration/test/CommonLibTests/Helpers.cpp new file mode 100644 index 0000000000..ccca6cad5b --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/Helpers.cpp @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +#include "stdafx.h" + +std::wstring +Helpers::ReadFileContent(std::wstring file) +{ + std::wcout << file << std::endl; + + std::fstream t(file); + std::stringstream buffer; + buffer << t.rdbuf(); + + int nChars = MultiByteToWideChar(CP_ACP, 0, buffer.str().c_str(), -1, NULL, 0); + + std::wstring retVal(nChars, '\0'); + + MultiByteToWideChar(CP_UTF8, 0, buffer.str().c_str(), -1, retVal.data(), nChars); + + return retVal; +} + +TempDirectory::TempDirectory() +{ + UUID uuid; + UuidCreate(&uuid); + RPC_CSTR szUuid = NULL; + if (UuidToStringA(&uuid, &szUuid) == RPC_S_OK) + { + m_path = std::filesystem::temp_directory_path() / reinterpret_cast(szUuid); + RpcStringFreeA(&szUuid); + return; + } + throw std::exception("Cannot create temp directory"); +} + +TempDirectory::~TempDirectory() +{ + std::filesystem::remove_all(m_path); +} diff --git a/src/IISIntegration/test/CommonLibTests/Helpers.h b/src/IISIntegration/test/CommonLibTests/Helpers.h new file mode 100644 index 0000000000..67256966bb --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/Helpers.h @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +#pragma once +class Helpers +{ +public: + static + std::wstring + ReadFileContent(std::wstring file); +}; + +class TempDirectory +{ +public: + + TempDirectory(); + + ~TempDirectory(); + + std::filesystem::path path() const + { + return m_path; + } + +private: + std::filesystem::path m_path; +}; diff --git a/src/IISIntegration/test/CommonLibTests/NativeTests.targets b/src/IISIntegration/test/CommonLibTests/NativeTests.targets new file mode 100644 index 0000000000..f3d2caf930 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/NativeTests.targets @@ -0,0 +1,8 @@ + + + $(VCIDEInstallDir)..\CommonExtensions\Microsoft\TestWindow\vstest.console.exe + + + + + \ No newline at end of file diff --git a/src/IISIntegration/test/CommonLibTests/PipeOutputManagerTests.cpp b/src/IISIntegration/test/CommonLibTests/PipeOutputManagerTests.cpp new file mode 100644 index 0000000000..385d6df9e0 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/PipeOutputManagerTests.cpp @@ -0,0 +1,162 @@ +// 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. + +#include "stdafx.h" +#include "gtest/internal/gtest-port.h" +#include "PipeOutputManager.h" + +class FileManagerWrapper +{ +public: + PipeOutputManager * manager; + FileManagerWrapper(PipeOutputManager* m) + : manager(m) + { + manager->Start(); + } + + ~FileManagerWrapper() + { + delete manager; + } +}; + +namespace PipeOutputManagerTests +{ + TEST(PipeManagerOutputTest, StdOut) + { + PCWSTR expected = L"test"; + + PipeOutputManager* pManager = new PipeOutputManager(true); + + pManager->Start(); + fwprintf(stdout, expected); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_STREQ(output.c_str(), expected); + delete pManager; + } + + TEST(PipeManagerOutputTest, StdOutMultiToWide) + { + PipeOutputManager* pManager = new PipeOutputManager(true); + + pManager->Start(); + fprintf(stdout, "test"); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_STREQ(output.c_str(), L"test"); + delete pManager; + } + + TEST(PipeManagerOutputTest, StdErr) + { + PCWSTR expected = L"test"; + + PipeOutputManager* pManager = new PipeOutputManager(); + + pManager->Start(); + fwprintf(stderr, expected); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_STREQ(output.c_str(), expected); + delete pManager; + } + + TEST(PipeManagerOutputTest, CheckMaxPipeSize) + { + std::wstring test; + for (int i = 0; i < 3000; i++) + { + test.append(L"hello world"); + } + + PipeOutputManager* pManager = new PipeOutputManager(); + + pManager->Start(); + wprintf(test.c_str()); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_EQ(output.size(), (DWORD)30000); + delete pManager; + } + + TEST(PipeManagerOutputTest, SetInvalidHandlesForErrAndOut) + { + auto m_fdPreviousStdOut = _dup(_fileno(stdout)); + auto m_fdPreviousStdErr = _dup(_fileno(stderr)); + + SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); + SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); + + PCWSTR expected = L"test"; + + PipeOutputManager* pManager = new PipeOutputManager(); + pManager->Start(); + + _dup2(m_fdPreviousStdOut, _fileno(stdout)); + _dup2(m_fdPreviousStdErr, _fileno(stderr)); + + // Test will fail if we didn't redirect stdout back to a file descriptor. + // This is because gtest relies on console output to know if a test succeeded or failed. + // If the output still points to a file/pipe, the test (and all other tests after it) will fail. + delete pManager; + } + + TEST(PipeManagerOutputTest, CreateDeleteMultipleTimesStdOutWorks) + { + for (int i = 0; i < 10; i++) + { + auto stdoutBefore = _fileno(stdout); + auto stderrBefore = _fileno(stderr); + PCWSTR expected = L"test"; + + PipeOutputManager* pManager = new PipeOutputManager(); + + pManager->Start(); + fwprintf(stdout, expected); + + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_STREQ(output.c_str(), expected); + ASSERT_EQ(stdoutBefore, _fileno(stdout)); + ASSERT_EQ(stderrBefore, _fileno(stderr)); + delete pManager; + } + // When this returns, we get an AV from gtest. + } + + TEST(PipeManagerOutputTest, CreateDeleteKeepOriginalStdErr) + { + for (int i = 0; i < 10; i++) + { + auto stdoutBefore = _fileno(stdout); + auto stderrBefore = _fileno(stderr); + auto stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); + auto stderrHandle = GetStdHandle(STD_ERROR_HANDLE); + PCWSTR expected = L"test"; + + PipeOutputManager* pManager = new PipeOutputManager(); + + pManager->Start(); + fwprintf(stderr, expected); + pManager->Stop(); + + auto output = pManager->GetStdOutContent(); + ASSERT_STREQ(output.c_str(), expected); + ASSERT_EQ(stdoutBefore, _fileno(stdout)); + + ASSERT_EQ(stderrBefore, _fileno(stderr)); + + delete pManager; + } + + wprintf(L"Hello!"); + } +} + diff --git a/src/IISIntegration/test/CommonLibTests/exception_handler_tests.cpp b/src/IISIntegration/test/CommonLibTests/exception_handler_tests.cpp new file mode 100644 index 0000000000..d0a9e97fdb --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/exception_handler_tests.cpp @@ -0,0 +1,49 @@ +// 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. + +#include "stdafx.h" + +TEST(CaughtExceptionHResult, ReturnsOutOfMemoryForBadAlloc) +{ + HRESULT hr; + try + { + throw std::bad_alloc(); + } + catch(...) + { + hr = CaughtExceptionHResult(); + } + + EXPECT_EQ(E_OUTOFMEMORY, hr); +} + +TEST(CaughtExceptionHResult, ReturnsValueForSystemError) +{ + HRESULT hr; + try + { + throw std::system_error(E_INVALIDARG, std::system_category()); + } + catch(...) + { + hr = CaughtExceptionHResult(); + } + + EXPECT_EQ(E_INVALIDARG, hr); +} + +TEST(CaughtExceptionHResult, ReturnsUhandledExceptionForOtherExceptions) +{ + HRESULT hr; + try + { + throw E_INVALIDARG; + } + catch(...) + { + hr = CaughtExceptionHResult(); + } + + EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION), hr); +} diff --git a/src/IISIntegration/test/CommonLibTests/fakeclasses.h b/src/IISIntegration/test/CommonLibTests/fakeclasses.h new file mode 100644 index 0000000000..a6f4a3e111 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/fakeclasses.h @@ -0,0 +1,190 @@ +// 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. + +#pragma once + +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "InProcessOptions.h" + +class MockProperty : public IAppHostProperty +{ +public: + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface, HRESULT(REFIID riid, void ** ppvObject)); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG()); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG()); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Name, HRESULT(BSTR* pbstrValue)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Value, HRESULT(VARIANT * pVariant)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, put_Value, HRESULT(VARIANT value)); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Clear, HRESULT()); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_StringValue, HRESULT(BSTR* pbstrValue)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Exception, HRESULT(IAppHostPropertyException ** ppException)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT * pValue)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, SetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT value)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Schema, HRESULT(IAppHostPropertySchema ** ppSchema)); +}; + +class MockCollection : public IAppHostElementCollection +{ +public: + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface, HRESULT(REFIID riid, void ** ppvObject)); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG()); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG()); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Clear, HRESULT()); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Schema, HRESULT(IAppHostCollectionSchema** pSchema)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Count, HRESULT(DWORD * dwordElem)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, get_Item, HRESULT(VARIANT cIndex, IAppHostElement ** ppElement)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, AddElement, HRESULT(IAppHostElement * pElement, INT cPosition)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, DeleteElement, HRESULT(VARIANT cIndex)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, CreateNewElement, HRESULT(BSTR bstrElementName, IAppHostElement** ppElement)); +}; + +class MockElement : public IAppHostElement +{ +public: + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface, HRESULT(REFIID riid, void ** ppvObject)); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG()); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG()); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Name, HRESULT(BSTR * pbstrName)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Collection, HRESULT(IAppHostElementCollection ** ppCollection)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Properties, HRESULT(IAppHostPropertyCollection ** ppProperties)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_ChildElements, HRESULT(IAppHostChildElementCollection ** ppElements)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT * pValue)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, SetMetadata, HRESULT(BSTR bstrMetadataType, VARIANT value)); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Schema, HRESULT(IAppHostElementSchema** pSchema)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetElementByName, HRESULT(BSTR bstrSubName, IAppHostElement ** ppElement)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, GetPropertyByName, HRESULT(BSTR bstrSubName, IAppHostProperty ** ppProperty)); + MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Clear, HRESULT()); + MOCK_METHOD1_WITH_CALLTYPE(__stdcall, get_Methods, HRESULT(IAppHostMethodCollection ** ppMethods)); +}; + +class MockHttpServer : public IHttpServer +{ + // Inherited via IHttpServer + virtual BOOL IsCommandLineLaunch(VOID) const override + { + return 0; + } + virtual PCWSTR GetAppPoolName(VOID) const override + { + return PCWSTR(); + } + virtual HRESULT AssociateWithThreadPool(HANDLE hHandle, LPOVERLAPPED_COMPLETION_ROUTINE completionRoutine) override + { + return E_NOTIMPL; + } + virtual VOID IncrementThreadCount(VOID) override + { + return VOID(); + } + virtual VOID DecrementThreadCount(VOID) override + { + return VOID(); + } + virtual VOID ReportUnhealthy(PCWSTR pszReasonString, HRESULT hrReason) override + { + return VOID(); + } + virtual VOID RecycleProcess(PCWSTR pszReason) override + { + return VOID(); + } + virtual IAppHostAdminManager * GetAdminManager(VOID) const override + { + return nullptr; + } + virtual HRESULT GetFileInfo(PCWSTR pszPhysicalPath, HANDLE hUserToken, PSID pSid, PCWSTR pszChangeNotificationPath, HANDLE hChangeNotificationToken, BOOL fCache, IHttpFileInfo ** ppFileInfo, IHttpTraceContext * pHttpTraceContext = NULL) override + { + return E_NOTIMPL; + } + virtual HRESULT FlushKernelCache(PCWSTR pszUrl) override + { + return E_NOTIMPL; + } + virtual HRESULT DoCacheOperation(CACHE_OPERATION cacheOperation, IHttpCacheKey * pCacheKey, IHttpCacheSpecificData ** ppCacheSpecificData, IHttpTraceContext * pHttpTraceContext = NULL) override + { + return E_NOTIMPL; + } + virtual GLOBAL_NOTIFICATION_STATUS NotifyCustomNotification(ICustomNotificationProvider * pCustomOutput) override + { + return GLOBAL_NOTIFICATION_STATUS(); + } + virtual IHttpPerfCounterInfo * GetPerfCounterInfo(VOID) override + { + return nullptr; + } + virtual VOID RecycleApplication(PCWSTR pszAppConfigPath) override + { + return VOID(); + } + virtual VOID NotifyConfigurationChange(PCWSTR pszPath) override + { + return VOID(); + } + virtual VOID NotifyFileChange(PCWSTR pszFileName) override + { + return VOID(); + } + virtual IDispensedHttpModuleContextContainer * DispenseContainer(VOID) override + { + return nullptr; + } + virtual HRESULT AddFragmentToCache(HTTP_DATA_CHUNK * pDataChunk, PCWSTR pszFragmentName) override + { + return E_NOTIMPL; + } + virtual HRESULT ReadFragmentFromCache(PCWSTR pszFragmentName, BYTE * pvBuffer, DWORD cbSize, DWORD * pcbCopied) override + { + return E_NOTIMPL; + } + virtual HRESULT RemoveFragmentFromCache(PCWSTR pszFragmentName) override + { + return E_NOTIMPL; + } + virtual HRESULT GetWorkerProcessSettings(IWpfSettings ** ppWorkerProcessSettings) override + { + return E_NOTIMPL; + } + virtual HRESULT GetProtocolManagerCustomInterface(PCWSTR pProtocolManagerDll, PCWSTR pProtocolManagerDllInitFunction, DWORD dwCustomInterfaceId, PVOID * ppCustomInterface) override + { + return E_NOTIMPL; + } + virtual BOOL SatisfiesPrecondition(PCWSTR pszPrecondition, BOOL * pfUnknownPrecondition = NULL) const override + { + return 0; + } + virtual IHttpTraceContext * GetTraceContext(VOID) const override + { + return nullptr; + } + virtual HRESULT RegisterFileChangeMonitor(PCWSTR pszPath, HANDLE hToken, IHttpFileMonitor ** ppFileMonitor) override + { + return E_NOTIMPL; + } + virtual HRESULT GetExtendedInterface(HTTP_SERVER_INTERFACE_VERSION version, PVOID * ppInterface) override + { + return E_NOTIMPL; + } +}; + + +class MockHttpApplication: public IHttpApplication +{ +public: + MOCK_CONST_METHOD0(GetApplicationPhysicalPath, PCWSTR ()); + MOCK_CONST_METHOD0(GetApplicationId, PCWSTR ()); + MOCK_CONST_METHOD0(GetAppConfigPath, PCWSTR ()); + MOCK_METHOD0(GetModuleContextContainer, IHttpModuleContextContainer* ()); +}; + +class MockInProcessOptions : public InProcessOptions +{ +public: + static + MockInProcessOptions* + CreateConfig() + { + return new MockInProcessOptions; + } +}; + diff --git a/src/IISIntegration/test/CommonLibTests/hostfxr_utility_tests.cpp b/src/IISIntegration/test/CommonLibTests/hostfxr_utility_tests.cpp new file mode 100644 index 0000000000..01c9541429 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/hostfxr_utility_tests.cpp @@ -0,0 +1,122 @@ +// 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. + +#include "stdafx.h" +#include +#include +#include +#include "hostfxr_utility.h" +#include "Environment.h" + +TEST(ParseHostFxrArguments, BasicHostFxrArguments) +{ + std::vector bstrArray; + + HOSTFXR_UTILITY::AppendArguments( + L"exec \"test.dll\"", // args + L"invalid", // physical path to application + bstrArray); // args array. + + EXPECT_EQ(2, bstrArray.size()); + ASSERT_STREQ(L"exec", bstrArray[0].c_str()); + ASSERT_STREQ(L"test.dll", bstrArray[1].c_str()); +} + +TEST(ParseHostFxrArguments, NoExecProvided) +{ + std::vector bstrArray; + + HOSTFXR_UTILITY::AppendArguments( + L"test.dll", // args + L"ignored", // physical path to application + bstrArray); // args array. + + EXPECT_EQ(1, bstrArray.size()); + ASSERT_STREQ(L"test.dll", bstrArray[0].c_str()); +} + +TEST(ParseHostFxrArguments, ConvertDllToAbsolutePath) +{ + std::vector bstrArray; + // we need to use existing dll so let's use ntdll that we know exists everywhere + auto system32 = Environment::ExpandEnvironmentVariables(L"%WINDIR%\\System32"); + HOSTFXR_UTILITY::AppendArguments( + L"exec \"ntdll.dll\"", // args + system32, // physical path to application + bstrArray, // args array. + true); // expandDllPaths + + EXPECT_EQ(2, bstrArray.size()); + ASSERT_STREQ(L"exec", bstrArray[0].c_str()); + ASSERT_STREQ((system32 + L"\\ntdll.dll").c_str(), bstrArray[1].c_str()); +} + +TEST(ParseHostFxrArguments, ProvideNoArgs_InvalidArgs) +{ + std::vector bstrArray; + std::filesystem::path struHostFxrDllLocation; + std::filesystem::path struExeLocation; + + EXPECT_THROW(HOSTFXR_UTILITY::GetHostFxrParameters( + L"dotnet", // processPath + L"some\\path", // application physical path, ignored. + L"", //arguments + struHostFxrDllLocation, + struExeLocation, + bstrArray), // args array. + InvalidOperationException); +} + +TEST(GetAbsolutePathToDotnetFromProgramFiles, BackupWorks) +{ + STRU struAbsolutePathToDotnet; + BOOL fDotnetInProgramFiles; + BOOL is64Bit; + BOOL fIsWow64 = FALSE; + SYSTEM_INFO systemInfo; + IsWow64Process(GetCurrentProcess(), &fIsWow64); + if (fIsWow64) + { + is64Bit = FALSE; + } + else + { + GetNativeSystemInfo(&systemInfo); + is64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; + } + + if (is64Bit) + { + fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files/dotnet/dotnet.exe"); + } + else + { + fDotnetInProgramFiles = std::filesystem::is_regular_file(L"C:/Program Files (x86)/dotnet/dotnet.exe"); + } + + auto dotnetPath = HOSTFXR_UTILITY::GetAbsolutePathToDotnetFromProgramFiles(); + if (fDotnetInProgramFiles) + { + EXPECT_TRUE(dotnetPath.has_value()); + } + else + { + EXPECT_FALSE(dotnetPath.has_value()); + } +} + +TEST(GetHostFxrArguments, InvalidParams) +{ + std::vector bstrArray; + std::filesystem::path struHostFxrDllLocation; + std::filesystem::path struExeLocation; + + EXPECT_THROW(HOSTFXR_UTILITY::GetHostFxrParameters( + L"bogus", // processPath + L"", // application physical path, ignored. + L"ignored", //arguments + struHostFxrDllLocation, + struExeLocation, + bstrArray), // args array. + InvalidOperationException); +} diff --git a/src/IISIntegration/test/CommonLibTests/inprocess_application_tests.cpp b/src/IISIntegration/test/CommonLibTests/inprocess_application_tests.cpp new file mode 100644 index 0000000000..d2ec985723 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/inprocess_application_tests.cpp @@ -0,0 +1,85 @@ +// 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. + +#include "stdafx.h" + +#include +#include "inprocessapplication.h" +#include "fakeclasses.h" + +using ::testing::_; +using ::testing::NiceMock; + +// Externals defined in inprocess +BOOL g_fProcessDetach; +HANDLE g_hEventLog; + +namespace InprocessTests +{ + TEST(InProcessTest, NoNullRefForExePath) + { + MockHttpServer server; + NiceMock application; + + ON_CALL(application, GetApplicationPhysicalPath()) + .WillByDefault(testing::Return(L"Some path")); + + ON_CALL(application, GetAppConfigPath()) + .WillByDefault(testing::Return(L"")); + + ON_CALL(application, GetApplicationId()) + .WillByDefault(testing::Return(L"")); + + auto requestHandlerConfig = std::unique_ptr(MockInProcessOptions::CreateConfig()); + + std::wstring exePath(L"hello"); + + std::array parameters{ + {"InProcessExeLocation", exePath.data()} + }; + + IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, application, std::move(requestHandlerConfig), parameters.data(), 1); + + ASSERT_STREQ(app->QueryExeLocation().c_str(), L"hello"); + } + + TEST(InProcessTest, GeneratesVirtualPath) + { + MockHttpServer server; + NiceMock application; + + ON_CALL(application, GetApplicationPhysicalPath()) + .WillByDefault(testing::Return(L"Some path")); + + ON_CALL(application, GetAppConfigPath()) + .WillByDefault(testing::Return(L"SECTION1/SECTION2/SECTION3/SECTION4/SECTION5")); + + ON_CALL(application, GetApplicationId()) + .WillByDefault(testing::Return(L"")); + + auto requestHandlerConfig = std::unique_ptr(MockInProcessOptions::CreateConfig()); + IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, application, std::move(requestHandlerConfig), nullptr, 0); + + ASSERT_STREQ(app->QueryApplicationVirtualPath().c_str(), L"/SECTION5"); + } + + TEST(InProcessTest, GeneratesVirtualPathForDefaultApp) + { + MockHttpServer server; + NiceMock application; + + ON_CALL(application, GetApplicationPhysicalPath()) + .WillByDefault(testing::Return(L"Some path")); + + ON_CALL(application, GetAppConfigPath()) + .WillByDefault(testing::Return(L"SECTION1/SECTION2/SECTION3/SECTION4")); + + ON_CALL(application, GetApplicationId()) + .WillByDefault(testing::Return(L"")); + + auto requestHandlerConfig = std::unique_ptr(MockInProcessOptions::CreateConfig()); + IN_PROCESS_APPLICATION *app = new IN_PROCESS_APPLICATION(server, application, std::move(requestHandlerConfig), nullptr, 0); + + ASSERT_STREQ(app->QueryApplicationVirtualPath().c_str(), L"/"); + } +} diff --git a/src/IISIntegration/test/CommonLibTests/main.cpp b/src/IISIntegration/test/CommonLibTests/main.cpp new file mode 100644 index 0000000000..1ad0a10ccd --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/main.cpp @@ -0,0 +1,12 @@ +// 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. + +#include "stdafx.h" + +DECLARE_DEBUG_PRINT_OBJECT2("tests", ASPNETCORE_DEBUG_FLAG_INFO | ASPNETCORE_DEBUG_FLAG_CONSOLE); + +int wmain(int argc, wchar_t* argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + RUN_ALL_TESTS(); +} diff --git a/src/IISIntegration/test/CommonLibTests/stdafx.h b/src/IISIntegration/test/CommonLibTests/stdafx.h new file mode 100644 index 0000000000..4b9ac7cd27 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/stdafx.h @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +#pragma once + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "stringa.h" +#include "stringu.h" +#include "dbgutil.h" +#include "ahutil.h" +#include "multisz.h" +#include "multisza.h" +#include "base64.h" +#include +#include +#include +#include +#include + +#include "stringu.h" +#include "stringa.h" +#include "multisz.h" +#include "dbgutil.h" +#include "hashfn.h" + +#include "requesthandler_config.h" +#include "hostfxr_utility.h" +#include "config_utility.h" +#include "environmentvariablehash.h" +#include "iapplication.h" +#include "debugutil.h" +#include "requesthandler.h" +#include "resources.h" +#include "aspnetcore_msg.h" +#include "Helpers.h" +#include "GlobalVersionUtility.h" + +#undef assert // Macro redefinition in IISLib. +#include "gtest/gtest.h" +#include "fakeclasses.h" + diff --git a/src/IISIntegration/test/CommonLibTests/utility_tests.cpp b/src/IISIntegration/test/CommonLibTests/utility_tests.cpp new file mode 100644 index 0000000000..ee69d79054 --- /dev/null +++ b/src/IISIntegration/test/CommonLibTests/utility_tests.cpp @@ -0,0 +1,75 @@ +// 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. + +#include "stdafx.h" +#include "Environment.h" +#include "StringHelpers.h" + +TEST(PassUnexpandedEnvString, ExpandsResult) +{ + HRESULT hr = S_OK; + PCWSTR unexpandedString = L"ANCM_TEST_ENV_VAR"; + PCWSTR unexpandedStringValue = L"foobar"; + STRU struExpandedString; + SetEnvironmentVariable(L"ANCM_TEST_ENV_VAR", unexpandedStringValue); + + hr = struExpandedString.CopyAndExpandEnvironmentStrings(L"%ANCM_TEST_ENV_VAR%"); + EXPECT_EQ(hr, S_OK); + EXPECT_STREQ(L"foobar", struExpandedString.QueryStr()); +} + +TEST(PassUnexpandedEnvString, LongStringExpandsResults) +{ + HRESULT hr = S_OK; + PCWSTR unexpandedString = L"ANCM_TEST_ENV_VAR_LONG"; + STRU struStringValue; + STACK_STRU(struExpandedString, MAX_PATH); + + struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize"); + struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize"); + struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize"); + struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize"); + struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize"); + struStringValue.Append(L"TestValueThatIsLongerThan256CharactersLongToTriggerResize"); + + SetEnvironmentVariable(unexpandedString, struStringValue.QueryStr()); + + hr = struExpandedString.CopyAndExpandEnvironmentStrings(L"%ANCM_TEST_ENV_VAR_LONG%"); + EXPECT_EQ(hr, S_OK); + EXPECT_EQ(struStringValue.QueryCCH(), struExpandedString.QueryCCH()); + // The values are exactly the same, however EXPECT_EQ is returning false. + //EXPECT_EQ(struStringValue.QueryStr(), struExpandedString.QueryStr()); + EXPECT_STREQ(struStringValue.QueryStr(), struExpandedString.QueryStr()); +} + + +TEST(GetEnvironmentVariableValue, ReturnsCorrectLenght) +{ + SetEnvironmentVariable(L"RANDOM_ENV_VAR_1", L"test"); + + auto result = Environment::GetEnvironmentVariableValue(L"RANDOM_ENV_VAR_1"); + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(result.value().length(), 4); + EXPECT_STREQ(result.value().c_str(), L"test"); +} + + +TEST(GetEnvironmentVariableValue, ReturnsNulloptWhenNotFound) +{ + auto result = Environment::GetEnvironmentVariableValue(L"RANDOM_ENV_VAR_2"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CheckStringHelpers, FormatWithoutContentDoesNotIncreaseSizeString) +{ + std::string testString = "test"; + auto result = format(testString); + EXPECT_EQ(testString.size(), result.size()); +} + +TEST(CheckStringHelpers, FormatWithoutContentDoesNotIncreaseSizeWstring) +{ + std::wstring testString = L"test"; + auto result = format(testString); + EXPECT_EQ(testString.size(), result.size()); +} diff --git a/src/IISIntegration/test/Directory.Build.props b/src/IISIntegration/test/Directory.Build.props new file mode 100644 index 0000000000..edfd666254 --- /dev/null +++ b/src/IISIntegration/test/Directory.Build.props @@ -0,0 +1,16 @@ + + + + + + netcoreapp2.2 + $(DeveloperBuildTestTfms) + $(StandardTestTfms) + $(StandardTestTfms);net461 + + + + + + diff --git a/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs b/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs new file mode 100644 index 0000000000..2e4a7b1c40 --- /dev/null +++ b/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/BackwardsCompatibilityTests.cs @@ -0,0 +1,39 @@ +// 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.Diagnostics; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; +using Xunit.Sdk; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class BackwardsCompatibilityTests : FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public BackwardsCompatibilityTests(IISTestSiteFixture fixture) : base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task CheckBackwardsCompatibilityIsUsed() + { + var response = await _fixture.Client.GetAsync("/HelloWorld"); + var handles = _fixture.DeploymentResult.HostProcess.Modules; + + foreach (ProcessModule handle in handles) + { + if (handle.ModuleName == "aspnetcorev2.dll") + { + Assert.Equal("12.2.18287.0", handle.FileVersionInfo.FileVersion); + return; + } + } + throw new XunitException($"Could not find aspnetcorev2.dll loaded in process {_fixture.DeploymentResult.HostProcess.ProcessName}"); + } + } +} diff --git a/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.cs new file mode 100644 index 0000000000..5c6f3739a4 --- /dev/null +++ b/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/DeployerSelector.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.Server.IntegrationTesting; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class DeployerSelector + { + public static ServerType ServerType => ServerType.IIS; + public static bool IsBackwardsCompatiblityTest => true; + public static bool IsForwardsCompatibilityTest => false; + } +} diff --git a/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj b/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj new file mode 100644 index 0000000000..c819a03ab1 --- /dev/null +++ b/src/IISIntegration/test/IIS.BackwardsCompatibility.FunctionalTests/IIS.BackwardsCompatibility.FunctionalTests.csproj @@ -0,0 +1,46 @@ + + + + netcoreapp2.2 + IISBackwardsCompatibility.FunctionalTests + True + + + + + + + + + + + False + + + False + + + False + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.cs new file mode 100644 index 0000000000..bd7aabbe0f --- /dev/null +++ b/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/DeployerSelector.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.Server.IntegrationTesting; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class DeployerSelector + { + public static ServerType ServerType => ServerType.IIS; + public static bool IsBackwardsCompatiblityTest => false; + public static bool IsForwardsCompatibilityTest => true; + } +} diff --git a/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs b/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs new file mode 100644 index 0000000000..5f4ebb5608 --- /dev/null +++ b/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/ForwardsCompatibilityTests.cs @@ -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.Diagnostics; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; +using Xunit.Sdk; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + public class ForwardsCompatibilityTests : FixtureLoggedTest + { + private readonly IISTestSiteFixture _fixture; + + public ForwardsCompatibilityTests(IISTestSiteFixture fixture) : base(fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task CheckForwardsCompatibilityIsUsed() + { + var response = await _fixture.Client.GetAsync("/HelloWorld"); + var handles = _fixture.DeploymentResult.HostProcess.Modules; + foreach (ProcessModule handle in handles) + { + if (handle.ModuleName == "aspnetcorev2_inprocess.dll") + { + Assert.Equal("12.2.18287.0", handle.FileVersionInfo.FileVersion); + return; + } + } + throw new XunitException($"Could not find aspnetcorev2_inprocess.dll loaded in process {_fixture.DeploymentResult.HostProcess.ProcessName}"); + } + } +} diff --git a/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj b/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj new file mode 100644 index 0000000000..929f6ec6b0 --- /dev/null +++ b/src/IISIntegration/test/IIS.ForwardsCompatibility.FunctionalTests/IIS.ForwardsCompatibility.FunctionalTests.csproj @@ -0,0 +1,45 @@ + + + + netcoreapp2.2 + IISForwardsCompatibility.FunctionalTests + True + + + + + + + + + + False + + + False + + + False + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/IIS.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/test/IIS.FunctionalTests/DeployerSelector.cs new file mode 100644 index 0000000000..f2e1be321e --- /dev/null +++ b/src/IISIntegration/test/IIS.FunctionalTests/DeployerSelector.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.Server.IntegrationTesting; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class DeployerSelector + { + public static ServerType ServerType => ServerType.IIS; + public static bool IsBackwardsCompatiblityTest => false; + public static bool IsForwardsCompatibilityTest => false; + } +} diff --git a/src/IISIntegration/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj b/src/IISIntegration/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj new file mode 100644 index 0000000000..62dec62e60 --- /dev/null +++ b/src/IISIntegration/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj @@ -0,0 +1,46 @@ + + + + netcoreapp2.2 + IIS.FunctionalTests + True + + + + + + + + + + + False + + + False + + + False + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs b/src/IISIntegration/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs new file mode 100644 index 0000000000..35f10b13ab --- /dev/null +++ b/src/IISIntegration/test/IIS.Shared.FunctionalTests/Inprocess/StdOutRedirectionTests.cs @@ -0,0 +1,150 @@ +// 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.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Newtonsoft.Json; +using Xunit; + +namespace IIS.FunctionalTests.Inprocess +{ + [Collection(PublishedSitesCollection.Name)] + public class StdOutRedirectionTests : LogFileTestBase + { + private readonly PublishedSitesFixture _fixture; + + public StdOutRedirectionTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + [SkipIfDebug] + public async Task FrameworkNotFoundExceptionLogged_Pipe() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + + var deploymentResult = await DeployAsync(deploymentParameters); + + Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.False(response.IsSuccessStatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, + "The specified framework 'Microsoft.NETCore.App', version '2.9.9' was not found."); + } + + [ConditionalFact] + [SkipIfDebug] + public async Task FrameworkNotFoundExceptionLogged_File() + { + var deploymentParameters = + _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + + deploymentParameters.EnableLogging(_logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + + Helpers.ModifyFrameworkVersionInRuntimeConfig(deploymentResult); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.False(response.IsSuccessStatusCode); + + StopServer(); + + var contents = Helpers.ReadAllTextFromFile(Helpers.GetExpectedLogName(deploymentResult, _logFolderPath), Logger); + var expectedString = "The specified framework 'Microsoft.NETCore.App', version '2.9.9' was not found."; + EventLogHelpers.VerifyEventLogEvent(deploymentResult, expectedString); + Assert.Contains(expectedString, contents); + } + + [ConditionalFact] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [SkipIfDebug] + public async Task EnableCoreHostTraceLogging_TwoLogFilesCreated() + { + var deploymentParameters = + _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.TransformArguments((a, _) => $"{a} CheckLargeStdOutWrites"); + + deploymentParameters.EnvironmentVariables["COREHOST_TRACE"] = "1"; + + deploymentParameters.EnableLogging(_logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.False(response.IsSuccessStatusCode); + + StopServer(); + + var fileInDirectory = Directory.GetFiles(_logFolderPath).Single(); + var contents = Helpers.ReadAllTextFromFile(fileInDirectory, Logger); + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr"); + Assert.Contains("Invoked hostfxr", contents); + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [SkipIfDebug] + [InlineData("CheckLargeStdErrWrites")] + [InlineData("CheckLargeStdOutWrites")] + [InlineData("CheckOversizedStdErrWrites")] + [InlineData("CheckOversizedStdOutWrites")] + public async Task EnableCoreHostTraceLogging_PipeCaptureNativeLogs(string path) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.EnvironmentVariables["COREHOST_TRACE"] = "1"; + deploymentParameters.TransformArguments((a, _) => $"{a} {path}"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + + Assert.False(response.IsSuccessStatusCode); + + StopServer(); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr"); + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.PoolEnvironmentVariables)] + [SkipIfDebug] + [InlineData("CheckLargeStdErrWrites")] + [InlineData("CheckLargeStdOutWrites")] + [InlineData("CheckOversizedStdErrWrites")] + [InlineData("CheckOversizedStdOutWrites")] + public async Task EnableCoreHostTraceLogging_FileCaptureNativeLogs(string path) + { + var deploymentParameters = + _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true); + deploymentParameters.EnvironmentVariables["COREHOST_TRACE"] = "1"; + deploymentParameters.TransformArguments((a, _) => $"{a} {path}"); + + deploymentParameters.EnableLogging(_logFolderPath); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/HelloWorld"); + Assert.False(response.IsSuccessStatusCode); + + StopServer(); + + var fileInDirectory = Directory.GetFiles(_logFolderPath).First(); + var contents = Helpers.ReadAllTextFromFile(fileInDirectory, Logger); + + EventLogHelpers.VerifyEventLogEvent(deploymentResult, "Invoked hostfxr"); + Assert.Contains("Invoked hostfxr", contents); + } + } +} diff --git a/src/IISIntegration/test/IIS.Shared.FunctionalTests/MofFileTests.cs b/src/IISIntegration/test/IIS.Shared.FunctionalTests/MofFileTests.cs new file mode 100644 index 0000000000..a054225ac5 --- /dev/null +++ b/src/IISIntegration/test/IIS.Shared.FunctionalTests/MofFileTests.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 System.Diagnostics; +using System.IO; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace IIS.FunctionalTests +{ + public class MofFileTests + { + [ConditionalFact] + [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] + [RequiresIIS(IISCapability.TracingModule)] + public void CheckMofFile() + { + var path = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"), "src", "aspnetcoremodulev2", "aspnetcore", "ancm.mof"); + var process = Process.Start("mofcomp.exe", path); + process.WaitForExit(); + Assert.Equal(0, process.ExitCode); + } + } +} diff --git a/src/IISIntegration/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs b/src/IISIntegration/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b26f48a815 --- /dev/null +++ b/src/IISIntegration/test/IIS.Shared.FunctionalTests/Properties/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// 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.Server.IISIntegration.FunctionalTests; +using Microsoft.Extensions.Logging.Testing; +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] +[assembly: RequiresIIS] +[assembly: ShortClassName] diff --git a/src/IISIntegration/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs b/src/IISIntegration/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs new file mode 100644 index 0000000000..cfbbf70486 --- /dev/null +++ b/src/IISIntegration/test/IIS.Shared.FunctionalTests/RequiresIISAttribute.cs @@ -0,0 +1,150 @@ +// 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.Linq; +using System.Runtime.InteropServices; +using System.Security.Principal; +using System.Xml.Linq; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Win32; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class RequiresIISAttribute : Attribute, ITestCondition + { + private static readonly (IISCapability Capability, string DllName)[] Modules = + { + (IISCapability.Websockets, "iiswsock.dll"), + (IISCapability.WindowsAuthentication, "authsspi.dll"), + (IISCapability.DynamicCompression, "compdyn.dll"), + (IISCapability.ApplicationInitialization, "warmup.dll"), + (IISCapability.TracingModule, "iisetw.dll"), + (IISCapability.FailedRequestTracingModule, "iisfreb.dll"), + (IISCapability.BasicAuthentication, "authbas.dll"), + }; + + private static readonly bool _isMetStatic; + private static readonly string _skipReasonStatic; + private static readonly bool _poolEnvironmentVariablesAvailable; + private static readonly IISCapability _modulesAvailable; + + static RequiresIISAttribute() + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_TEST_SKIP_IIS") == "true") + { + _skipReasonStatic = "Test skipped using ASPNETCORE_TEST_SKIP_IIS environment variable"; + return; + } + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + _skipReasonStatic = "IIS tests can only be run on Windows"; + return; + } + + var identity = WindowsIdentity.GetCurrent(); + var principal = new WindowsPrincipal(identity); + if (!principal.IsInRole(WindowsBuiltInRole.Administrator)) + { + _skipReasonStatic += "The current console is not running as admin."; + return; + } + + if (!File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "w3wp.exe"))) + { + _skipReasonStatic += "The machine does not have IIS installed."; + return; + } + + var ancmConfigPath = Path.Combine(Environment.SystemDirectory, "inetsrv", "config", "schema", "aspnetcore_schema_v2.xml"); + + if (!File.Exists(ancmConfigPath)) + { + _skipReasonStatic = "IIS Schema is not installed."; + return; + } + + XDocument ancmConfig; + + try + { + ancmConfig = XDocument.Load(ancmConfigPath); + } + catch + { + _skipReasonStatic = "Could not read ANCM schema configuration"; + return; + } + + _isMetStatic = ancmConfig + .Root + .Descendants("attribute") + .Any(n => "hostingModel".Equals(n.Attribute("name")?.Value, StringComparison.Ordinal)); + + _skipReasonStatic = _isMetStatic ? null : "IIS schema needs to be upgraded to support ANCM."; + + foreach (var module in Modules) + { + if (File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", module.DllName))) + { + _modulesAvailable |= module.Capability; + } + } + + var iisRegistryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\InetStp", writable: false); + if (iisRegistryKey == null) + { + _poolEnvironmentVariablesAvailable = false; + } + else + { + var majorVersion = (int)iisRegistryKey.GetValue("MajorVersion", -1); + var minorVersion = (int)iisRegistryKey.GetValue("MinorVersion", -1); + var version = new Version(majorVersion, minorVersion); + _poolEnvironmentVariablesAvailable = version >= new Version(10, 0); + } + } + + public RequiresIISAttribute() + : this(IISCapability.None) { } + + public RequiresIISAttribute(IISCapability capabilities) + { + IsMet = _isMetStatic; + SkipReason = _skipReasonStatic; + if (capabilities.HasFlag(IISCapability.PoolEnvironmentVariables)) + { + IsMet &= _poolEnvironmentVariablesAvailable; + if (!_poolEnvironmentVariablesAvailable) + { + SkipReason += "The machine does allow for setting environment variables on application pools."; + } + } + + if (capabilities.HasFlag(IISCapability.ShutdownToken)) + { + IsMet = false; + SkipReason += "https://github.com/aspnet/IISIntegration/issues/1074"; + } + + foreach (var module in Modules) + { + if (capabilities.HasFlag(module.Capability)) + { + var available = _modulesAvailable.HasFlag(module.Capability); + IsMet &= available; + if (!available) + { + SkipReason += $"The machine does have {module.Capability} available."; + } + } + } + } + + public bool IsMet { get; } + public string SkipReason { get; } + } +} diff --git a/src/IISIntegration/test/IIS.Shared.FunctionalTests/ServicesTests.cs b/src/IISIntegration/test/IIS.Shared.FunctionalTests/ServicesTests.cs new file mode 100644 index 0000000000..875b5b13be --- /dev/null +++ b/src/IISIntegration/test/IIS.Shared.FunctionalTests/ServicesTests.cs @@ -0,0 +1,96 @@ +// 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.ServiceProcess; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace IIS.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class ApplicationInitializationTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public ApplicationInitializationTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.ApplicationInitialization)] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task ApplicationPreloadStartsApp(HostingModel hostingModel) + { + // This test often hits a memory leak in warmup.dll module, it has been reported to IIS team + using (AppVerifier.Disable(DeployerSelector.ServerType, 0x900)) + { + var baseDeploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel, publish: true); + baseDeploymentParameters.TransformArguments( + (args, contentRoot) => $"{args} CreateFile \"{Path.Combine(contentRoot, "Started.txt")}\""); + EnablePreload(baseDeploymentParameters); + + var result = await DeployAsync(baseDeploymentParameters); + + await Helpers.Retry(async () => await File.ReadAllTextAsync(Path.Combine(result.ContentRoot, "Started.txt")), 10, 200); + StopServer(); + EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.Started(result)); + } + } + + [ConditionalTheory] + [RequiresIIS(IISCapability.ApplicationInitialization)] + [InlineData(HostingModel.InProcess)] + [InlineData(HostingModel.OutOfProcess)] + public async Task ApplicationInitializationPageIsRequested(HostingModel hostingModel) + { + // This test often hits a memory leak in warmup.dll module, it has been reported to IIS team + using (AppVerifier.Disable(DeployerSelector.ServerType, 0x900)) + { + var baseDeploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel, publish: true); + EnablePreload(baseDeploymentParameters); + + baseDeploymentParameters.ServerConfigActionList.Add( + (config, _) => { + config + .RequiredElement("system.webServer") + .GetOrAdd("applicationInitialization") + .GetOrAdd("add", "initializationPage", "/CreateFile"); + }); + + var result = await DeployAsync(baseDeploymentParameters); + + await Helpers.Retry(async () => await File.ReadAllTextAsync(Path.Combine(result.ContentRoot, "Started.txt")), 10, 200); + StopServer(); + EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.Started(result)); + } + } + + private static void EnablePreload(IISDeploymentParameters baseDeploymentParameters) + { + baseDeploymentParameters.EnsureSection("applicationInitialization", "system.webServer"); + baseDeploymentParameters.ServerConfigActionList.Add( + (config, _) => { + + config + .RequiredElement("system.applicationHost") + .RequiredElement("sites") + .RequiredElement("site") + .RequiredElement("application") + .SetAttributeValue("preloadEnabled", true); + }); + + baseDeploymentParameters.EnableModule("ApplicationInitializationModule", "%IIS_BIN%\\warmup.dll"); + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/AppHostConfig/HostableWebCore.config b/src/IISIntegration/test/IIS.Tests/AppHostConfig/HostableWebCore.config new file mode 100644 index 0000000000..5e994d2855 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/AppHostConfig/HostableWebCore.config @@ -0,0 +1,198 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+ + +
+
+
+
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/IIS.Tests/ClientDisconnectTests.cs b/src/IISIntegration/test/IIS.Tests/ClientDisconnectTests.cs new file mode 100644 index 0000000000..dbe562aa7c --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/ClientDisconnectTests.cs @@ -0,0 +1,302 @@ +// 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 System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [SkipIfHostableWebCoreNotAvailable] + [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + public class ClientDisconnectTests : StrictTestServerTests + { + [ConditionalFact] + public async Task WritesSucceedAfterClientDisconnect() + { + var requestStartedCompletionSource = CreateTaskCompletionSource(); + var clientDisconnectedCompletionSource = CreateTaskCompletionSource(); + var requestCompletedCompletionSource = CreateTaskCompletionSource(); + + var data = new byte[1024]; + using (var testServer = await TestServer.Create( + async ctx => + { + requestStartedCompletionSource.SetResult(true); + await clientDisconnectedCompletionSource.Task; + for (var i = 0; i < 1000; i++) + { + await ctx.Response.Body.WriteAsync(data); + } + + requestCompletedCompletionSource.SetResult(true); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await requestStartedCompletionSource.Task.DefaultTimeout(); + } + clientDisconnectedCompletionSource.SetResult(true); + + await requestCompletedCompletionSource.Task.DefaultTimeout(); + } + + AssertConnectionDisconnectLog(); + } + + [ConditionalFact] + public async Task WritesCancelledWhenUsingAbortedToken() + { + var requestStartedCompletionSource = CreateTaskCompletionSource(); + var requestCompletedCompletionSource = CreateTaskCompletionSource(); + + Exception exception = null; + + var data = new byte[1]; + using (var testServer = await TestServer.Create(async ctx => + { + requestStartedCompletionSource.SetResult(true); + try + { + while (true) + { + await ctx.Response.Body.WriteAsync(data, ctx.RequestAborted); + } + } + catch (Exception e) + { + exception = e; + } + + requestCompletedCompletionSource.SetResult(true); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + + await requestStartedCompletionSource.Task.DefaultTimeout(); + } + + await requestCompletedCompletionSource.Task.DefaultTimeout(); + + Assert.IsType(exception); + } + + AssertConnectionDisconnectLog(); + } + + [ConditionalFact] + public async Task ReadThrowsAfterClientDisconnect() + { + var requestStartedCompletionSource = CreateTaskCompletionSource(); + var requestCompletedCompletionSource = CreateTaskCompletionSource(); + + Exception exception = null; + + var data = new byte[1024]; + using (var testServer = await TestServer.Create(async ctx => + { + requestStartedCompletionSource.SetResult(true); + try + { + await ctx.Request.Body.ReadAsync(data); + } + catch (Exception e) + { + exception = e; + } + + requestCompletedCompletionSource.SetResult(true); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await requestStartedCompletionSource.Task.DefaultTimeout(); + } + + await requestCompletedCompletionSource.Task.DefaultTimeout(); + } + + Assert.IsType(exception); + Assert.Equal("The client has disconnected", exception.Message); + + AssertConnectionDisconnectLog(); + } + + [ConditionalFact] + public async Task WriterThrowsCancelledException() + { + var requestStartedCompletionSource = CreateTaskCompletionSource(); + var requestCompletedCompletionSource = CreateTaskCompletionSource(); + + Exception exception = null; + var cancellationTokenSource = new CancellationTokenSource(); + + var data = new byte[1]; + using (var testServer = await TestServer.Create(async ctx => + { + requestStartedCompletionSource.SetResult(true); + try + { + while (true) + { + await ctx.Response.Body.WriteAsync(data, cancellationTokenSource.Token); + } + } + catch (Exception e) + { + exception = e; + } + + requestCompletedCompletionSource.SetResult(true); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + + await requestStartedCompletionSource.Task.DefaultTimeout(); + cancellationTokenSource.Cancel(); + await requestCompletedCompletionSource.Task.DefaultTimeout(); + } + + Assert.IsType(exception); + } + } + + [ConditionalFact] + public async Task ReaderThrowsCancelledException() + { + var requestStartedCompletionSource = CreateTaskCompletionSource(); + var requestCompletedCompletionSource = CreateTaskCompletionSource(); + + Exception exception = null; + var cancellationTokenSource = new CancellationTokenSource(); + + var data = new byte[1024]; + using (var testServer = await TestServer.Create(async ctx => + { + requestStartedCompletionSource.SetResult(true); + try + { + await ctx.Request.Body.ReadAsync(data, cancellationTokenSource.Token); + } + catch (Exception e) + { + exception = e; + } + + requestCompletedCompletionSource.SetResult(true); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await requestStartedCompletionSource.Task.DefaultTimeout(); + cancellationTokenSource.Cancel(); + await requestCompletedCompletionSource.Task.DefaultTimeout(); + } + Assert.IsType(exception); + } + } + + [ConditionalFact] + public async Task ReaderThrowsResetExceptionOnInvalidBody() + { + var requestStartedCompletionSource = CreateTaskCompletionSource(); + var requestCompletedCompletionSource = CreateTaskCompletionSource(); + + Exception exception = null; + + var data = new byte[1024]; + using (var testServer = await TestServer.Create(async ctx => + { + requestStartedCompletionSource.SetResult(true); + try + { + await ctx.Request.Body.ReadAsync(data); + } + catch (Exception e) + { + exception = e; + } + + requestCompletedCompletionSource.SetResult(true); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await connection.Send( + "POST / HTTP/1.1", + "Transfer-Encoding: chunked", + "Host: localhost", + "Connection: close", + "", + ""); + + await requestStartedCompletionSource.Task; + await connection.Send( + "ZZZZZZZZZZZZZ"); + + await connection.Receive( + "HTTP/1.1 400 Bad Request", + "" + ); + + } + await requestCompletedCompletionSource.Task.DefaultTimeout(); + } + + Assert.IsType(exception); + Assert.Equal("The client has disconnected", exception.Message); + AssertConnectionDisconnectLog(); + } + + [ConditionalFact] + public async Task RequestAbortedIsTrippedWithoutIO() + { + var requestStarted = CreateTaskCompletionSource(); + var requestAborted = CreateTaskCompletionSource(); + + using (var testServer = await TestServer.Create( + async ctx => { + ctx.RequestAborted.Register(() => requestAborted.SetResult(true)); + requestStarted.SetResult(true); + await requestAborted.Task; + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await requestStarted.Task; + } + await requestAborted.Task; + } + + AssertConnectionDisconnectLog(); + } + + private void AssertConnectionDisconnectLog() + { + Assert.Single(TestSink.Writes, w => w.EventId.Name == "ConnectionDisconnect"); + } + + private static async Task SendContentLength1Post(TestConnection connection) + { + await connection.Send( + "POST / HTTP/1.1", + "Content-Length: 1", + "Host: localhost", + "Connection: close", + "", + ""); + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/ConnectionIdFeatureTests.cs b/src/IISIntegration/test/IIS.Tests/ConnectionIdFeatureTests.cs new file mode 100644 index 0000000000..37e69b3a32 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/ConnectionIdFeatureTests.cs @@ -0,0 +1,54 @@ +// 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.Tasks; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [SkipIfHostableWebCoreNotAvailable] + [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + public class HttpBodyControlFeatureTests : StrictTestServerTests + { + [ConditionalFact] + public async Task ThrowsOnSyncReadOrWrite() + { + Exception writeException = null; + Exception readException = null; + using (var testServer = await TestServer.Create( + ctx => { + var bodyControl = ctx.Features.Get(); + bodyControl.AllowSynchronousIO = false; + + try + { + ctx.Response.Body.Write(new byte[10]); + } + catch (Exception ex) + { + writeException = ex; + } + + try + { + ctx.Request.Body.Read(new byte[10]); + } + catch (Exception ex) + { + readException = ex; + } + + return Task.CompletedTask; + }, LoggerFactory)) + { + await testServer.HttpClient.GetStringAsync("/"); + } + + Assert.IsType(readException); + Assert.IsType(writeException); + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/HttpBodyControlFeatureTests.cs b/src/IISIntegration/test/IIS.Tests/HttpBodyControlFeatureTests.cs new file mode 100644 index 0000000000..3d91c445ca --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/HttpBodyControlFeatureTests.cs @@ -0,0 +1,31 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [SkipIfHostableWebCoreNotAvailable] + [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + public class ConnectionIdFeatureTests : StrictTestServerTests + { + [ConditionalFact] + public async Task ProvidesConnectionId() + { + string connectionId = null; + using (var testServer = await TestServer.Create(ctx => { + var connectionIdFeature = ctx.Features.Get(); + connectionId = connectionIdFeature.ConnectionId; + return Task.CompletedTask; + }, LoggerFactory)) + { + await testServer.HttpClient.GetStringAsync("/"); + } + + Assert.NotNull(connectionId); + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/IIS.Tests.csproj b/src/IISIntegration/test/IIS.Tests/IIS.Tests.csproj new file mode 100644 index 0000000000..3fdb2a5363 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/IIS.Tests.csproj @@ -0,0 +1,32 @@ + + + + netcoreapp2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/IIS.Tests/ResponseAbortTests.cs b/src/IISIntegration/test/IIS.Tests/ResponseAbortTests.cs new file mode 100644 index 0000000000..c7ec472586 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/ResponseAbortTests.cs @@ -0,0 +1,151 @@ +// 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.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [SkipIfHostableWebCoreNotAvailable] + [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + public class ResponseAbortTests : StrictTestServerTests + { + [ConditionalFact] + public async Task ClosesWithoutSendingAnything() + { + using (var testServer = await TestServer.Create( + ctx => { + ctx.Abort(); + return Task.CompletedTask; + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await connection.WaitForConnectionClose(); + } + } + } + + [ConditionalFact] + public async Task ClosesAfterDataSent() + { + var bodyReceived = CreateTaskCompletionSource(); + using (var testServer = await TestServer.Create( + async ctx => { + await ctx.Response.WriteAsync("Abort"); + await ctx.Response.Body.FlushAsync(); + await bodyReceived.Task.DefaultTimeout(); + ctx.Abort(); + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await connection.Receive( + "HTTP/1.1 200 OK", + ""); + await connection.ReceiveHeaders( + "Transfer-Encoding: chunked"); + + await connection.ReceiveChunk("Abort"); + bodyReceived.SetResult(true); + await connection.WaitForConnectionClose(); + } + } + } + + [ConditionalFact] + public async Task ReadsThrowAfterAbort() + { + Exception exception = null; + + using (var testServer = await TestServer.Create( + async ctx => { + ctx.Abort(); + try + { + var a = new byte[10]; + await ctx.Request.Body.ReadAsync(a); + } + catch (Exception e) + { + exception = e; + } + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await connection.WaitForConnectionClose(); + } + } + + Assert.IsType(exception); + } + + [ConditionalFact] + public async Task WritesNoopAfterAbort() + { + Exception exception = null; + + using (var testServer = await TestServer.Create( + async ctx => { + ctx.Abort(); + try + { + await ctx.Response.Body.WriteAsync(new byte[10]); + } + catch (Exception e) + { + exception = e; + } + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await connection.WaitForConnectionClose(); + } + } + + Assert.Null(exception); + } + + [ConditionalFact] + public async Task RequestAbortedIsTrippedAfterAbort() + { + bool tokenAborted = false; + using (var testServer = await TestServer.Create( + ctx => { + ctx.Abort(); + tokenAborted = ctx.RequestAborted.IsCancellationRequested; + return Task.CompletedTask; + }, LoggerFactory)) + { + using (var connection = testServer.CreateConnection()) + { + await SendContentLength1Post(connection); + await connection.WaitForConnectionClose(); + } + } + + Assert.True(tokenAborted); + } + + private static async Task SendContentLength1Post(TestConnection connection) + { + await connection.Send( + "POST / HTTP/1.1", + "Content-Length: 1", + "Host: localhost", + "", + ""); + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/StrictTestServerTests.cs b/src/IISIntegration/test/IIS.Tests/StrictTestServerTests.cs new file mode 100644 index 0000000000..c8f62beedb --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/StrictTestServerTests.cs @@ -0,0 +1,24 @@ +// 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.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class StrictTestServerTests: LoggedTest + { + public override void Dispose() + { + base.Dispose(); + Assert.DoesNotContain(TestSink.Writes, w => w.LogLevel > LogLevel.Information); + } + + protected static TaskCompletionSource CreateTaskCompletionSource() + { + return new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/TestServerTest.cs b/src/IISIntegration/test/IIS.Tests/TestServerTest.cs new file mode 100644 index 0000000000..40b538ea52 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/TestServerTest.cs @@ -0,0 +1,35 @@ +// 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.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Testing.xunit; +using Microsoft.Extensions.Logging.Testing; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [SkipIfHostableWebCoreNotAvailable] + [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + public class TestServerTest : StrictTestServerTests + { + [ConditionalFact] + public async Task SingleProcessTestServer_HelloWorld() + { + var helloWorld = "Hello World"; + var expectedPath = "/Path"; + + string path = null; + using (var testServer = await TestServer.Create(ctx => + { + path = ctx.Request.Path.ToString(); + return ctx.Response.WriteAsync(helloWorld); + }, LoggerFactory)) + { + var result = await testServer.HttpClient.GetAsync(expectedPath); + Assert.Equal(helloWorld, await result.Content.ReadAsStringAsync()); + Assert.Equal(expectedPath, path); + } + } + } +} diff --git a/src/IISIntegration/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs b/src/IISIntegration/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs new file mode 100644 index 0000000000..b63743f106 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/Utilities/SkipIfHostableWebCoreNotAvailibleAttribute.cs @@ -0,0 +1,17 @@ +// 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.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class SkipIfHostableWebCoreNotAvailableAttribute : Attribute, ITestCondition + { + public bool IsMet { get; } = File.Exists(TestServer.HostableWebCoreLocation); + + public string SkipReason { get; } = $"Hostable Web Core not available, {TestServer.HostableWebCoreLocation} not found."; + } +} diff --git a/src/IISIntegration/test/IIS.Tests/Utilities/TestServer.cs b/src/IISIntegration/test/IIS.Tests/Utilities/TestServer.cs new file mode 100644 index 0000000000..351b826316 --- /dev/null +++ b/src/IISIntegration/test/IIS.Tests/Utilities/TestServer.cs @@ -0,0 +1,211 @@ +// 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.Net.Http; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Loader; +using System.Threading; +using System.Threading.Tasks; +using System.Xml.Linq; +using System.Xml.XPath; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.Common; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public class TestServer: IDisposable, IStartup + { + private const string InProcessHandlerDll = "aspnetcorev2_inprocess.dll"; + private const string AspNetCoreModuleDll = "aspnetcorev2.dll"; + private const string HWebCoreDll = "hwebcore.dll"; + + internal static string HostableWebCoreLocation => Environment.ExpandEnvironmentVariables($@"%windir%\system32\inetsrv\{HWebCoreDll}"); + internal static string BasePath => Path.GetDirectoryName(new Uri(typeof(TestServer).Assembly.CodeBase).AbsolutePath); + + internal static string AspNetCoreModuleLocation => Path.Combine(BasePath, AspNetCoreModuleDll); + + private static readonly SemaphoreSlim WebCoreLock = new SemaphoreSlim(1, 1); + + private static readonly int PortRetryCount = 10; + + private readonly TaskCompletionSource _startedTaskCompletionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + private readonly Action _appBuilder; + private readonly ILoggerFactory _loggerFactory; + private readonly hostfxr_main_fn _hostfxrMainFn; + + private Uri BaseUri => new Uri("http://localhost:" + _currentPort); + public HttpClient HttpClient { get; private set; } + public TestConnection CreateConnection() => new TestConnection(_currentPort); + + private IWebHost _host; + + private string _appHostConfigPath; + private int _currentPort; + + private TestServer(Action appBuilder, ILoggerFactory loggerFactory) + { + _hostfxrMainFn = Main; + _appBuilder = appBuilder; + _loggerFactory = loggerFactory; + } + + public static async Task Create(Action appBuilder, ILoggerFactory loggerFactory) + { + await WebCoreLock.WaitAsync(); + var server = new TestServer(appBuilder, loggerFactory); + server.Start(); + (await server.HttpClient.GetAsync("/start")).EnsureSuccessStatusCode(); + await server._startedTaskCompletionSource.Task; + return server; + } + + public static Task Create(RequestDelegate app, ILoggerFactory loggerFactory) + { + return Create(builder => builder.Run(app), loggerFactory); + } + + private void Start() + { + LoadLibrary(HostableWebCoreLocation); + _appHostConfigPath = Path.GetTempFileName(); + + set_main_handler(_hostfxrMainFn); + + Retry(() => + { + _currentPort = TestPortHelper.GetNextPort(); + + InitializeConfig(_currentPort); + + var startResult = WebCoreActivate(_appHostConfigPath, null, "Instance"); + if (startResult != 0) + { + throw new InvalidOperationException($"Error while running WebCoreActivate: {startResult} on port {_currentPort}"); + } + }, PortRetryCount); + + HttpClient = new HttpClient(new LoggingHandler(new SocketsHttpHandler(), _loggerFactory.CreateLogger())) + { + BaseAddress = BaseUri + }; + } + + private void InitializeConfig(int port) + { + var webHostConfig = XDocument.Load(Path.GetFullPath("HostableWebCore.config")); + webHostConfig.XPathSelectElement("/configuration/system.webServer/globalModules/add[@name='AspNetCoreModuleV2']") + .SetAttributeValue("image", AspNetCoreModuleLocation); + + var siteElement = webHostConfig.Root + .RequiredElement("system.applicationHost") + .RequiredElement("sites") + .RequiredElement("site"); + + siteElement + .RequiredElement("bindings") + .RequiredElement("binding") + .SetAttributeValue("bindingInformation", $":{port}:localhost"); + + webHostConfig.Save(_appHostConfigPath); + } + + private int Main(IntPtr argc, IntPtr argv) + { + _host = new WebHostBuilder() + .UseIIS() + .ConfigureServices(services => { + services.AddSingleton(this); + services.AddSingleton(_loggerFactory); + }) + .UseSetting(WebHostDefaults.ApplicationKey, typeof(TestServer).GetTypeInfo().Assembly.FullName) + .Build(); + + var doneEvent = new ManualResetEventSlim(); + var lifetime = _host.Services.GetService(); + + lifetime.ApplicationStopping.Register(() => doneEvent.Set()); + _host.Start(); + _startedTaskCompletionSource.SetResult(null); + doneEvent.Wait(); + _host.Dispose(); + return 0; + } + + public void Dispose() + { + HttpClient.Dispose(); + + // WebCoreShutdown occasionally AVs + // This causes the dotnet test process to crash + // To avoid this, we have to wait to shutdown + // and pass in true to immediately shutdown the hostable web core + // Both of these seem to be required. + Thread.Sleep(100); + WebCoreShutdown(immediate: true); + WebCoreLock.Release(); + } + + public IServiceProvider ConfigureServices(IServiceCollection services) + { + return services.BuildServiceProvider(); + } + + public void Configure(IApplicationBuilder app) + { + app.Map("/start", builder => builder.Run(context => context.Response.WriteAsync("Done"))); + _appBuilder(app); + } + + private delegate int hostfxr_main_fn(IntPtr argc, IntPtr argv); + + [DllImport(HWebCoreDll)] + private static extern int WebCoreActivate( + [In, MarshalAs(UnmanagedType.LPWStr)] + string appHostConfigPath, + [In, MarshalAs(UnmanagedType.LPWStr)] + string rootWebConfigPath, + [In, MarshalAs(UnmanagedType.LPWStr)] + string instanceName); + + [DllImport(HWebCoreDll)] + private static extern int WebCoreShutdown(bool immediate); + + [DllImport(InProcessHandlerDll)] + private static extern int set_main_handler(hostfxr_main_fn main); + + [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] + private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); + + private void Retry(Action func, int attempts) + { + var exceptions = new List(); + + for (var attempt = 0; attempt < attempts; attempt++) + { + try + { + func(); + return; + } + catch (Exception e) + { + exceptions.Add(e); + } + } + + throw new AggregateException(exceptions); + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/DeployerSelector.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/DeployerSelector.cs new file mode 100644 index 0000000000..ba6a1ec6e2 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/DeployerSelector.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.Server.IntegrationTesting; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + public static class DeployerSelector + { + public static ServerType ServerType => ServerType.IISExpress; + public static bool IsBackwardsCompatiblityTest => false; + public static bool IsForwardsCompatibilityTest => false; + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/HttpsTests.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/HttpsTests.cs new file mode 100644 index 0000000000..ac58f73c0e --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/HttpsTests.cs @@ -0,0 +1,60 @@ +// 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.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.Common; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class HttpsTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public HttpsTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) + .WithAllApplicationTypes() + .WithAllAncmVersions() + .WithAllHostingModels(); + + [ConditionalTheory] + [MemberData(nameof(TestVariants))] + public async Task HttpsHelloWorld(TestVariant variant) + { + var port = TestPortHelper.GetNextSSLPort(); + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant); + deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/"; + deploymentParameters.AddHttpsToServerConfig(); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (a, b, c, d) => true + }; + var client = deploymentResult.CreateClient(handler); + var response = await client.GetAsync("HttpsHelloWorld"); + var responseText = await response.Content.ReadAsStringAsync(); + if (variant.HostingModel == HostingModel.OutOfProcess) + { + Assert.Equal("Scheme:https; Original:http", responseText); + } + else + { + Assert.Equal("Scheme:https; Original:", responseText); + } + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj b/src/IISIntegration/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj new file mode 100644 index 0000000000..988c2d5943 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj @@ -0,0 +1,38 @@ + + + + netcoreapp2.2 + True + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs new file mode 100644 index 0000000000..47fb3a6553 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/AuthenticationTests.cs @@ -0,0 +1,70 @@ +// 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.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class AuthenticationTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public AuthenticationTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + [RequiresIIS(IISCapability.WindowsAuthentication)] + public async Task Authentication_InProcess() + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(publish: true); + deploymentParameters.SetWindowsAuth(); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("/AuthenticationAnonymous"); + + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Anonymous?True", responseText); + + response = await deploymentResult.HttpClient.GetAsync("/AuthenticationRestricted"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString()); + Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString()); + + response = await deploymentResult.HttpClient.GetAsync("/AuthenticationRestrictedNTLM"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString()); + // Note we can't restrict a challenge to a specific auth type, the native auth modules always add themselves. + Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString()); + + response = await deploymentResult.HttpClient.GetAsync("/AuthenticationForbidden"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + + var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; + var httpClient = deploymentResult.CreateHttpClient(httpClientHandler); + + response = await httpClient.GetAsync("/AuthenticationAnonymous"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Anonymous?True", responseText); + + response = await httpClient.GetAsync("/AuthenticationRestricted"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotEmpty(responseText); + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs new file mode 100644 index 0000000000..caaf728c64 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/ShutdownTests.cs @@ -0,0 +1,90 @@ +// 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.Net.Http; +using System.Net.Sockets; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class ShutdownTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public ShutdownTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public async Task ServerShutsDownWhenMainExits() + { + var parameters = _fixture.GetBaseDeploymentParameters(publish: true); + var deploymentResult = await DeployAsync(parameters); + try + { + await deploymentResult.HttpClient.GetAsync("/Shutdown"); + } + catch (HttpRequestException ex) when (ex.InnerException is IOException) + { + // Server might close a connection before request completes + } + + deploymentResult.AssertWorkerProcessStop(); + } + + + [ConditionalFact] + public async Task ServerShutsDownWhenMainExitsStress() + { + var parameters = _fixture.GetBaseDeploymentParameters(publish: true); + var deploymentResult = await StartAsync(parameters); + + var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response => { + var statusCode = (int)response.StatusCode; + Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode); + }); + + try + { + await deploymentResult.HttpClient.GetAsync("/Shutdown"); + await load; + } + catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException) + { + // Server might close a connection before request completes + } + + deploymentResult.AssertWorkerProcessStop(); + } + + [ConditionalFact] + public async Task GracefulShutdown_DoesNotCrashProcess() + { + var parameters = _fixture.GetBaseDeploymentParameters(publish: true); + var result = await DeployAsync(parameters); + + var response = await result.HttpClient.GetAsync("/HelloWorld"); + StopServer(gracefulShutdown: true); + Assert.True(result.HostProcess.ExitCode == 0); + } + + [ConditionalFact] + public async Task ForcefulShutdown_DoesCrashProcess() + { + var parameters = _fixture.GetBaseDeploymentParameters(publish: true); + var result = await DeployAsync(parameters); + + var response = await result.HttpClient.GetAsync("/HelloWorld"); + StopServer(gracefulShutdown: false); + Assert.True(result.HostProcess.ExitCode == 1); + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs new file mode 100644 index 0000000000..826001c96d --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs @@ -0,0 +1,79 @@ +// 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.Linq; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(IISTestSiteCollection.Name)] + [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, SkipReason = "No supported on this platform")] + public class WebSocketsTests + { + private readonly string _webSocketUri; + + public WebSocketsTests(IISTestSiteFixture fixture) + { + _webSocketUri = fixture.DeploymentResult.ApplicationBaseUri.Replace("http:", "ws:"); + } + + [ConditionalFact] + public async Task OnStartedCalledForWebSocket() + { + var cws = new ClientWebSocket(); + await cws.ConnectAsync(new Uri(_webSocketUri + "WebSocketLifetimeEvents"), default); + + await ReceiveMessage(cws, "OnStarting"); + await ReceiveMessage(cws, "Upgraded"); + } + + [ConditionalFact] + public async Task WebReadBeforeUpgrade() + { + var cws = new ClientWebSocket(); + await cws.ConnectAsync(new Uri(_webSocketUri + "WebReadBeforeUpgrade"), default); + + await ReceiveMessage(cws, "Yay"); + } + + [ConditionalFact] + public async Task CanSendAndReceieveData() + { + var cws = new ClientWebSocket(); + await cws.ConnectAsync(new Uri(_webSocketUri + "WebSocketEcho"), default); + + for (int i = 0; i < 1000; i++) + { + var mesage = i.ToString(); + await SendMessage(cws, mesage); + await ReceiveMessage(cws, mesage); + } + } + + private async Task SendMessage(ClientWebSocket webSocket, string message) + { + await webSocket.SendAsync(new ArraySegment(Encoding.ASCII.GetBytes(message)), WebSocketMessageType.Text, true, default); + } + + private async Task ReceiveMessage(ClientWebSocket webSocket, string expectedMessage) + { + var received = new byte[expectedMessage.Length]; + + var offset = 0; + WebSocketReceiveResult result; + do + { + result = await webSocket.ReceiveAsync(new ArraySegment(received, offset, received.Length - offset), default); + offset += result.Count; + } while (!result.EndOfMessage); + + Assert.Equal(expectedMessage, Encoding.ASCII.GetString(received)); + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs new file mode 100644 index 0000000000..349f72d7bf --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/MultipleAppTests.cs @@ -0,0 +1,81 @@ +// 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.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class MultipleAppTests : IISFunctionalTestBase + { + private readonly PublishedSitesFixture _fixture; + + public MultipleAppTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalTheory] + [InlineData(AncmVersion.AspNetCoreModule)] + [InlineData(AncmVersion.AspNetCoreModuleV2)] + public Task Startup(AncmVersion ancmVersion) + { + // ANCM v1 currently does *not* retry if an app fails to start the first time due to a port collision. + // So, this test is expected to fail on v1 approximately 1 in 1,000 times (probably of at least one collision + // when 10 sites choose a random port from the range 1025-48000). Adding one retry should reduce the failure + // rate from 1 in 1,000 to 1 in 1,000,000. The previous product code (with "srand(GetTickCount())") should still + // fail the test reliably. + // https://github.com/aspnet/IISIntegration/issues/1350 + // + // ANCM v2 does retry on port collisions, so no retries should be required. + var attempts = (ancmVersion == AncmVersion.AspNetCoreModule) ? 2 : 1; + + return Helpers.Retry(async () => + { + const int numApps = 10; + + using (var deployers = new DisposableList()) + { + var deploymentResults = new List(); + + // Deploy all apps + for (var i = 0; i < numApps; i++) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel: IntegrationTesting.HostingModel.OutOfProcess); + deploymentParameters.AncmVersion = ancmVersion; + + var deployer = CreateDeployer(deploymentParameters); + deployers.Add(deployer); + deploymentResults.Add(await deployer.DeployAsync()); + } + + // Start all requests as quickly as possible, so apps are started as quickly as possible, + // to test possible race conditions when multiple apps start at the same time. + var requestTasks = new List>(); + foreach (var deploymentResult in deploymentResults) + { + requestTasks.Add(deploymentResult.HttpClient.GetAsync("/HelloWorld")); + } + + // Verify all apps started and return expected response + foreach (var requestTask in requestTasks) + { + var response = await requestTask; + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal("Hello World", responseText); + } + } + }, + attempts: attempts, msDelay: 0); + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs new file mode 100644 index 0000000000..3ff46bf304 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs @@ -0,0 +1,87 @@ +// 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.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class NtlmAuthenticationTests : IISFunctionalTestBase + { + // Test only runs on IISExpress today as our CI machines do not have + // Windows auth installed globally. + // TODO either enable windows auth on our CI or use containers to test this + // behavior + + private readonly PublishedSitesFixture _fixture; + + public NtlmAuthenticationTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + public static TestMatrix TestVariants + => TestMatrix.ForServers(DeployerSelector.ServerType) + .WithTfms(Tfm.NetCoreApp22, Tfm.Net461) + .WithAllAncmVersions(); + + [ConditionalTheory] + [RequiresIIS(IISCapability.WindowsAuthentication)] + [MemberData(nameof(TestVariants))] + public async Task NtlmAuthentication(TestVariant variant) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(variant); + deploymentParameters.ApplicationBaseUriHint = $"https://localhost:0/"; + + deploymentParameters.SetWindowsAuth(enabled: true); + + var result = await DeployAsync(deploymentParameters); + var response = await result.HttpClient.GetAsync("/HelloWorld"); + + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Hello World", responseText); + + var httpClient = result.HttpClient; + response = await httpClient.GetAsync("/Anonymous"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Anonymous?True", responseText); + + response = await httpClient.GetAsync("/Restricted"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString()); + Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString()); + + response = await httpClient.GetAsync("/RestrictedNTLM"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString()); + // Note we can't restrict a challenge to a specific auth type, the native auth modules always add themselves. + Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString()); + + response = await httpClient.GetAsync("/Forbidden"); + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + + var httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true }; + httpClient = result.CreateClient(httpClientHandler); + + response = await httpClient.GetAsync("/Anonymous"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("Anonymous?True", responseText); + + response = await httpClient.GetAsync("/Restricted"); + responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotEmpty(responseText); + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b26f48a815 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/Properties/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// 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.Server.IISIntegration.FunctionalTests; +using Microsoft.Extensions.Logging.Testing; +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] +[assembly: RequiresIIS] +[assembly: ShortClassName] diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs new file mode 100644 index 0000000000..2e0a68b9f7 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/RequiresIISAttribute.cs @@ -0,0 +1,24 @@ +// 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.Server.IntegrationTesting; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] + public sealed class RequiresIISAttribute : Attribute, ITestCondition + { + public bool IsMet => IISExpressAncmSchema.SupportsInProcessHosting; + + public string SkipReason => IISExpressAncmSchema.SkipReason; + + public RequiresIISAttribute() { } + + public RequiresIISAttribute(IISCapability capabilities) + { + // IISCapabilities aren't pertinent to IISExpress + } + } +} diff --git a/src/IISIntegration/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs b/src/IISIntegration/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs new file mode 100644 index 0000000000..62d07c5fd9 --- /dev/null +++ b/src/IISIntegration/test/IISExpress.FunctionalTests/UpgradeFeatureDetectionTests.cs @@ -0,0 +1,83 @@ +// 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.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing.xunit; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests +{ + [Collection(PublishedSitesCollection.Name)] + public class UpgradeFeatureDetectionTests : IISFunctionalTestBase + { + private readonly string _isWebsocketsSupported = Environment.OSVersion.Version >= new Version(6, 2) ? "Enabled" : "Disabled"; + private readonly PublishedSitesFixture _fixture; + + public UpgradeFeatureDetectionTests(PublishedSitesFixture fixture) + { + _fixture = fixture; + } + + [ConditionalFact] + public Task UpgradeFeatureDetectionDisabled_InProcess() + { + // fails due to not modifying the apphost.config file. + return UpgradeFeatureDetectionDeployer( + disableWebSocket: true, + Helpers.GetInProcessTestSitesPath(), + "Disabled", HostingModel.InProcess); + } + + [ConditionalFact] + public Task UpgradeFeatureDetectionEnabled_InProcess() + { + return UpgradeFeatureDetectionDeployer( + disableWebSocket: false, + Helpers.GetInProcessTestSitesPath(), + _isWebsocketsSupported, HostingModel.InProcess); + } + + [ConditionalFact] + public Task UpgradeFeatureDetectionDisabled_OutOfProcess() + { + return UpgradeFeatureDetectionDeployer( + disableWebSocket: true, + Helpers.GetOutOfProcessTestSitesPath(), + "Disabled", HostingModel.OutOfProcess); + } + + [ConditionalFact] + public Task UpgradeFeatureDetectionEnabled_OutOfProcess() + { + return UpgradeFeatureDetectionDeployer( + disableWebSocket: false, + Helpers.GetOutOfProcessTestSitesPath(), + _isWebsocketsSupported, HostingModel.OutOfProcess); + } + + private async Task UpgradeFeatureDetectionDeployer(bool disableWebSocket, string sitePath, string expected, HostingModel hostingModel) + { + var deploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel, publish: true); + + if (disableWebSocket) + { + // For IIS, we need to modify the apphost.config file + deploymentParameters.AddServerConfigAction( + element => element.Descendants("webSocket") + .Single() + .SetAttributeValue("enabled", "false")); + } + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("UpgradeFeatureDetection"); + var responseText = await response.Content.ReadAsStringAsync(); + Assert.Equal(expected, responseText); + } + } +} diff --git a/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs b/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs new file mode 100644 index 0000000000..772fbde2c3 --- /dev/null +++ b/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISExtensionTests.cs @@ -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.Linq; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration +{ + public class IISExtensionTests + { + [Fact] + public void CallingUseIISIntegrationMultipleTimesWorks() + { + + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .UseIISIntegration() + .Configure(app => { }); + var server = new TestServer(builder); + + var filters = server.Host.Services.GetServices() + .OfType(); + + Assert.Single(filters); + } + } +} diff --git a/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs b/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs new file mode 100644 index 0000000000..0898b7ae21 --- /dev/null +++ b/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/IISMiddlewareTests.cs @@ -0,0 +1,420 @@ +// 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; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http.Features.Authentication; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IISIntegration +{ + public class IISMiddlewareTests + { + [Fact] + public async Task MiddlewareSkippedIfTokenIsMissing() + { + var assertsExecuted = false; + + var builder = new WebHostBuilder() + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + app.Run(context => + { + var auth = context.Features.Get(); + Assert.Null(auth); + assertsExecuted = true; + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var req = new HttpRequestMessage(HttpMethod.Get, ""); + req.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + var response = await server.CreateClient().SendAsync(req); + Assert.True(assertsExecuted); + response.EnsureSuccessStatusCode(); + } + + [Fact] + public async Task MiddlewareRejectsRequestIfTokenHeaderIsMissing() + { + var assertsExecuted = false; + + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + app.Run(context => + { + var auth = context.Features.Get(); + Assert.Null(auth); + assertsExecuted = true; + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var req = new HttpRequestMessage(HttpMethod.Get, ""); + var response = await server.CreateClient().SendAsync(req); + Assert.False(assertsExecuted); + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + [Theory] + [InlineData("/", "/iisintegration", "shutdown")] + [InlineData("/", "/iisintegration", "Shutdown")] + [InlineData("/pathBase", "/pathBase/iisintegration", "shutdown")] + [InlineData("/pathBase", "/pathBase/iisintegration", "Shutdown")] + public async Task MiddlewareShutsdownGivenANCMShutdown(string pathBase, string requestPath, string shutdownEvent) + { + var requestExecuted = new ManualResetEvent(false); + var applicationStoppingFired = new ManualResetEvent(false); + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", pathBase) + .UseIISIntegration() + .Configure(app => + { + var appLifetime = app.ApplicationServices.GetRequiredService(); + appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set()); + + app.Run(context => + { + requestExecuted.Set(); + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var request = new HttpRequestMessage(HttpMethod.Post, requestPath); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", shutdownEvent); + var response = await server.CreateClient().SendAsync(request); + + Assert.True(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(5))); + Assert.False(requestExecuted.WaitOne(0)); + Assert.Equal(HttpStatusCode.Accepted, response.StatusCode); + } + + public static TheoryData InvalidShutdownMethods + { + get + { + return new TheoryData + { + HttpMethod.Put, + HttpMethod.Trace, + HttpMethod.Head, + HttpMethod.Get, + HttpMethod.Delete, + HttpMethod.Options + }; + } + } + + [Theory] + [MemberData(nameof(InvalidShutdownMethods))] + public async Task MiddlewareIgnoresShutdownGivenWrongMethod(HttpMethod method) + { + var requestExecuted = new ManualResetEvent(false); + var applicationStoppingFired = new ManualResetEvent(false); + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + var appLifetime = app.ApplicationServices.GetRequiredService(); + appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set()); + + app.Run(context => + { + requestExecuted.Set(); + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var request = new HttpRequestMessage(method, "/iisintegration"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", "shutdown"); + var response = await server.CreateClient().SendAsync(request); + + Assert.False(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(1))); + Assert.True(requestExecuted.WaitOne(0)); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Theory] + [InlineData("/")] + [InlineData("/path")] + [InlineData("/path/iisintegration")] + public async Task MiddlewareIgnoresShutdownGivenWrongPath(string path) + { + var requestExecuted = new ManualResetEvent(false); + var applicationStoppingFired = new ManualResetEvent(false); + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + var appLifetime = app.ApplicationServices.GetRequiredService(); + appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set()); + + app.Run(context => + { + requestExecuted.Set(); + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var request = new HttpRequestMessage(HttpMethod.Post, path); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", "shutdown"); + var response = await server.CreateClient().SendAsync(request); + + Assert.False(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(1))); + Assert.True(requestExecuted.WaitOne(0)); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Theory] + [InlineData("event")] + [InlineData("")] + [InlineData(null)] + public async Task MiddlewareIgnoresShutdownGivenWrongEvent(string shutdownEvent) + { + var requestExecuted = new ManualResetEvent(false); + var applicationStoppingFired = new ManualResetEvent(false); + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + var appLifetime = app.ApplicationServices.GetRequiredService(); + appLifetime.ApplicationStopping.Register(() => applicationStoppingFired.Set()); + + app.Run(context => + { + requestExecuted.Set(); + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var request = new HttpRequestMessage(HttpMethod.Post, "/iisintegration"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-EVENT", shutdownEvent); + var response = await server.CreateClient().SendAsync(request); + + Assert.False(applicationStoppingFired.WaitOne(TimeSpan.FromSeconds(1))); + Assert.True(requestExecuted.WaitOne(0)); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Fact] + public void UrlDelayRegisteredAndPreferHostingUrlsSet() + { + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + app.Run(context => Task.FromResult(0)); + }); + + Assert.Null(builder.GetSetting(WebHostDefaults.ServerUrlsKey)); + Assert.Null(builder.GetSetting(WebHostDefaults.PreferHostingUrlsKey)); + + // Adds a server and calls Build() + var server = new TestServer(builder); + + Assert.Equal("http://127.0.0.1:12345", builder.GetSetting(WebHostDefaults.ServerUrlsKey)); + Assert.Equal("true", builder.GetSetting(WebHostDefaults.PreferHostingUrlsKey)); + } + + [Fact] + public void PathBaseHiddenFromServer() + { + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/pathBase") + .UseIISIntegration() + .Configure(app => + { + app.Run(context => Task.FromResult(0)); + }); + new TestServer(builder); + + Assert.Equal("http://127.0.0.1:12345", builder.GetSetting(WebHostDefaults.ServerUrlsKey)); + } + + [Fact] + public async Task AddsUsePathBaseMiddlewareWhenPathBaseSpecified() + { + var requestPathBase = string.Empty; + var requestPath = string.Empty; + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/pathbase") + .UseIISIntegration() + .Configure(app => + { + app.Run(context => + { + requestPathBase = context.Request.PathBase.Value; + requestPath = context.Request.Path.Value; + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var request = new HttpRequestMessage(HttpMethod.Get, "/PathBase/Path"); + request.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + var response = await server.CreateClient().SendAsync(request); + + Assert.Equal("/PathBase", requestPathBase); + Assert.Equal("/Path", requestPath); + } + + [Fact] + public async Task AddsAuthenticationHandlerByDefault() + { + var assertsExecuted = false; + + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .Configure(app => + { + app.Run(async context => + { + var auth = context.RequestServices.GetRequiredService(); + var windows = await auth.GetSchemeAsync(IISDefaults.AuthenticationScheme); + Assert.NotNull(windows); + Assert.Null(windows.DisplayName); + Assert.Equal("Microsoft.AspNetCore.Server.IISIntegration.AuthenticationHandler", windows.HandlerType.FullName); + assertsExecuted = true; + }); + }); + var server = new TestServer(builder); + + var req = new HttpRequestMessage(HttpMethod.Get, ""); + req.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + await server.CreateClient().SendAsync(req); + + Assert.True(assertsExecuted); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task OnlyAddAuthenticationHandlerIfForwardWindowsAuthentication(bool forward) + { + var assertsExecuted = false; + + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .ConfigureServices(services => + { + services.Configure(options => + { + options.ForwardWindowsAuthentication = forward; + }); + }) + .Configure(app => + { + app.Run(async context => + { + var auth = context.RequestServices.GetService(); + Assert.NotNull(auth); + var windowsAuth = await auth.GetSchemeAsync(IISDefaults.AuthenticationScheme); + if (forward) + { + Assert.NotNull(windowsAuth); + Assert.Null(windowsAuth.DisplayName); + Assert.Equal("AuthenticationHandler", windowsAuth.HandlerType.Name); + } + else + { + Assert.Null(windowsAuth); + } + assertsExecuted = true; + }); + }); + var server = new TestServer(builder); + + var req = new HttpRequestMessage(HttpMethod.Get, ""); + req.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + await server.CreateClient().SendAsync(req); + + Assert.True(assertsExecuted); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task DoesNotBlowUpWithoutAuth(bool forward) + { + var assertsExecuted = false; + + var builder = new WebHostBuilder() + .UseSetting("TOKEN", "TestToken") + .UseSetting("PORT", "12345") + .UseSetting("APPL_PATH", "/") + .UseIISIntegration() + .ConfigureServices(services => + { + services.Configure(options => + { + options.ForwardWindowsAuthentication = forward; + }); + }) + .Configure(app => + { + app.Run(context => + { + assertsExecuted = true; + return Task.FromResult(0); + }); + }); + var server = new TestServer(builder); + + var req = new HttpRequestMessage(HttpMethod.Get, ""); + req.Headers.TryAddWithoutValidation("MS-ASPNETCORE-TOKEN", "TestToken"); + await server.CreateClient().SendAsync(req); + + Assert.True(assertsExecuted); + } + } +} diff --git a/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj b/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj new file mode 100644 index 0000000000..ea19c2a1fc --- /dev/null +++ b/src/IISIntegration/test/Microsoft.AspNetCore.Server.IISIntegration.Tests/Microsoft.AspNetCore.Server.IISIntegration.Tests.csproj @@ -0,0 +1,18 @@ + + + + $(StandardTestTfms) + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/TestTasks/InjectRequestHandler.cs b/src/IISIntegration/test/TestTasks/InjectRequestHandler.cs new file mode 100644 index 0000000000..4da8129d71 --- /dev/null +++ b/src/IISIntegration/test/TestTasks/InjectRequestHandler.cs @@ -0,0 +1,62 @@ +// 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.Diagnostics; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace TestTasks +{ + public class InjectRequestHandler + { + private static void Main(string[] args) + { + string rid = args[0]; + string libraryLocation = args[1]; + string depsFile = args[2]; + + JToken deps; + using (var file = File.OpenText(depsFile)) + using (JsonTextReader reader = new JsonTextReader(file)) + { + deps = JObject.ReadFrom(reader); + } + + var libraryName = "ANCMRH/1.0"; + var libraries = (JObject)deps["libraries"]; + var targetName = (JValue)deps["runtimeTarget"]["name"]; + + var target = (JObject)deps["targets"][targetName.Value]; + var targetLibrary = target.Properties().FirstOrDefault(p => p.Name == libraryName); + targetLibrary?.Remove(); + targetLibrary = + new JProperty(libraryName, new JObject( + new JProperty("runtimeTargets", new JObject( + new JProperty(libraryLocation.Replace('\\', '/'), new JObject( + new JProperty("rid", rid), + new JProperty("assetType", "native") + )))))); + target.AddFirst(targetLibrary); + + var library = libraries.Properties().FirstOrDefault(p => p.Name == libraryName); + library?.Remove(); + library = + new JProperty(libraryName, new JObject( + new JProperty("type", "package"), + new JProperty("serviceable", true), + new JProperty("sha512", ""), + new JProperty("path", libraryName), + new JProperty("hashPath", ""))); + libraries.AddFirst(library); + + using (var file = File.CreateText(depsFile)) + using (var writer = new JsonTextWriter(file) { Formatting = Formatting.Indented }) + { + deps.WriteTo(writer); + } + } + } +} diff --git a/src/IISIntegration/test/TestTasks/TestTasks.csproj b/src/IISIntegration/test/TestTasks/TestTasks.csproj new file mode 100644 index 0000000000..aa4c144936 --- /dev/null +++ b/src/IISIntegration/test/TestTasks/TestTasks.csproj @@ -0,0 +1,12 @@ + + + + Exe + $(StandardTestTfms) + + + + + + + diff --git a/src/IISIntegration/test/WebSites/Directory.Build.props b/src/IISIntegration/test/WebSites/Directory.Build.props new file mode 100644 index 0000000000..9b29d34f16 --- /dev/null +++ b/src/IISIntegration/test/WebSites/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj b/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj new file mode 100644 index 0000000000..4d0952108a --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/InProcessWebSite.csproj @@ -0,0 +1,32 @@ + + + + + + netcoreapp2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json b/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json new file mode 100644 index 0000000000..246b7a0b47 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessForwardsCompatWebSite/Properties/launchSettings.json @@ -0,0 +1,42 @@ +{ + "iisSettings": { + "windowsAuthentication": true, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5762/", + "sslPort": 0 + } + }, + "profiles": { + "ANCM IIS Express": { + "commandName": "Executable", + "executablePath": "$(IISExpressPath)", + "commandLineArgs": "$(IISExpressArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ANCM_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + }, + "ANCM IIS": { + "commandName": "Executable", + "executablePath": "$(IISPath)", + "commandLineArgs": "$(IISArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/DummyServer.cs b/src/IISIntegration/test/WebSites/InProcessWebSite/DummyServer.cs new file mode 100644 index 0000000000..d122f05776 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/DummyServer.cs @@ -0,0 +1,30 @@ +// 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 System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Http.Features; + +namespace TestSite +{ + public class DummyServer : IServer + { + public void Dispose() + { + } + + public Task StartAsync(IHttpApplication application, CancellationToken cancellationToken) + { + return Task.Delay(TimeSpan.MaxValue); + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.Delay(TimeSpan.MaxValue); + } + + public IFeatureCollection Features { get; } + } +} diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/InProcessWebSite.csproj b/src/IISIntegration/test/WebSites/InProcessWebSite/InProcessWebSite.csproj new file mode 100644 index 0000000000..d007d2daa1 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/InProcessWebSite.csproj @@ -0,0 +1,33 @@ + + + + + + netcoreapp2.2 + true + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/Program.cs b/src/IISIntegration/test/WebSites/InProcessWebSite/Program.cs new file mode 100644 index 0000000000..c40448ee91 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/Program.cs @@ -0,0 +1,114 @@ +// 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.Linq; +using System.Text; +using System.Threading; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace TestSite +{ + public static class Program + { + public static int Main(string[] args) + { + var mode = args.FirstOrDefault(); + switch (mode) + { + case "CreateFile": + File.WriteAllText(args[1], ""); + return StartServer(); + case "CheckLargeStdOutWrites": + Console.WriteLine(new string('a', 30000)); + break; + case "CheckLargeStdErrWrites": + Console.Error.WriteLine(new string('a', 30000)); + Console.Error.Flush(); + break; + case "ConsoleWrite": + Console.WriteLine($"Random number: {args[1]}"); + break; + case "ConsoleErrorWrite": + Console.Error.WriteLine($"Random number: {args[1]}"); + Console.Error.Flush(); + break; + case "CheckOversizedStdErrWrites": + Console.WriteLine(new string('a', 31000)); + break; + case "CheckOversizedStdOutWrites": + Console.Error.WriteLine(new string('a', 31000)); + Console.Error.Flush(); + break; + case "Hang": + Thread.Sleep(Timeout.Infinite); + break; + case "Throw": + throw new InvalidOperationException("Program.Main exception"); + case "EarlyReturn": + return 12; + case "HangOnStop": + { + var host = new WebHostBuilder() + .UseIIS() + .UseStartup() + .Build(); + host.Run(); + + Thread.Sleep(Timeout.Infinite); + } + break; + case "CheckConsoleFunctions": + // Call a bunch of console functions and make sure none return invalid handle. + Console.OutputEncoding = Encoding.UTF8; + Console.Title = "Test"; + Console.WriteLine($"Is Console redirection: {Console.IsOutputRedirected}"); + Console.BackgroundColor = ConsoleColor.Blue; + Console.WriteLine("彡⾔"); + break; + case "OverriddenServer": + { + var host = new WebHostBuilder() + .UseIIS() + .ConfigureServices(services => services.AddSingleton()) + .Configure(builder => builder.Run(async context => { await context.Response.WriteAsync("I shouldn't work"); })) + .Build(); + host.Run(); + } + break; + case "ConsoleErrorWriteStartServer": + Console.Error.WriteLine("TEST MESSAGE"); + return StartServer(); + case "ConsoleWriteStartServer": + Console.WriteLine("TEST MESSAGE"); + return StartServer(); + default: + return StartServer(); + + } + return 12; + } + + private static int StartServer() + { + var host = new WebHostBuilder() + .ConfigureLogging((_, factory) => + { + factory.AddConsole(); + factory.AddFilter("Console", level => level >= LogLevel.Information); + }) + .UseIIS() + .UseStartup() + .Build(); + + host.Run(); + return 0; + } + } +} diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/Properties/launchSettings.json b/src/IISIntegration/test/WebSites/InProcessWebSite/Properties/launchSettings.json new file mode 100644 index 0000000000..246b7a0b47 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/Properties/launchSettings.json @@ -0,0 +1,42 @@ +{ + "iisSettings": { + "windowsAuthentication": true, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5762/", + "sslPort": 0 + } + }, + "profiles": { + "ANCM IIS Express": { + "commandName": "Executable", + "executablePath": "$(IISExpressPath)", + "commandLineArgs": "$(IISExpressArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ANCM_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + }, + "ANCM IIS": { + "commandName": "Executable", + "executablePath": "$(IISPath)", + "commandLineArgs": "$(IISArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.WebSockets.cs b/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.WebSockets.cs new file mode 100644 index 0000000000..d658ebd03f --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.WebSockets.cs @@ -0,0 +1,147 @@ +// 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.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace TestSite +{ + public partial class Startup + { + + private void WebsocketRequest(IApplicationBuilder app) + { + app.Run(async context => + { + await context.Response.WriteAsync("test"); + }); + } + + private void WebReadBeforeUpgrade(IApplicationBuilder app) + { + app.Run(async context => { + + var singleByteArray = new byte[1]; + Assert.Equal(0, await context.Request.Body.ReadAsync(singleByteArray, 0, 1)); + + var ws = await Upgrade(context); + await SendMessages(ws, "Yay"); + }); + } + + private void WebSocketEcho(IApplicationBuilder app) + { + app.Run(async context => + { + var ws = await Upgrade(context); + + var appLifetime = app.ApplicationServices.GetRequiredService(); + + await Echo(ws, appLifetime.ApplicationStopping); + }); + } + + private void WebSocketLifetimeEvents(IApplicationBuilder app) + { + app.Run(async context => { + + var messages = new List(); + + context.Response.OnStarting(() => { + context.Response.Headers["custom-header"] = "value"; + messages.Add("OnStarting"); + return Task.CompletedTask; + }); + + var ws = await Upgrade(context); + messages.Add("Upgraded"); + + await SendMessages(ws, messages.ToArray()); + }); + } + + private static async Task SendMessages(WebSocket webSocket, params string[] messages) + { + foreach (var message in messages) + { + await webSocket.SendAsync(new ArraySegment(Encoding.ASCII.GetBytes(message)), WebSocketMessageType.Text, true, CancellationToken.None); + } + } + + private static async Task Upgrade(HttpContext context) + { + var upgradeFeature = context.Features.Get(); + + // Generate WebSocket response headers + string key = context.Request.Headers[Constants.Headers.SecWebSocketKey].ToString(); + var responseHeaders = HandshakeHelpers.GenerateResponseHeaders(key); + foreach (var headerPair in responseHeaders) + { + context.Response.Headers[headerPair.Key] = headerPair.Value; + } + + // Upgrade the connection + Stream opaqueTransport = await upgradeFeature.UpgradeAsync(); + + // Get the WebSocket object + var ws = WebSocketProtocol.CreateFromStream(opaqueTransport, isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2)); + return ws; + } + + private async Task Echo(WebSocket webSocket, CancellationToken token) + { + var buffer = new byte[1024 * 4]; + var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), token); + bool closeFromServer = false; + string closeFromServerCmd = "CloseFromServer"; + int closeFromServerLength = closeFromServerCmd.Length; + + while (!result.CloseStatus.HasValue && !token.IsCancellationRequested && !closeFromServer) + { + if (result.Count == closeFromServerLength && + Encoding.ASCII.GetString(buffer).Substring(0, result.Count) == closeFromServerCmd) + { + // The client sent "CloseFromServer" text message to request the server to close (a test scenario). + closeFromServer = true; + } + else + { + await webSocket.SendAsync(new ArraySegment(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, token); + result = await webSocket.ReceiveAsync(new ArraySegment(buffer), token); + } + } + + if (result.CloseStatus.HasValue) + { + // Client-initiated close handshake + await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); + } + else + { + // Server-initiated close handshake due to either of the two conditions: + // (1) The applicaton host is performing a graceful shutdown. + // (2) The client sent "CloseFromServer" text message to request the server to close (a test scenario). + await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, closeFromServerCmd, CancellationToken.None); + + // The server has sent the Close frame. + // Stop sending but keep receiving until we get the Close frame from the client. + while (!result.CloseStatus.HasValue) + { + result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); + } + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.cs b/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.cs new file mode 100644 index 0000000000..eb84272b76 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/Startup.cs @@ -0,0 +1,699 @@ +// 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.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IIS; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Primitives; +using Xunit; + +namespace TestSite +{ + public partial class Startup + { + public void Configure(IApplicationBuilder app) + { + TestStartup.Register(app, this); + } + + private async Task ServerVariable(HttpContext ctx) + { + var varName = ctx.Request.Query["q"]; + var newValue = ctx.Request.Query["v"]; + var feature = ctx.Features.Get(); + if (newValue.Count != 0) + { + feature[varName] = newValue; + } + await ctx.Response.WriteAsync($"{varName}: {feature[varName] ?? "(null)"}"); + } + + private async Task AuthenticationAnonymous(HttpContext ctx) + { + await ctx.Response.WriteAsync("Anonymous?" + !ctx.User.Identity.IsAuthenticated); + } + + private async Task AuthenticationRestricted(HttpContext ctx) + { + if (ctx.User.Identity.IsAuthenticated) + { + await ctx.Response.WriteAsync(ctx.User.Identity.AuthenticationType); + } + else + { + await ctx.ChallengeAsync(IISServerDefaults.AuthenticationScheme); + } + } + + private async Task AuthenticationForbidden(HttpContext ctx) + { + await ctx.ForbidAsync(IISServerDefaults.AuthenticationScheme); + } + + private async Task AuthenticationRestrictedNTLM(HttpContext ctx) + { + if (string.Equals("NTLM", ctx.User.Identity.AuthenticationType, StringComparison.Ordinal)) + { + await ctx.Response.WriteAsync("NTLM"); + } + else + { + await ctx.ChallengeAsync(IISServerDefaults.AuthenticationScheme); + } + } + + private async Task FeatureCollectionSetRequestFeatures(HttpContext ctx) + { + try + { + Assert.Equal("GET", ctx.Request.Method); + ctx.Request.Method = "test"; + Assert.Equal("test", ctx.Request.Method); + + Assert.Equal("http", ctx.Request.Scheme); + ctx.Request.Scheme = "test"; + Assert.Equal("test", ctx.Request.Scheme); + + Assert.Equal("/FeatureCollectionSetRequestFeatures", ctx.Request.PathBase); + ctx.Request.PathBase = "/base"; + Assert.Equal("/base", ctx.Request.PathBase); + + Assert.Equal("/path", ctx.Request.Path); + ctx.Request.Path = "/path"; + Assert.Equal("/path", ctx.Request.Path); + + Assert.Equal("?query", ctx.Request.QueryString.Value); + ctx.Request.QueryString = QueryString.Empty; + Assert.Equal("", ctx.Request.QueryString.Value); + + Assert.Equal("HTTP/1.1", ctx.Request.Protocol); + ctx.Request.Protocol = "HTTP/1.0"; + Assert.Equal("HTTP/1.0", ctx.Request.Protocol); + + Assert.NotNull(ctx.Request.Headers); + var headers = new HeaderDictionary(); + ctx.Features.Get().Headers = headers; + Assert.Same(headers, ctx.Features.Get().Headers); + + Assert.NotNull(ctx.Request.Body); + var body = new MemoryStream(); + ctx.Request.Body = body; + Assert.Same(body, ctx.Request.Body); + + //Assert.NotNull(ctx.Features.Get().TraceIdentifier); + //Assert.NotEqual(CancellationToken.None, ctx.RequestAborted); + //var token = new CancellationTokenSource().Token; + //ctx.RequestAborted = token; + //Assert.Equal(token, ctx.RequestAborted); + + await ctx.Response.WriteAsync("Success"); + return; + } + catch (Exception exception) + { + ctx.Response.StatusCode = 500; + await ctx.Response.WriteAsync(exception.ToString()); + } + await ctx.Response.WriteAsync("_Failure"); + } + + private async Task FeatureCollectionSetResponseFeatures(HttpContext ctx) + { + try + { + Assert.Equal(200, ctx.Response.StatusCode); + ctx.Response.StatusCode = 404; + Assert.Equal(404, ctx.Response.StatusCode); + ctx.Response.StatusCode = 200; + + Assert.Null(ctx.Features.Get().ReasonPhrase); + ctx.Features.Get().ReasonPhrase = "Set Response"; + Assert.Equal("Set Response", ctx.Features.Get().ReasonPhrase); + + Assert.NotNull(ctx.Response.Headers); + var headers = new HeaderDictionary(); + ctx.Features.Get().Headers = headers; + Assert.Same(headers, ctx.Features.Get().Headers); + + var originalBody = ctx.Response.Body; + Assert.NotNull(originalBody); + var body = new MemoryStream(); + ctx.Response.Body = body; + Assert.Same(body, ctx.Response.Body); + ctx.Response.Body = originalBody; + + await ctx.Response.WriteAsync("Success"); + return; + } + catch (Exception exception) + { + ctx.Response.StatusCode = 500; + await ctx.Response.WriteAsync(exception.ToString()); + } + await ctx.Response.WriteAsync("_Failure"); + } + + private async Task FeatureCollectionSetConnectionFeatures(HttpContext ctx) + { + try + { + Assert.True(IPAddress.IsLoopback(ctx.Connection.LocalIpAddress)); + ctx.Connection.LocalIpAddress = IPAddress.IPv6Any; + Assert.Equal(IPAddress.IPv6Any, ctx.Connection.LocalIpAddress); + + Assert.True(IPAddress.IsLoopback(ctx.Connection.RemoteIpAddress)); + ctx.Connection.RemoteIpAddress = IPAddress.IPv6Any; + Assert.Equal(IPAddress.IPv6Any, ctx.Connection.RemoteIpAddress); + await ctx.Response.WriteAsync("Success"); + return; + } + catch (Exception exception) + { + ctx.Response.StatusCode = 500; + await ctx.Response.WriteAsync(exception.ToString()); + } + await ctx.Response.WriteAsync("_Failure"); + } + + private void Throw(HttpContext ctx) + { + throw new Exception(); + } + + private async Task SetCustomErorCode(HttpContext ctx) + { + var feature = ctx.Features.Get(); + feature.ReasonPhrase = ctx.Request.Query["reason"]; + feature.StatusCode = int.Parse(ctx.Request.Query["code"]); + if (ctx.Request.Query["writeBody"] == "True") + { + await ctx.Response.WriteAsync(ctx.Request.Query["body"]); + } + } + + private async Task HelloWorld(HttpContext ctx) + { + if (ctx.Request.Path.Value.StartsWith("/Path")) + { + await ctx.Response.WriteAsync(ctx.Request.Path.Value); + return; + } + if (ctx.Request.Path.Value.StartsWith("/Query")) + { + await ctx.Response.WriteAsync(ctx.Request.QueryString.Value); + return; + } + + await ctx.Response.WriteAsync("Hello World"); + } + + private async Task LargeResponseBody(HttpContext ctx) + { + if (int.TryParse(ctx.Request.Query["length"], out var length)) + { + await ctx.Response.WriteAsync(new string('a', length)); + } + } + + private async Task ResponseHeaders(HttpContext ctx) + { + ctx.Response.Headers["UnknownHeader"] = "test123=foo"; + ctx.Response.ContentType = "text/plain"; + ctx.Response.Headers["MultiHeader"] = new StringValues(new string[] { "1", "2" }); + await ctx.Response.WriteAsync("Request Complete"); + } + + private async Task ResponseInvalidOrdering(HttpContext ctx) + { + if (ctx.Request.Path.Equals("/SetStatusCodeAfterWrite")) + { + await ctx.Response.WriteAsync("Started_"); + try + { + ctx.Response.StatusCode = 200; + } + catch (InvalidOperationException) + { + await ctx.Response.WriteAsync("SetStatusCodeAfterWriteThrew_"); + } + await ctx.Response.WriteAsync("Finished"); + return; + } + else if (ctx.Request.Path.Equals("/SetHeaderAfterWrite")) + { + await ctx.Response.WriteAsync("Started_"); + try + { + ctx.Response.Headers["This will fail"] = "some value"; + } + catch (InvalidOperationException) + { + await ctx.Response.WriteAsync("SetHeaderAfterWriteThrew_"); + } + await ctx.Response.WriteAsync("Finished"); + return; + } + } + + private async Task CheckEnvironmentVariable(HttpContext ctx) + { + var variable = Environment.GetEnvironmentVariable("ASPNETCORE_INPROCESS_TESTING_VALUE"); + await ctx.Response.WriteAsync(variable); + } + + private async Task CheckEnvironmentLongValueVariable(HttpContext ctx) + { + var variable = Environment.GetEnvironmentVariable("ASPNETCORE_INPROCESS_TESTING_LONG_VALUE"); + await ctx.Response.WriteAsync(variable); + } + + private async Task CheckAppendedEnvironmentVariable(HttpContext ctx) + { + var variable = Environment.GetEnvironmentVariable("ProgramFiles"); + await ctx.Response.WriteAsync(variable); + } + + private async Task CheckRemoveAuthEnvironmentVariable(HttpContext ctx) + { + var variable = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_HTTPAUTH"); + await ctx.Response.WriteAsync(variable); + } + private async Task ReadAndWriteSynchronously(HttpContext ctx) + { + var t2 = Task.Run(() => WriteManyTimesToResponseBody(ctx)); + var t1 = Task.Run(() => ReadRequestBody(ctx)); + await Task.WhenAll(t1, t2); + } + + private async Task ReadRequestBody(HttpContext ctx) + { + var readBuffer = new byte[1]; + var result = await ctx.Request.Body.ReadAsync(readBuffer, 0, 1); + while (result != 0) + { + result = await ctx.Request.Body.ReadAsync(readBuffer, 0, 1); + } + } + + private async Task WriteManyTimesToResponseBody(HttpContext ctx) + { + for (var i = 0; i < 10000; i++) + { + await ctx.Response.WriteAsync("hello world"); + } + } + + private async Task ReadAndWriteEcho(HttpContext ctx) + { + var readBuffer = new byte[4096]; + var result = await ctx.Request.Body.ReadAsync(readBuffer, 0, readBuffer.Length); + while (result != 0) + { + await ctx.Response.WriteAsync(Encoding.UTF8.GetString(readBuffer, 0, result)); + result = await ctx.Request.Body.ReadAsync(readBuffer, 0, readBuffer.Length); + } + } + private async Task ReadAndFlushEcho(HttpContext ctx) + { + var readBuffer = new byte[4096]; + var result = await ctx.Request.Body.ReadAsync(readBuffer, 0, readBuffer.Length); + while (result != 0) + { + await ctx.Response.WriteAsync(Encoding.UTF8.GetString(readBuffer, 0, result)); + await ctx.Response.Body.FlushAsync(); + result = await ctx.Request.Body.ReadAsync(readBuffer, 0, readBuffer.Length); + } + } + + private async Task ReadAndWriteEchoLines(HttpContext ctx) + { + if (ctx.Request.Headers.TryGetValue("Response-Content-Type", out var contentType)) + { + ctx.Response.ContentType = contentType; + } + + //Send headers + await ctx.Response.Body.FlushAsync(); + + var reader = new StreamReader(ctx.Request.Body); + while (!reader.EndOfStream) + { + var line = await reader.ReadLineAsync(); + if (line == "") + { + return; + } + await ctx.Response.WriteAsync(line + Environment.NewLine); + await ctx.Response.Body.FlushAsync(); + } + } + + private async Task ReadAndWriteEchoLinesNoBuffering(HttpContext ctx) + { + var feature = ctx.Features.Get(); + feature.DisableResponseBuffering(); + + if (ctx.Request.Headers.TryGetValue("Response-Content-Type", out var contentType)) + { + ctx.Response.ContentType = contentType; + } + + //Send headers + await ctx.Response.Body.FlushAsync(); + + var reader = new StreamReader(ctx.Request.Body); + while (!reader.EndOfStream) + { + var line = await reader.ReadLineAsync(); + if (line == "") + { + return; + } + await ctx.Response.WriteAsync(line + Environment.NewLine); + } + } + + private async Task ReadPartialBody(HttpContext ctx) + { + var data = new byte[5]; + var count = 0; + do + { + count += await ctx.Request.Body.ReadAsync(data, count, data.Length - count); + } while (count != data.Length); + await ctx.Response.Body.WriteAsync(data, 0, data.Length); + } + + private async Task SetHeaderFromBody(HttpContext ctx) + { + using (var reader = new StreamReader(ctx.Request.Body)) + { + var value = await reader.ReadToEndAsync(); + ctx.Response.Headers["BodyAsString"] = value; + await ctx.Response.WriteAsync(value); + } + } + + private async Task ReadAndWriteEchoTwice(HttpContext ctx) + { + var readBuffer = new byte[4096]; + var result = await ctx.Request.Body.ReadAsync(readBuffer, 0, readBuffer.Length); + while (result != 0) + { + await ctx.Response.WriteAsync(Encoding.UTF8.GetString(readBuffer, 0, result)); + await ctx.Response.Body.FlushAsync(); + await ctx.Response.WriteAsync(Encoding.UTF8.GetString(readBuffer, 0, result)); + await ctx.Response.Body.FlushAsync(); + result = await ctx.Request.Body.ReadAsync(readBuffer, 0, readBuffer.Length); + } + } + + private async Task ReadAndWriteSlowConnection(HttpContext ctx) + { + var t2 = Task.Run(() => WriteResponseBodyAFewTimes(ctx)); + var t1 = Task.Run(() => ReadRequestBody(ctx)); + await Task.WhenAll(t1, t2); + } + + private async Task WriteResponseBodyAFewTimes(HttpContext ctx) + { + for (var i = 0; i < 100; i++) + { + await ctx.Response.WriteAsync("hello world"); + } + } + + private async Task ReadAndWriteCopyToAsync(HttpContext ctx) + { + await ctx.Request.Body.CopyToAsync(ctx.Response.Body); + } + + private async Task UpgradeFeatureDetection(HttpContext ctx) + { + if (ctx.Features.Get() != null) + { + await ctx.Response.WriteAsync("Enabled"); + } + else + { + await ctx.Response.WriteAsync("Disabled"); + } + } + + private async Task TestReadOffsetWorks(HttpContext ctx) + { + var buffer = new byte[11]; + ctx.Request.Body.Read(buffer, 0, 6); + ctx.Request.Body.Read(buffer, 6, 5); + + await ctx.Response.WriteAsync(Encoding.UTF8.GetString(buffer)); + } + + private async Task TestInvalidReadOperations(HttpContext ctx) + { + var success = false; + if (ctx.Request.Path.StartsWithSegments("/NullBuffer")) + { + try + { + await ctx.Request.Body.ReadAsync(null, 0, 0); + } + catch (Exception) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidOffsetSmall")) + { + try + { + await ctx.Request.Body.ReadAsync(new byte[1], -1, 0); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidOffsetLarge")) + { + try + { + await ctx.Request.Body.ReadAsync(new byte[1], 2, 0); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountSmall")) + { + try + { + await ctx.Request.Body.ReadAsync(new byte[1], 0, -1); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountLarge")) + { + try + { + await ctx.Request.Body.ReadAsync(new byte[1], 0, -1); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountWithOffset")) + { + try + { + await ctx.Request.Body.ReadAsync(new byte[3], 1, 3); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + + + await ctx.Response.WriteAsync(success ? "Success" : "Failure"); + } + + private async Task TestValidReadOperations(HttpContext ctx) + { + var count = -1; + + if (ctx.Request.Path.StartsWithSegments("/NullBuffer")) + { + count = await ctx.Request.Body.ReadAsync(null, 0, 0); + } + else if (ctx.Request.Path.StartsWithSegments("/NullBufferPost")) + { + count = await ctx.Request.Body.ReadAsync(null, 0, 0); + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountZeroRead")) + { + count = await ctx.Request.Body.ReadAsync(new byte[1], 0, 0); + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountZeroReadPost")) + { + count = await ctx.Request.Body.ReadAsync(new byte[1], 0, 0); + } + + await ctx.Response.WriteAsync(count == 0 ? "Success" : "Failure"); + } + + private async Task TestInvalidWriteOperations(HttpContext ctx) + { + var success = false; + + if (ctx.Request.Path.StartsWithSegments("/InvalidOffsetSmall")) + { + try + { + await ctx.Response.Body.WriteAsync(new byte[1], -1, 0); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidOffsetLarge")) + { + try + { + await ctx.Response.Body.WriteAsync(new byte[1], 2, 0); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountSmall")) + { + try + { + await ctx.Response.Body.WriteAsync(new byte[1], 0, -1); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountLarge")) + { + try + { + await ctx.Response.Body.WriteAsync(new byte[1], 0, -1); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + else if (ctx.Request.Path.StartsWithSegments("/InvalidCountWithOffset")) + { + try + { + await ctx.Response.Body.WriteAsync(new byte[3], 1, 3); + } + catch (ArgumentOutOfRangeException) + { + success = true; + } + } + + await ctx.Response.WriteAsync(success ? "Success" : "Failure"); + } + + private async Task TestValidWriteOperations(HttpContext ctx) + { + if (ctx.Request.Path.StartsWithSegments("/NullBuffer")) + { + await ctx.Response.Body.WriteAsync(null, 0, 0); + } + else if (ctx.Request.Path.StartsWithSegments("/NullBufferPost")) + { + await ctx.Response.Body.WriteAsync(null, 0, 0); + } + + await ctx.Response.WriteAsync("Success"); + } + + private async Task LargeResponseFile(HttpContext ctx) + { + var tempFile = Path.GetTempFileName(); + var fileContent = new string('a', 200000); + var fileStream = File.OpenWrite(tempFile); + + for (var i = 0; i < 1000; i++) + { + await fileStream.WriteAsync(Encoding.UTF8.GetBytes(fileContent), 0, fileContent.Length); + } + fileStream.Close(); + + await ctx.Response.SendFileAsync(tempFile, 0, null); + + // Try to delete the file from the temp directory. If it fails, don't report an error + // to the application. File should eventually be cleaned up from the temp directory + // by OS. + try + { + File.Delete(tempFile); + } + catch (Exception) + { + } + } + + private async Task BasePath(HttpContext ctx) + { + await ctx.Response.WriteAsync(AppDomain.CurrentDomain.BaseDirectory); + } + + private async Task Shutdown(HttpContext ctx) + { + await ctx.Response.WriteAsync("Shutting down"); + ctx.RequestServices.GetService().StopApplication(); + } + + private async Task GetServerVariableStress(HttpContext ctx) + { + // This test simulates the scenario where native Flush call is being + // executed on background thread while request thread calls GetServerVariable + // concurrent native calls may cause native object corruption + + var serverVariableFeature = ctx.Features.Get(); + await ctx.Response.WriteAsync("Response Begin"); + for (int i = 0; i < 1000; i++) + { + await ctx.Response.WriteAsync(serverVariableFeature["REMOTE_PORT"]); + await ctx.Response.Body.FlushAsync(); + } + await ctx.Response.WriteAsync("Response End"); + } + + private async Task CommandLineArgs(HttpContext ctx) + { + await ctx.Response.WriteAsync(string.Join("|", Environment.GetCommandLineArgs().Skip(1))); + } + + public Task HttpsHelloWorld(HttpContext ctx) => + ctx.Response.WriteAsync("Scheme:" + ctx.Request.Scheme + "; Original:" + ctx.Request.Headers["x-original-proto"]); + } +} diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/web.config b/src/IISIntegration/test/WebSites/InProcessWebSite/web.config new file mode 100644 index 0000000000..2a9bd223c3 --- /dev/null +++ b/src/IISIntegration/test/WebSites/InProcessWebSite/web.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/WebSites/InProcessWebSite/wwwroot/static.txt b/src/IISIntegration/test/WebSites/InProcessWebSite/wwwroot/static.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/IISIntegration/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj new file mode 100644 index 0000000000..14beb7394e --- /dev/null +++ b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/OutOfProcessWebSite.csproj @@ -0,0 +1,31 @@ + + + + + + $(StandardTestTfms) + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Program.cs b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Program.cs new file mode 100644 index 0000000000..90895237d2 --- /dev/null +++ b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/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.IO; +using System.Linq; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Logging; + +namespace TestSite +{ + public static class Program + { + public static int Main(string[] args) + { + var mode = args.FirstOrDefault(); + switch (mode) + { + case "CreateFile": + File.WriteAllText(args[1], ""); + return StartServer(); + } + + return StartServer(); + } + + private static int StartServer() + { + var host = new WebHostBuilder() + .ConfigureLogging( + (_, factory) => { + factory.AddConsole(); + factory.AddFilter("Console", level => level >= LogLevel.Information); + }) + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .UseKestrel() + .Build(); + + host.Run(); + return 0; + } + } +} + diff --git a/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json new file mode 100644 index 0000000000..246b7a0b47 --- /dev/null +++ b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Properties/launchSettings.json @@ -0,0 +1,42 @@ +{ + "iisSettings": { + "windowsAuthentication": true, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5762/", + "sslPort": 0 + } + }, + "profiles": { + "ANCM IIS Express": { + "commandName": "Executable", + "executablePath": "$(IISExpressPath)", + "commandLineArgs": "$(IISExpressArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ANCM_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + }, + "ANCM IIS": { + "commandName": "Executable", + "executablePath": "$(IISPath)", + "commandLineArgs": "$(IISArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Startup.cs b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Startup.cs new file mode 100644 index 0000000000..de54a85a8a --- /dev/null +++ b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/Startup.cs @@ -0,0 +1,105 @@ +// 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.Diagnostics; +using System.IO; +using System.Linq; +using System.Security.Principal; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.IISIntegration.FunctionalTests; +using Microsoft.AspNetCore.Server.IISIntegration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace TestSite +{ + public partial class Startup + { + private IServerAddressesFeature _serverAddresses; + + public void Configure(IApplicationBuilder app) + { + TestStartup.Register(app, this); + + _serverAddresses = app.ServerFeatures.Get(); + } + + public Task Path(HttpContext ctx) => ctx.Response.WriteAsync(ctx.Request.Path.Value); + + public Task Query(HttpContext ctx) => ctx.Response.WriteAsync(ctx.Request.QueryString.Value); + + public Task BodyLimit(HttpContext ctx) => ctx.Response.WriteAsync(ctx.Features.Get()?.MaxRequestBodySize?.ToString() ?? "null"); + + + public Task HelloWorld(HttpContext ctx) => ctx.Response.WriteAsync("Hello World"); + + public Task HttpsHelloWorld(HttpContext ctx) => + ctx.Response.WriteAsync("Scheme:" + ctx.Request.Scheme + "; Original:" + ctx.Request.Headers["x-original-proto"]); + + public Task Anonymous(HttpContext context) => context.Response.WriteAsync("Anonymous?" + !context.User.Identity.IsAuthenticated); + + public Task Restricted(HttpContext context) + { + if (context.User.Identity.IsAuthenticated) + { + Assert.IsType(context.User); + return context.Response.WriteAsync(context.User.Identity.AuthenticationType); + } + else + { + return context.ChallengeAsync(IISDefaults.AuthenticationScheme); + } + } + + public Task Forbidden(HttpContext context) => context.ForbidAsync(IISDefaults.AuthenticationScheme); + + public Task RestrictedNTLM(HttpContext context) + { + if (string.Equals("NTLM", context.User.Identity.AuthenticationType, StringComparison.Ordinal)) + { + return context.Response.WriteAsync("NTLM"); + } + else + { + return context.ChallengeAsync(IISDefaults.AuthenticationScheme); + } + } + + public Task UpgradeFeatureDetection(HttpContext context) => + context.Response.WriteAsync(context.Features.Get() != null? "Enabled": "Disabled"); + + public Task CheckRequestHandlerVersion(HttpContext context) + { + // We need to check if the aspnetcorev2_outofprocess dll is loaded by iisexpress.exe + // As they aren't in the same process, we will try to delete the file and expect a file + // in use error + try + { + File.Delete(context.Request.Headers["ANCMRHPath"]); + } + catch(UnauthorizedAccessException) + { + // TODO calling delete on the file will succeed when running with IIS + return context.Response.WriteAsync("Hello World"); + } + + return context.Response.WriteAsync(context.Request.Headers["ANCMRHPath"]); + } + + private async Task ProcessId(HttpContext context) + { + await context.Response.WriteAsync(Process.GetCurrentProcess().Id.ToString()); + } + + private async Task ServerAddresses(HttpContext context) + { + await context.Response.WriteAsync(string.Join(",", _serverAddresses.Addresses)); + } + } +} diff --git a/src/IISIntegration/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt b/src/IISIntegration/test/WebSites/OutOfProcessWebSite/wwwroot/static.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/IISIntegration/test/WebSites/StressTestWebSite/Program.cs b/src/IISIntegration/test/WebSites/StressTestWebSite/Program.cs new file mode 100644 index 0000000000..e8e5392c2c --- /dev/null +++ b/src/IISIntegration/test/WebSites/StressTestWebSite/Program.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.Hosting; +using Microsoft.Extensions.Logging; + +namespace ANCMStressTestApp +{ + public class Program + { + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .ConfigureLogging((_, factory) => + { + factory.AddConsole(); + }) + .UseKestrel() + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/src/IISIntegration/test/WebSites/StressTestWebSite/Properties/launchSettings.json b/src/IISIntegration/test/WebSites/StressTestWebSite/Properties/launchSettings.json new file mode 100644 index 0000000000..246b7a0b47 --- /dev/null +++ b/src/IISIntegration/test/WebSites/StressTestWebSite/Properties/launchSettings.json @@ -0,0 +1,42 @@ +{ + "iisSettings": { + "windowsAuthentication": true, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5762/", + "sslPort": 0 + } + }, + "profiles": { + "ANCM IIS Express": { + "commandName": "Executable", + "executablePath": "$(IISExpressPath)", + "commandLineArgs": "$(IISExpressArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ANCM_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + }, + "ANCM IIS": { + "commandName": "Executable", + "executablePath": "$(IISPath)", + "commandLineArgs": "$(IISArguments)", + "environmentVariables": { + "IIS_SITE_PATH": "$(MSBuildThisFileDirectory)", + "ANCM_PATH": "$(AspNetCoreModuleV1ShimDll)", + "ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)", + "ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)", + "LAUNCHER_ARGS": "$(TargetPath)", + "ASPNETCORE_ENVIRONMENT": "Development", + "LAUNCHER_PATH": "$(DotNetPath)", + "ASPNETCORE_MODULE_DEBUG": "console" + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/StressTestWebSite/Startup.cs b/src/IISIntegration/test/WebSites/StressTestWebSite/Startup.cs new file mode 100644 index 0000000000..68f6eb1f77 --- /dev/null +++ b/src/IISIntegration/test/WebSites/StressTestWebSite/Startup.cs @@ -0,0 +1,232 @@ +// 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.Linq; +using System.Threading.Tasks; +using System.Threading; +using System.Text; +using System.Net.WebSockets; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Net.Http.Headers; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Primitives; + +namespace ANCMStressTestApp +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + } + + public void Configure(IApplicationBuilder app) + { + app.Map("/HelloWorld", HelloWorld); + app.Map("/ConnectionClose", ConnectionClose); + app.Map("/EchoPostData", EchoPostData); + app.Map("/LargeResponseBody", LargeResponseBody); + app.Map("/ResponseHeaders", ResponseHeaders); + app.Map("/EnvironmentVariables", EnvironmentVariables); + app.Map("/RequestInformation", RequestInformation); + app.Map("/WebSocket", WebSocket); + + app.Run(async context => + { + await context.Response.WriteAsync("Default Page"); + }); + } + + private void HelloWorld(IApplicationBuilder app) + { + app.Run(async context => + { + await context.Response.WriteAsync("Hello World"); + }); + } + + private void ConnectionClose(IApplicationBuilder app) + { + app.Run(async context => + { + context.Response.Headers[HeaderNames.Connection] = "close"; + await context.Response.WriteAsync("Connnection Close"); + await context.Response.Body.FlushAsync(); + }); + } + + private void EchoPostData(IApplicationBuilder app) + { + app.Run(async context => + { + string responseBody = string.Empty; + + if (string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase)) + { + using (StreamReader reader = new StreamReader(context.Request.Body, Encoding.UTF8)) + { + responseBody = await reader.ReadToEndAsync(); + } + } + else + { + responseBody = "NoAction"; + } + + await context.Response.WriteAsync(responseBody); + }); + } + + private void LargeResponseBody(IApplicationBuilder app) + { + app.Run(async context => + { + if (int.TryParse(context.Request.Query["length"], out var length)) + { + await context.Response.WriteAsync(new string('a', length)); + } + }); + } + + private void ResponseHeaders(IApplicationBuilder app) + { + app.Run(async context => + { + context.Response.Headers["UnknownHeader"] = "test123=foo"; + context.Response.ContentType = "text/plain"; + context.Response.Headers["MultiHeader"] = new StringValues(new string[] { "1", "2" }); + await context.Response.WriteAsync("Request Complete"); + }); + } + + private void EnvironmentVariables(IApplicationBuilder app) + { + app.Run(async context => + { + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Environment Variables:" + Environment.NewLine); + var vars = Environment.GetEnvironmentVariables(); + foreach (var key in vars.Keys.Cast().OrderBy(key => key, StringComparer.OrdinalIgnoreCase)) + { + var value = vars[key]; + await context.Response.WriteAsync(key + ": " + value + Environment.NewLine); + } + await context.Response.WriteAsync(Environment.NewLine); + }); + } + + private void RequestInformation(IApplicationBuilder app) + { + app.Run(async context => + { + context.Response.ContentType = "text/plain"; + + await context.Response.WriteAsync("Address:" + Environment.NewLine); + await context.Response.WriteAsync("Scheme: " + context.Request.Scheme + Environment.NewLine); + await context.Response.WriteAsync("Host: " + context.Request.Headers["Host"] + Environment.NewLine); + await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine); + await context.Response.WriteAsync("Path: " + context.Request.Path.Value + Environment.NewLine); + await context.Response.WriteAsync("Query: " + context.Request.QueryString.Value + Environment.NewLine); + await context.Response.WriteAsync(Environment.NewLine); + + await context.Response.WriteAsync("Connection:" + Environment.NewLine); + await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + Environment.NewLine); + await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + Environment.NewLine); + await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + Environment.NewLine); + await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + Environment.NewLine); + await context.Response.WriteAsync(Environment.NewLine); + + await context.Response.WriteAsync("Headers:" + Environment.NewLine); + foreach (var header in context.Request.Headers) + { + await context.Response.WriteAsync(header.Key + ": " + header.Value + Environment.NewLine); + } + await context.Response.WriteAsync(Environment.NewLine); + }); + } + + private void WebSocket(IApplicationBuilder app) + { + app.Run(async context => + { + var upgradeFeature = context.Features.Get(); + + // Generate WebSocket response headers + string key = context.Request.Headers[Constants.Headers.SecWebSocketKey].ToString(); + var responseHeaders = HandshakeHelpers.GenerateResponseHeaders(key); + foreach (var headerPair in responseHeaders) + { + context.Response.Headers[headerPair.Key] = headerPair.Value; + } + + // Upgrade the connection + Stream opaqueTransport = await upgradeFeature.UpgradeAsync(); + + // Get the WebSocket object + var ws = WebSocketProtocol.CreateFromStream(opaqueTransport, isServer: true, subProtocol: null, keepAliveInterval: TimeSpan.FromMinutes(2)); + + var appLifetime = app.ApplicationServices.GetRequiredService(); + + await Echo(ws, appLifetime.ApplicationStopping); + }); + } + + private async Task Echo(WebSocket webSocket, CancellationToken token) + { + try + { + var buffer = new byte[1024 * 4]; + var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), token); + bool closeFromServer = false; + string closeFromServerCmd = "CloseFromServer"; + int closeFromServerLength = closeFromServerCmd.Length; + + while (!result.CloseStatus.HasValue && !token.IsCancellationRequested && !closeFromServer) + { + if (result.Count == closeFromServerLength && + Encoding.ASCII.GetString(buffer).Substring(0, result.Count) == closeFromServerCmd) + { + // The client sent "CloseFromServer" text message to request the server to close (a test scenario). + closeFromServer = true; + } + else + { + await webSocket.SendAsync(new ArraySegment(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, token); + result = await webSocket.ReceiveAsync(new ArraySegment(buffer), token); + } + } + + if (result.CloseStatus.HasValue) + { + // Client-initiated close handshake + await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); + } + else + { + // Server-initiated close handshake due to either of the two conditions: + // (1) The applicaton host is performing a graceful shutdown. + // (2) The client sent "CloseFromServer" text message to request the server to close (a test scenario). + await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, closeFromServerCmd, CancellationToken.None); + + // The server has sent the Close frame. + // Stop sending but keep receiving until we get the Close frame from the client. + while (!result.CloseStatus.HasValue) + { + result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); + } + } + } + catch (Exception e) + { + Console.WriteLine("{0} Exception caught!", e); + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/StressTestWebSite/StressTestWebSite.csproj b/src/IISIntegration/test/WebSites/StressTestWebSite/StressTestWebSite.csproj new file mode 100644 index 0000000000..25ae032221 --- /dev/null +++ b/src/IISIntegration/test/WebSites/StressTestWebSite/StressTestWebSite.csproj @@ -0,0 +1,25 @@ + + + + + + $(StandardTestTfms) + true + + + + + + + + + + + + + + + + + + diff --git a/src/IISIntegration/test/WebSites/shared/SharedStartup/Startup.shared.cs b/src/IISIntegration/test/WebSites/shared/SharedStartup/Startup.shared.cs new file mode 100644 index 0000000000..b5d7f0305f --- /dev/null +++ b/src/IISIntegration/test/WebSites/shared/SharedStartup/Startup.shared.cs @@ -0,0 +1,117 @@ +// 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.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace TestSite +{ + public partial class Startup + { + public void ConfigureServices(IServiceCollection serviceCollection) + { + serviceCollection.AddResponseCompression(); + } + + private async Task HostingEnvironment(HttpContext ctx) + { + var hostingEnv = ctx.RequestServices.GetService(); + + await ctx.Response.WriteAsync("ContentRootPath " + hostingEnv.ContentRootPath + Environment.NewLine); + await ctx.Response.WriteAsync("WebRootPath " + hostingEnv.WebRootPath + Environment.NewLine); + await ctx.Response.WriteAsync("CurrentDirectory " + Environment.CurrentDirectory); + } + + private async Task ConsoleWrite(HttpContext ctx) + { + Console.WriteLine("TEST MESSAGE"); + + await ctx.Response.WriteAsync("Hello World"); + } + + private async Task ConsoleErrorWrite(HttpContext ctx) + { + Console.Error.WriteLine("TEST MESSAGE"); + + await ctx.Response.WriteAsync("Hello World"); + } + + public async Task Auth(HttpContext ctx) + { + var authProvider = ctx.RequestServices.GetService(); + var authScheme = (await authProvider.GetAllSchemesAsync()).SingleOrDefault(); + + await ctx.Response.WriteAsync(authScheme?.Name ?? "null"); + if (ctx.User.Identity.Name != null) + { + await ctx.Response.WriteAsync(":" + ctx.User.Identity.Name); + } + } + + public async Task GetClientCert(HttpContext context) + { + var clientCert = context.Connection.ClientCertificate; + await context.Response.WriteAsync(clientCert != null ? $"Enabled;{clientCert.GetCertHashString()}" : "Disabled"); + } + + private static int _waitingRequestCount; + + public Task WaitForAbort(HttpContext context) + { + Interlocked.Increment(ref _waitingRequestCount); + try + { + context.RequestAborted.WaitHandle.WaitOne(); + return Task.CompletedTask; + } + finally + { + Interlocked.Decrement(ref _waitingRequestCount); + } + } + + public Task Abort(HttpContext context) + { + context.Abort(); + return Task.CompletedTask; + } + + public async Task WaitingRequestCount(HttpContext context) + { + await context.Response.WriteAsync(_waitingRequestCount.ToString()); + } + + public Task CreateFile(HttpContext context) + { + var hostingEnv = context.RequestServices.GetService(); + File.WriteAllText(System.IO.Path.Combine(hostingEnv.ContentRootPath, "Started.txt"), ""); + return Task.CompletedTask; + } + + public Task OverrideServer(HttpContext context) + { + context.Response.Headers["Server"] = "MyServer/7.8"; + return Task.CompletedTask; + } + + public void CompressedData(IApplicationBuilder builder) + { + builder.UseResponseCompression(); + // write random bytes to check that compressed data is passed through + builder.Run( + async context => + { + context.Response.ContentType = "text/html"; + await context.Response.Body.WriteAsync(new byte[100], 0, 100); + }); + } + } +} diff --git a/src/IISIntegration/test/WebSites/shared/WebSockets/Constants.cs b/src/IISIntegration/test/WebSites/shared/WebSockets/Constants.cs new file mode 100644 index 0000000000..95b53003cc --- /dev/null +++ b/src/IISIntegration/test/WebSites/shared/WebSockets/Constants.cs @@ -0,0 +1,17 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests +{ + public static class Constants + { + public static class Headers + { + public const string Upgrade = "Upgrade"; + public const string UpgradeWebSocket = "websocket"; + public const string Connection = "Connection"; + public const string SecWebSocketKey = "Sec-WebSocket-Key"; + public const string SecWebSocketAccept = "Sec-WebSocket-Accept"; + } + } +} diff --git a/src/IISIntegration/test/WebSites/shared/WebSockets/HandshakeHelpers.cs b/src/IISIntegration/test/WebSites/shared/WebSockets/HandshakeHelpers.cs new file mode 100644 index 0000000000..b079ea3f85 --- /dev/null +++ b/src/IISIntegration/test/WebSites/shared/WebSockets/HandshakeHelpers.cs @@ -0,0 +1,41 @@ +// 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.Security.Cryptography; +using System.Text; + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests +{ + internal static class HandshakeHelpers + { + public static IEnumerable> GenerateResponseHeaders(string key) + { + yield return new KeyValuePair(Constants.Headers.Connection, Constants.Headers.Upgrade); + yield return new KeyValuePair(Constants.Headers.Upgrade, Constants.Headers.UpgradeWebSocket); + yield return new KeyValuePair(Constants.Headers.SecWebSocketAccept, CreateResponseKey(key)); + } + + public static string CreateResponseKey(string requestKey) + { + // "The value of this header field is constructed by concatenating /key/, defined above in step 4 + // in Section 4.2.2, with the string "258EAFA5- E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of + // this concatenated value to obtain a 20-byte value and base64-encoding" + // https://tools.ietf.org/html/rfc6455#section-4.2.2 + + if (requestKey == null) + { + throw new ArgumentNullException(nameof(requestKey)); + } + + using (var algorithm = SHA1.Create()) + { + string merged = requestKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + byte[] mergedBytes = Encoding.UTF8.GetBytes(merged); + byte[] hashedBytes = algorithm.ComputeHash(mergedBytes); + return Convert.ToBase64String(hashedBytes); + } + } + } +} diff --git a/src/IISIntegration/test/WebSites/shared/WebSockets/TestStartup.cs b/src/IISIntegration/test/WebSites/shared/WebSockets/TestStartup.cs new file mode 100644 index 0000000000..b1604e367a --- /dev/null +++ b/src/IISIntegration/test/WebSites/shared/WebSockets/TestStartup.cs @@ -0,0 +1,38 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNetCore.IISIntegration.FunctionalTests +{ + public static class TestStartup + { + public static void Register(IApplicationBuilder app, object startup) + { + var type = startup.GetType(); + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) + { + var parameters = method.GetParameters(); + if (method.Name != "Configure" && + parameters.Length == 1) + { + Action appfunc = null; + if (parameters[0].ParameterType == typeof(IApplicationBuilder)) + { + appfunc = innerAppBuilder => method.Invoke(startup, new[] { innerAppBuilder }); + } + else if (parameters[0].ParameterType == typeof(HttpContext)) + { + appfunc = innerAppBuilder => innerAppBuilder.Run(ctx => (Task)method.Invoke(startup, new[] { ctx })); + } + + if (appfunc != null) + { + app.Map("/" + method.Name, appfunc); + } + } + } + } + } +} diff --git a/src/IISIntegration/test/gtest/gtest.vcxproj b/src/IISIntegration/test/gtest/gtest.vcxproj new file mode 100644 index 0000000000..924f26337d --- /dev/null +++ b/src/IISIntegration/test/gtest/gtest.vcxproj @@ -0,0 +1,180 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + 15.0 + {CAC1267B-8778-4257-AAC6-CAF481723B01} + Win32Proj + gtest + 10.0.15063.0 + + + + StaticLibrary + true + v141 + Unicode + gtestd + + + StaticLibrary + false + v141 + true + Unicode + gtest + + + StaticLibrary + true + v141 + Unicode + gtestd + + + StaticLibrary + false + v141 + true + Unicode + gtest + + + + + + + + + + + + + + + + + + + + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(VC_SourcePath); + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(VC_SourcePath); + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(VC_SourcePath); + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath); + $(VC_SourcePath); + $(MSBuildProjectDirectory)\bin\$(Configuration)\$(Platform)\ + + + + NotUsing + Level3 + Disabled + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + googletest\googletest\include;googletest\googletest;googletest\googlemock;googletest\googlemock\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Windows + true + + + + + NotUsing + Level3 + Disabled + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + googletest\googletest\include;googletest\googletest;googletest\googlemock;googletest\googlemock\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + + + Windows + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + googletest\googletest\include;googletest\googletest;googletest\googlemock;googletest\googlemock\include;%(AdditionalIncludeDirectories) + MultiThreaded + + + Windows + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + googletest\googletest\include;googletest\googletest;googletest\googlemock;googletest\googlemock\include;%(AdditionalIncludeDirectories) + MultiThreaded + + + Windows + true + true + true + + + + + + \ No newline at end of file diff --git a/tools/GenerateNativeAssets.ps1 b/src/IISIntegration/tools/GenerateNativeAssets.ps1 similarity index 100% rename from tools/GenerateNativeAssets.ps1 rename to src/IISIntegration/tools/GenerateNativeAssets.ps1 diff --git a/tools/SetupTestEnvironment.ps1 b/src/IISIntegration/tools/SetupTestEnvironment.ps1 similarity index 100% rename from tools/SetupTestEnvironment.ps1 rename to src/IISIntegration/tools/SetupTestEnvironment.ps1 diff --git a/tools/UpdateIISExpressCertificate.ps1 b/src/IISIntegration/tools/UpdateIISExpressCertificate.ps1 similarity index 100% rename from tools/UpdateIISExpressCertificate.ps1 rename to src/IISIntegration/tools/UpdateIISExpressCertificate.ps1 diff --git a/tools/certificate.ps1 b/src/IISIntegration/tools/certificate.ps1 similarity index 100% rename from tools/certificate.ps1 rename to src/IISIntegration/tools/certificate.ps1 diff --git a/tools/httpsys.ps1 b/src/IISIntegration/tools/httpsys.ps1 similarity index 100% rename from tools/httpsys.ps1 rename to src/IISIntegration/tools/httpsys.ps1 diff --git a/tools/installancm.ps1 b/src/IISIntegration/tools/installancm.ps1 similarity index 100% rename from tools/installancm.ps1 rename to src/IISIntegration/tools/installancm.ps1 diff --git a/tools/update_schema.ps1 b/src/IISIntegration/tools/update_schema.ps1 similarity index 100% rename from tools/update_schema.ps1 rename to src/IISIntegration/tools/update_schema.ps1 diff --git a/version.props b/src/IISIntegration/version.props similarity index 100% rename from version.props rename to src/IISIntegration/version.props diff --git a/test/gtest/googletest b/test/gtest/googletest deleted file mode 160000 index 4e4df226fc..0000000000 --- a/test/gtest/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e4df226fc197c0dda6e37f5c8c3845ca1e73a49