11// Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33
4- using System ;
4+ using System . Diagnostics ;
55using System . Globalization ;
6- using System . Linq ;
76using System . Net . Http ;
87using System . Net . Sockets ;
98using System . Net . WebSockets ;
109using System . Text ;
11- using System . Threading ;
12- using System . Threading . Tasks ;
13- using Microsoft . AspNetCore . Server . IIS . FunctionalTests ;
1410using Microsoft . AspNetCore . InternalTesting ;
15- using Xunit ;
11+ using Microsoft . AspNetCore . Server . IIS . FunctionalTests ;
12+ using Microsoft . AspNetCore . Server . IntegrationTesting ;
13+ using Microsoft . AspNetCore . Server . IntegrationTesting . IIS ;
14+ using Xunit . Abstractions ;
15+
16+ #if ! IIS_FUNCTIONALS
17+ using Microsoft . AspNetCore . Server . IIS . FunctionalTests ;
1618
19+ #if IISEXPRESS_FUNCTIONALS
1720namespace Microsoft . AspNetCore . Server . IIS . IISExpress . FunctionalTests ;
21+ #elif NEWHANDLER_FUNCTIONALS
22+ namespace Microsoft . AspNetCore . Server . IIS . NewHandler . FunctionalTests ;
23+ #elif NEWSHIM_FUNCTIONALS
24+ namespace Microsoft . AspNetCore . Server . IIS . NewShim . FunctionalTests ;
25+ #endif
26+ #else
27+
28+ namespace Microsoft . AspNetCore . Server . IIS . FunctionalTests ;
29+ #endif
1830
19- [ Collection ( IISTestSiteCollection . Name ) ]
2031[ MinimumOSVersion ( OperatingSystems . Windows , WindowsVersions . Win8 , SkipReason = "No WebSocket supported on Win7" ) ]
2132[ SkipOnHelix ( "Unsupported queue" , Queues = "Windows.Amd64.VS2022.Pre.Open;" ) ]
22- public class WebSocketsTests
33+ public abstract class WebSocketsTests : FunctionalTestsBase
2334{
24- private readonly string _requestUri ;
25- private readonly string _webSocketUri ;
35+ public IISTestSiteFixture Fixture { get ; }
2636
27- public WebSocketsTests ( IISTestSiteFixture fixture )
37+ public WebSocketsTests ( IISTestSiteFixture fixture , ITestOutputHelper testOutput ) : base ( testOutput )
2838 {
29- _requestUri = fixture . DeploymentResult . ApplicationBaseUri ;
30- _webSocketUri = _requestUri . Replace ( "http:" , "ws: ") ;
39+ Fixture = fixture ;
40+ Fixture . DeploymentParameters . EnableLogging ( "C:/github/aspnetcore/artifacts/log ") ;
3141 }
3242
3343 [ ConditionalFact ]
3444 public async Task RequestWithBody_NotUpgradable ( )
3545 {
3646 using var client = new HttpClient ( ) { Timeout = TimeSpan . FromSeconds ( 200 ) } ;
37- using var response = await client . PostAsync ( _requestUri + "WebSocketNotUpgradable" , new StringContent ( "Hello World" ) ) ;
47+ using var response = await client . PostAsync ( Fixture . DeploymentResult . ApplicationBaseUri + "WebSocketNotUpgradable" , new StringContent ( "Hello World" ) ) ;
3848 response . EnsureSuccessStatusCode ( ) ;
3949 }
4050
4151 [ ConditionalFact ]
4252 public async Task RequestWithoutBody_Upgradable ( )
4353 {
54+ if ( Fixture . DeploymentParameters . HostingModel == HostingModel . OutOfProcess )
55+ {
56+ // OutOfProcess doesn't support upgrade requests without the "Upgrade": "websocket" header.
57+ return ;
58+ }
59+
4460 using var client = new HttpClient ( ) { Timeout = TimeSpan . FromSeconds ( 200 ) } ;
4561 // POST with Content-Length: 0 counts as not having a body.
46- using var response = await client . PostAsync ( _requestUri + "WebSocketUpgradable" , new StringContent ( "" ) ) ;
62+ using var response = await client . PostAsync ( Fixture . DeploymentResult . ApplicationBaseUri + "WebSocketUpgradable" , new StringContent ( "" ) ) ;
4763 response . EnsureSuccessStatusCode ( ) ;
4864 }
4965
5066 [ ConditionalFact ]
5167 public async Task OnStartedCalledForWebSocket ( )
5268 {
53- var cws = new ClientWebSocket ( ) ;
54- await cws . ConnectAsync ( new Uri ( _webSocketUri + "WebSocketLifetimeEvents" ) , default ) ;
69+ var webSocketUri = Fixture . DeploymentResult . ApplicationBaseUri ;
70+ webSocketUri = webSocketUri . Replace ( "http:" , "ws:" ) ;
71+
72+ using var cws = new ClientWebSocket ( ) ;
73+ await cws . ConnectAsync ( new Uri ( webSocketUri + "WebSocketLifetimeEvents" ) , default ) ;
5574
5675 await ReceiveMessage ( cws , "OnStarting" ) ;
5776 await ReceiveMessage ( cws , "Upgraded" ) ;
@@ -60,17 +79,23 @@ public async Task OnStartedCalledForWebSocket()
6079 [ ConditionalFact ]
6180 public async Task WebReadBeforeUpgrade ( )
6281 {
63- var cws = new ClientWebSocket ( ) ;
64- await cws . ConnectAsync ( new Uri ( _webSocketUri + "WebSocketReadBeforeUpgrade" ) , default ) ;
82+ var webSocketUri = Fixture . DeploymentResult . ApplicationBaseUri ;
83+ webSocketUri = webSocketUri . Replace ( "http:" , "ws:" ) ;
84+
85+ using var cws = new ClientWebSocket ( ) ;
86+ await cws . ConnectAsync ( new Uri ( webSocketUri + "WebSocketReadBeforeUpgrade" ) , default ) ;
6587
6688 await ReceiveMessage ( cws , "Yay" ) ;
6789 }
6890
6991 [ ConditionalFact ]
7092 public async Task CanSendAndReceieveData ( )
7193 {
72- var cws = new ClientWebSocket ( ) ;
73- await cws . ConnectAsync ( new Uri ( _webSocketUri + "WebSocketEcho" ) , default ) ;
94+ var webSocketUri = Fixture . DeploymentResult . ApplicationBaseUri ;
95+ webSocketUri = webSocketUri . Replace ( "http:" , "ws:" ) ;
96+
97+ using var cws = new ClientWebSocket ( ) ;
98+ await cws . ConnectAsync ( new Uri ( webSocketUri + "WebSocketEcho" ) , default ) ;
7499
75100 for ( int i = 0 ; i < 1000 ; i ++ )
76101 {
@@ -80,10 +105,33 @@ public async Task CanSendAndReceieveData()
80105 }
81106 }
82107
108+ [ ConditionalFact ]
109+ public async Task AttemptCompressionWorks ( )
110+ {
111+ var webSocketUri = Fixture . DeploymentResult . ApplicationBaseUri ;
112+ webSocketUri = webSocketUri . Replace ( "http:" , "ws:" ) ;
113+
114+ using var cws = new ClientWebSocket ( ) ;
115+ cws . Options . DangerousDeflateOptions = new WebSocketDeflateOptions ( ) ;
116+ await cws . ConnectAsync ( new Uri ( webSocketUri + "WebSocketAllowCompression" ) , default ) ;
117+
118+ // Compression doesn't work with OutOfProcess, let's make sure the websocket extensions aren't forwarded and the connection still works
119+ var expected = Fixture . DeploymentParameters . HostingModel == HostingModel . InProcess
120+ ? "permessage-deflate; client_max_window_bits=15" : "None" ;
121+ await ReceiveMessage ( cws , expected ) ;
122+
123+ for ( int i = 0 ; i < 1000 ; i ++ )
124+ {
125+ var message = i . ToString ( CultureInfo . InvariantCulture ) ;
126+ await SendMessage ( cws , message ) ;
127+ await ReceiveMessage ( cws , message ) ;
128+ }
129+ }
130+
83131 [ ConditionalFact ]
84132 public async Task Http1_0_Request_NotUpgradable ( )
85133 {
86- Uri uri = new Uri ( _requestUri + "WebSocketNotUpgradable" ) ;
134+ Uri uri = new Uri ( Fixture . DeploymentResult . ApplicationBaseUri + "WebSocketNotUpgradable" ) ;
87135 using TcpClient client = new TcpClient ( ) ;
88136
89137 await client . ConnectAsync ( uri . Host , uri . Port ) ;
@@ -103,7 +151,7 @@ public async Task Http1_0_Request_NotUpgradable()
103151 [ ConditionalFact ]
104152 public async Task Http1_0_Request_UpgradeErrors ( )
105153 {
106- Uri uri = new Uri ( _requestUri + "WebSocketUpgradeFails" ) ;
154+ Uri uri = new Uri ( Fixture . DeploymentResult . ApplicationBaseUri + "WebSocketUpgradeFails" ) ;
107155 using TcpClient client = new TcpClient ( ) ;
108156
109157 await client . ConnectAsync ( uri . Host , uri . Port ) ;
@@ -148,6 +196,7 @@ private async Task SendMessage(ClientWebSocket webSocket, string message)
148196
149197 private async Task ReceiveMessage ( ClientWebSocket webSocket , string expectedMessage )
150198 {
199+ Debug . Assert ( expectedMessage . Length > 0 ) ;
151200 var received = new byte [ expectedMessage . Length ] ;
152201
153202 var offset = 0 ;
@@ -156,7 +205,7 @@ private async Task ReceiveMessage(ClientWebSocket webSocket, string expectedMess
156205 {
157206 result = await webSocket . ReceiveAsync ( new ArraySegment < byte > ( received , offset , received . Length - offset ) , default ) ;
158207 offset += result . Count ;
159- } while ( ! result . EndOfMessage ) ;
208+ } while ( ! result . EndOfMessage && result . CloseStatus is null && received . Length - offset > 0 ) ;
160209
161210 Assert . Equal ( expectedMessage , Encoding . ASCII . GetString ( received ) ) ;
162211 }
0 commit comments