diff --git a/src/GraphQL.Client/UriExtensions.cs b/src/GraphQL.Client/UriExtensions.cs index a3ab2b04..ad40a5bf 100644 --- a/src/GraphQL.Client/UriExtensions.cs +++ b/src/GraphQL.Client/UriExtensions.cs @@ -9,7 +9,7 @@ public static class UriExtensions /// /// /// - public static bool HasWebSocketScheme(this Uri uri) => uri.Scheme.Equals("wss") || uri.Scheme.Equals("ws"); + public static bool HasWebSocketScheme(this Uri uri) => uri.Scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) || uri.Scheme.Equals("ws", StringComparison.OrdinalIgnoreCase); /// /// Infers the websocket uri from . @@ -21,8 +21,16 @@ public static Uri GetWebSocketUri(this Uri uri) if (uri.HasWebSocketScheme()) return uri; - string webSocketScheme = uri.Scheme == "https" ? "wss" : "ws"; - return new Uri($"{webSocketScheme}://{uri.Host}:{uri.Port}{uri.PathAndQuery}"); + string webSocketScheme; + + if (uri.Scheme == Uri.UriSchemeHttps) + webSocketScheme = "wss"; + else if (uri.Scheme == Uri.UriSchemeHttp) + webSocketScheme = "ws"; + else + throw new NotSupportedException($"cannot infer websocket uri from uri scheme {uri.Scheme}"); + + return new UriBuilder(uri){Scheme = webSocketScheme}.Uri; } } } diff --git a/tests/GraphQL.Integration.Tests/UriExtensionTests.cs b/tests/GraphQL.Integration.Tests/UriExtensionTests.cs new file mode 100644 index 00000000..1298ca11 --- /dev/null +++ b/tests/GraphQL.Integration.Tests/UriExtensionTests.cs @@ -0,0 +1,47 @@ +using System; +using FluentAssertions; +using GraphQL.Client.Http; +using Xunit; + +namespace GraphQL.Integration.Tests +{ + public class UriExtensionTests + { + [Theory] + [InlineData("http://thats-not-a-websocket-url.net", false)] + [InlineData("https://thats-not-a-websocket-url.net", false)] + [InlineData("ftp://thats-not-a-websocket-url.net", false)] + [InlineData("ws://that-is-a-websocket-url.net", true)] + [InlineData("wss://that-is-a-websocket-url.net", true)] + [InlineData("WS://that-is-a-websocket-url.net", true)] + [InlineData("WSS://that-is-a-websocket-url.net", true)] + public void HasWebSocketSchemaTest(string url, bool result) + { + new Uri(url).HasWebSocketScheme().Should().Be(result); + } + + [Theory] + [InlineData("http://this-url-can-be-converted.net", true, "ws://this-url-can-be-converted.net")] + [InlineData("https://this-url-can-be-converted.net", true, "wss://this-url-can-be-converted.net")] + [InlineData("HTTP://this-url-can-be-converted.net", true, "ws://this-url-can-be-converted.net")] + [InlineData("HTTPS://this-url-can-be-converted.net", true, "wss://this-url-can-be-converted.net")] + [InlineData("ws://this-url-can-be-converted.net", true, "ws://this-url-can-be-converted.net")] + [InlineData("wss://this-url-can-be-converted.net", true, "wss://this-url-can-be-converted.net")] + [InlineData("https://this-url-can-be-converted.net/and/all/elements/?are#preserved", true, "wss://this-url-can-be-converted.net/and/all/elements/?are#preserved")] + [InlineData("ftp://this-url-cannot-be-converted.net", false, null)] + // AppSync example + [InlineData("wss://example1234567890000.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=123456789ABCDEF&payload=e30=", true, "wss://example1234567890000.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=123456789ABCDEF&payload=e30=")] + public void GetWebSocketUriTest(string input, bool canConvert, string result) + { + var inputUri = new Uri(input); + if (canConvert) + { + inputUri.GetWebSocketUri().Should().BeEquivalentTo(new Uri(result)); + } + else + { + inputUri.Invoking(uri => uri.GetWebSocketUri()).Should().Throw(); + } + } + } +}