Use TryAddWithoutValidation in WebSocketHandle.ConnectAsyncCore (dotnet/corefx#35954)
authorStephen Toub <stoub@microsoft.com>
Mon, 11 Mar 2019 17:32:41 +0000 (13:32 -0400)
committerGitHub <noreply@github.com>
Mon, 11 Mar 2019 17:32:41 +0000 (13:32 -0400)
Don't validate the headers the developer has explicitly added to ClientWebSocketOptions.RequestHeaders; just pass them through.

Commit migrated from https://github.com/dotnet/corefx/commit/e433981ea570928efbb1587cc6735c90c1881a58

src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs
src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs

index fd04dfb..bba1228 100644 (file)
@@ -83,7 +83,7 @@ namespace System.Net.WebSockets
                 {
                     foreach (string key in options.RequestHeaders)
                     {
-                        request.Headers.Add(key, options.RequestHeaders[key]);
+                        request.Headers.TryAddWithoutValidation(key, options.RequestHeaders[key]);
                     }
                 }
 
@@ -248,7 +248,7 @@ namespace System.Net.WebSockets
             request.Headers.TryAddWithoutValidation(HttpKnownHeaderNames.SecWebSocketKey, secKey);
             if (options._requestedSubProtocols?.Count > 0)
             {
-                request.Headers.Add(HttpKnownHeaderNames.SecWebSocketProtocol, string.Join(", ", options.RequestedSubProtocols));
+                request.Headers.TryAddWithoutValidation(HttpKnownHeaderNames.SecWebSocketProtocol, string.Join(", ", options.RequestedSubProtocols));
             }
         }
 
index ded853e..dc9553e 100644 (file)
@@ -225,5 +225,22 @@ namespace System.Net.WebSockets.Client.Tests
                 Assert.Equal(AcceptedProtocol, cws.SubProtocol);
             }
         }
+
+        [ConditionalFact(nameof(WebSocketsSupported))]
+        public async Task ConnectAsync_NonStandardRequestHeaders_HeadersAddedWithoutValidation()
+        {
+            await LoopbackServer.CreateClientAndServerAsync(async uri =>
+            {
+                using (var clientSocket = new ClientWebSocket())
+                using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
+                {
+                    clientSocket.Options.SetRequestHeader("Authorization", "AWS4-HMAC-SHA256 Credential= AKIAXXXXXXXXXXXYSZA /20190301/us-east-2/neptune-db/aws4_request, SignedHeaders=host;x-amz-date, Signature=b8155de54d9faab00000000000000000000000000a07e0d7dda49902e4d9202");
+                    await clientSocket.ConnectAsync(uri, cts.Token);
+                }
+            }, server => server.AcceptConnectionAsync(async connection =>
+            {
+                Assert.True(await LoopbackHelper.WebSocketHandshakeAsync(connection));
+            }), new LoopbackServer.Options { WebSocketEndpoint = true });
+        }
     }
 }