diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs b/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs index 0f13855c2c7e..ad6ccc2ab1d9 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Common/DeploymentParameters.cs @@ -183,11 +183,12 @@ public override string ToString() { return string.Format( CultureInfo.InvariantCulture, - "[Variation] :: ServerType={0}, Runtime={1}, Arch={2}, BaseUrlHint={3}, Publish={4}", + "[Variation] :: ServerType={0}, Runtime={1}, Arch={2}, BaseUrlHint={3}, Publish={4}, HostingModel={5}", ServerType, RuntimeFlavor, RuntimeArchitecture, ApplicationBaseUriHint, - PublishApplicationBeforeDeployment); + PublishApplicationBeforeDeployment, + HostingModel); } } diff --git a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp index ab22cd4755be..298481209578 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp @@ -180,6 +180,10 @@ FORWARDING_HANDLER::ExecuteRequestHandler() if (cchHeader == 9 && _stricmp(pszWebSocketHeader, "websocket") == 0) { m_fWebSocketEnabled = TRUE; + + // WinHttp does not support any extensions being returned by the server, so we remove the request header to avoid the server + // responding with any accepted extensions. + pRequest->DeleteHeader("Sec-WebSocket-Extensions"); } } diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteCollection.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteCollection.cs index b0c81b037f30..7a96d25087da 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteCollection.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteCollection.cs @@ -9,9 +9,15 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests; /// This type just maps collection names to available fixtures /// [CollectionDefinition(Name)] -public class IISTestSiteCollection : ICollectionFixture +public class IISTestSiteCollectionInProc : ICollectionFixture { - public const string Name = nameof(IISTestSiteCollection); + public const string Name = nameof(IISTestSiteCollectionInProc); +} + +[CollectionDefinition(Name)] +public class IISTestSiteCollectionOutOfProc : ICollectionFixture +{ + public const string Name = nameof(IISTestSiteCollectionOutOfProc); } [CollectionDefinition(Name)] diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteFixture.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteFixture.cs index 73074454b0c1..024ed61f9087 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteFixture.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Infrastructure/IISTestSiteFixture.cs @@ -46,6 +46,11 @@ internal IISTestSiteFixture(Action configure) ApplicationPublisher = new PublishedApplicationPublisher(Helpers.GetInProcessTestSitesName()), ServerType = DeployerSelector.ServerType }; + + // Uncomment to add IIS debug logs to test output. + //DeploymentParameters.EnvironmentVariables.Add("ASPNETCORE_MODULE_DEBUG", "console"); + + DeploymentParameters.EnableModule("WebSocketModule", "%IIS_BIN%/iiswsock.dll"); } public HttpClient Client => DeploymentResult.HttpClient; diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs index c701dd6bea25..4428a6d1a6dd 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/RequestResponseTests.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Server.IIS.NewShim.FunctionalTests; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests; #endif -[Collection(IISTestSiteCollection.Name)] +[Collection(IISTestSiteCollectionInProc.Name)] [SkipOnHelix("Unsupported queue", Queues = "Windows.Amd64.VS2022.Pre.Open;")] public class RequestResponseTests { diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketInProcessTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketInProcessTests.cs new file mode 100644 index 000000000000..0eff6ec45e0b --- /dev/null +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketInProcessTests.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; +using Microsoft.AspNetCore.InternalTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Xunit.Abstractions; + +#if !IIS_FUNCTIONALS +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; + +#if IISEXPRESS_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.IISExpress.FunctionalTests; +#elif NEWHANDLER_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.NewHandler.FunctionalTests; +#elif NEWSHIM_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.NewShim.FunctionalTests; +#endif +#else + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests; +#endif + +[Collection(IISTestSiteCollectionInProc.Name)] +[MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "No WebSocket supported on Win7")] +[SkipOnHelix("Unsupported queue", Queues = "Windows.Amd64.VS2022.Pre.Open;")] +public class WebSocketsInProcessTests : WebSocketsTests +{ + public WebSocketsInProcessTests(IISTestSiteFixture fixture, ITestOutputHelper testOutput) : base(fixture, testOutput) + { + Fixture.DeploymentParameters.HostingModel = HostingModel.InProcess; + } +} diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketOutOfProcessTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketOutOfProcessTests.cs new file mode 100644 index 000000000000..58b1c148ceb5 --- /dev/null +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketOutOfProcessTests.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; +using Microsoft.AspNetCore.InternalTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Xunit.Abstractions; + +#if !IIS_FUNCTIONALS +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; + +#if IISEXPRESS_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.IISExpress.FunctionalTests; +#elif NEWHANDLER_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.NewHandler.FunctionalTests; +#elif NEWSHIM_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.NewShim.FunctionalTests; +#endif +#else + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests; +#endif + +[Collection(IISTestSiteCollectionOutOfProc.Name)] +[MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "No WebSocket supported on Win7")] +[SkipOnHelix("Unsupported queue", Queues = "Windows.Amd64.VS2022.Pre.Open;")] +public class WebSocketsOutOfProcessTests : WebSocketsTests +{ + public WebSocketsOutOfProcessTests(IISTestSiteFixture fixture, ITestOutputHelper testOutput) : base(fixture, testOutput) + { + Fixture.DeploymentParameters.HostingModel = HostingModel.OutOfProcess; + } +} diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketTests.cs similarity index 55% rename from src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs rename to src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketTests.cs index a5586af0c0b9..aa2d7d0ebe3e 100644 --- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WebSocketTests.cs @@ -1,57 +1,76 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; +using System.Diagnostics; using System.Globalization; -using System.Linq; using System.Net.Http; using System.Net.Sockets; using System.Net.WebSockets; using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Server.IIS.FunctionalTests; using Microsoft.AspNetCore.InternalTesting; -using Xunit; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Xunit.Abstractions; + +#if !IIS_FUNCTIONALS +using Microsoft.AspNetCore.Server.IIS.FunctionalTests; +#if IISEXPRESS_FUNCTIONALS namespace Microsoft.AspNetCore.Server.IIS.IISExpress.FunctionalTests; +#elif NEWHANDLER_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.NewHandler.FunctionalTests; +#elif NEWSHIM_FUNCTIONALS +namespace Microsoft.AspNetCore.Server.IIS.NewShim.FunctionalTests; +#endif +#else + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests; +#endif -[Collection(IISTestSiteCollection.Name)] [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "No WebSocket supported on Win7")] [SkipOnHelix("Unsupported queue", Queues = "Windows.Amd64.VS2022.Pre.Open;")] -public class WebSocketsTests +public abstract class WebSocketsTests : FunctionalTestsBase { - private readonly string _requestUri; - private readonly string _webSocketUri; + public IISTestSiteFixture Fixture { get; } - public WebSocketsTests(IISTestSiteFixture fixture) + public WebSocketsTests(IISTestSiteFixture fixture, ITestOutputHelper testOutput) : base(testOutput) { - _requestUri = fixture.DeploymentResult.ApplicationBaseUri; - _webSocketUri = _requestUri.Replace("http:", "ws:"); + Fixture = fixture; + Fixture.DeploymentParameters.EnableLogging("C:/github/aspnetcore/artifacts/log"); } [ConditionalFact] public async Task RequestWithBody_NotUpgradable() { using var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(200) }; - using var response = await client.PostAsync(_requestUri + "WebSocketNotUpgradable", new StringContent("Hello World")); + using var response = await client.PostAsync(Fixture.DeploymentResult.ApplicationBaseUri + "WebSocketNotUpgradable", new StringContent("Hello World")); response.EnsureSuccessStatusCode(); } [ConditionalFact] public async Task RequestWithoutBody_Upgradable() { + if (Fixture.DeploymentParameters.HostingModel == HostingModel.OutOfProcess) + { + // OutOfProcess doesn't support upgrade requests without the "Upgrade": "websocket" header. + return; + } + using var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(200) }; // POST with Content-Length: 0 counts as not having a body. - using var response = await client.PostAsync(_requestUri + "WebSocketUpgradable", new StringContent("")); + using var response = await client.PostAsync(Fixture.DeploymentResult.ApplicationBaseUri + "WebSocketUpgradable", new StringContent("")); response.EnsureSuccessStatusCode(); } [ConditionalFact] public async Task OnStartedCalledForWebSocket() { - var cws = new ClientWebSocket(); - await cws.ConnectAsync(new Uri(_webSocketUri + "WebSocketLifetimeEvents"), default); + var webSocketUri = Fixture.DeploymentResult.ApplicationBaseUri; + webSocketUri = webSocketUri.Replace("http:", "ws:"); + + using var cws = new ClientWebSocket(); + await cws.ConnectAsync(new Uri(webSocketUri + "WebSocketLifetimeEvents"), default); await ReceiveMessage(cws, "OnStarting"); await ReceiveMessage(cws, "Upgraded"); @@ -60,8 +79,11 @@ public async Task OnStartedCalledForWebSocket() [ConditionalFact] public async Task WebReadBeforeUpgrade() { - var cws = new ClientWebSocket(); - await cws.ConnectAsync(new Uri(_webSocketUri + "WebSocketReadBeforeUpgrade"), default); + var webSocketUri = Fixture.DeploymentResult.ApplicationBaseUri; + webSocketUri = webSocketUri.Replace("http:", "ws:"); + + using var cws = new ClientWebSocket(); + await cws.ConnectAsync(new Uri(webSocketUri + "WebSocketReadBeforeUpgrade"), default); await ReceiveMessage(cws, "Yay"); } @@ -69,8 +91,11 @@ public async Task WebReadBeforeUpgrade() [ConditionalFact] public async Task CanSendAndReceieveData() { - var cws = new ClientWebSocket(); - await cws.ConnectAsync(new Uri(_webSocketUri + "WebSocketEcho"), default); + var webSocketUri = Fixture.DeploymentResult.ApplicationBaseUri; + webSocketUri = webSocketUri.Replace("http:", "ws:"); + + using var cws = new ClientWebSocket(); + await cws.ConnectAsync(new Uri(webSocketUri + "WebSocketEcho"), default); for (int i = 0; i < 1000; i++) { @@ -80,10 +105,33 @@ public async Task CanSendAndReceieveData() } } + [ConditionalFact] + public async Task AttemptCompressionWorks() + { + var webSocketUri = Fixture.DeploymentResult.ApplicationBaseUri; + webSocketUri = webSocketUri.Replace("http:", "ws:"); + + using var cws = new ClientWebSocket(); + cws.Options.DangerousDeflateOptions = new WebSocketDeflateOptions(); + await cws.ConnectAsync(new Uri(webSocketUri + "WebSocketAllowCompression"), default); + + // Compression doesn't work with OutOfProcess, let's make sure the websocket extensions aren't forwarded and the connection still works + var expected = Fixture.DeploymentParameters.HostingModel == HostingModel.InProcess + ? "permessage-deflate; client_max_window_bits=15" : "None"; + await ReceiveMessage(cws, expected); + + for (int i = 0; i < 1000; i++) + { + var message = i.ToString(CultureInfo.InvariantCulture); + await SendMessage(cws, message); + await ReceiveMessage(cws, message); + } + } + [ConditionalFact] public async Task Http1_0_Request_NotUpgradable() { - Uri uri = new Uri(_requestUri + "WebSocketNotUpgradable"); + Uri uri = new Uri(Fixture.DeploymentResult.ApplicationBaseUri + "WebSocketNotUpgradable"); using TcpClient client = new TcpClient(); await client.ConnectAsync(uri.Host, uri.Port); @@ -103,7 +151,7 @@ public async Task Http1_0_Request_NotUpgradable() [ConditionalFact] public async Task Http1_0_Request_UpgradeErrors() { - Uri uri = new Uri(_requestUri + "WebSocketUpgradeFails"); + Uri uri = new Uri(Fixture.DeploymentResult.ApplicationBaseUri + "WebSocketUpgradeFails"); using TcpClient client = new TcpClient(); await client.ConnectAsync(uri.Host, uri.Port); @@ -148,6 +196,7 @@ private async Task SendMessage(ClientWebSocket webSocket, string message) private async Task ReceiveMessage(ClientWebSocket webSocket, string expectedMessage) { + Debug.Assert(expectedMessage.Length > 0); var received = new byte[expectedMessage.Length]; var offset = 0; @@ -156,7 +205,7 @@ private async Task ReceiveMessage(ClientWebSocket webSocket, string expectedMess { result = await webSocket.ReceiveAsync(new ArraySegment(received, offset, received.Length - offset), default); offset += result.Count; - } while (!result.EndOfMessage); + } while (!result.EndOfMessage && result.CloseStatus is null && received.Length - offset > 0); Assert.Equal(expectedMessage, Encoding.ASCII.GetString(received)); } diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj index 15ad8db11a2f..f34f4f9e7cee 100644 --- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj +++ b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj @@ -11,7 +11,6 @@ true - diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/InProcessWebSite.csproj b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/InProcessWebSite.csproj index 4fdccefc70e8..7a4cef0ef12d 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/InProcessWebSite.csproj +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/InProcessWebSite.csproj @@ -28,6 +28,7 @@ + diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs index d0750ef81fd4..c7d502039f55 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.WebSockets.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Net.WebSockets; using System.Text; @@ -50,6 +51,8 @@ private void WebSocketReadBeforeUpgrade(IApplicationBuilder app) var ws = await Upgrade(context); await SendMessages(ws, "Yay"); + + await CloseWebSocket(ws, false); }); } @@ -85,6 +88,8 @@ private void WebSocketLifetimeEvents(IApplicationBuilder app) messages.Add("Upgraded"); await SendMessages(ws, messages.ToArray()); + + await CloseWebSocket(ws, false); }); } @@ -94,10 +99,38 @@ private void WebSocketUpgradeFails(IApplicationBuilder app) { var upgradeFeature = context.Features.Get(); var ex = await Assert.ThrowsAsync(() => upgradeFeature.UpgradeAsync()); - Assert.Equal("Upgrade requires HTTP/1.1.", ex.Message); + if (ex.Message != "Upgrade requires HTTP/1.1." + && ex.Message != "Cannot upgrade a non-upgradable request. Check IHttpUpgradeFeature.IsUpgradableRequest to determine if a request can be upgraded.") + { + throw new InvalidOperationException("Unexpected error from UpgradeAsync."); + } }); } +#if !FORWARDCOMPAT + private void WebSocketAllowCompression(IApplicationBuilder app) + { + app.Run(async context => + { + var ws = await context.WebSockets.AcceptWebSocketAsync(new WebSocketAcceptContext() + { + DangerousEnableCompression = true + }); + + var appLifetime = app.ApplicationServices.GetRequiredService(); + + var extensionsHeader = context.Response.Headers.SecWebSocketExtensions.ToString(); + if (extensionsHeader.Length == 0) + { + extensionsHeader = "None"; + } + await ws.SendAsync(Encoding.ASCII.GetBytes(extensionsHeader), WebSocketMessageType.Text, endOfMessage: true, default); + using var cts = CancellationTokenSource.CreateLinkedTokenSource(appLifetime.ApplicationStopping, context.RequestAborted); + await Echo(ws, cts.Token); + }); + } +#endif + private static async Task SendMessages(WebSocket webSocket, params string[] messages) { foreach (var message in messages) @@ -157,17 +190,30 @@ private async Task Echo(WebSocket webSocket, CancellationToken token) } 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); - } + await CloseWebSocket(webSocket, false); + } + } + + private async Task CloseWebSocket(WebSocket webSocket, bool receivedClose) + { + // 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, "CloseFromServer", CancellationToken.None); + + if (receivedClose) + { + return; + } + + // The server has sent the Close frame. + // Stop sending but keep receiving until we get the Close frame from the client. + WebSocketReceiveResult result; + var buffer = new byte[100]; + do + { + result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); } + while (!result.CloseStatus.HasValue); } } diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs index fba1940f881e..7588f67559ea 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs @@ -2,14 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Collections.Generic; -using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.Marshalling; using System.Security.Principal; using System.Text; using System.Threading; @@ -44,6 +40,11 @@ public void Configure(IApplicationBuilder app, IHttpContextAccessor httpContextA { app.UseHttpsRedirection(); } + +#if !FORWARDCOMPAT + app.UseWebSockets(); +#endif + TestStartup.Register(app, this); _httpContextAccessor = httpContextAccessor; } diff --git a/src/Servers/IIS/IISIntegration.slnf b/src/Servers/IIS/IISIntegration.slnf index db899fc491a9..9b6e5ea81e86 100644 --- a/src/Servers/IIS/IISIntegration.slnf +++ b/src/Servers/IIS/IISIntegration.slnf @@ -20,6 +20,7 @@ "src\\Middleware\\HttpOverrides\\src\\Microsoft.AspNetCore.HttpOverrides.csproj", "src\\Middleware\\HttpsPolicy\\src\\Microsoft.AspNetCore.HttpsPolicy.csproj", "src\\Middleware\\ResponseCompression\\src\\Microsoft.AspNetCore.ResponseCompression.csproj", + "src\\Middleware\\WebSockets\\src\\Microsoft.AspNetCore.WebSockets.csproj", "src\\ObjectPool\\src\\Microsoft.Extensions.ObjectPool.csproj", "src\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj", "src\\Servers\\HttpSys\\src\\Microsoft.AspNetCore.Server.HttpSys.csproj", @@ -39,10 +40,10 @@ "src\\Servers\\IIS\\IIS\\samples\\NativeIISSample\\NativeIISSample.csproj", "src\\Servers\\IIS\\IIS\\src\\Microsoft.AspNetCore.Server.IIS.csproj", "src\\Servers\\IIS\\IIS\\test\\IIS.FunctionalTests\\IIS.FunctionalTests.csproj", + "src\\Servers\\IIS\\IIS\\test\\IIS.LongTests\\IIS.LongTests.csproj", "src\\Servers\\IIS\\IIS\\test\\IIS.NewHandler.FunctionalTests\\IIS.NewHandler.FunctionalTests.csproj", "src\\Servers\\IIS\\IIS\\test\\IIS.NewShim.FunctionalTests\\IIS.NewShim.FunctionalTests.csproj", "src\\Servers\\IIS\\IIS\\test\\IIS.ShadowCopy.Tests\\IIS.ShadowCopy.Tests.csproj", - "src\\Servers\\IIS\\IIS\\test\\IIS.LongTests\\IIS.LongTests.csproj", "src\\Servers\\IIS\\IIS\\test\\IIS.Tests\\IIS.Tests.csproj", "src\\Servers\\IIS\\IIS\\test\\IISExpress.FunctionalTests\\IISExpress.FunctionalTests.csproj", "src\\Servers\\IIS\\IIS\\test\\testassets\\IIS.Common.TestLib\\IIS.Common.TestLib.csproj",