diff --git a/playground/Stress/Stress.ApiService/ConsoleStresser.cs b/playground/Stress/Stress.ApiService/ConsoleStresser.cs index 03ab3e8a487..a084050f666 100644 --- a/playground/Stress/Stress.ApiService/ConsoleStresser.cs +++ b/playground/Stress/Stress.ApiService/ConsoleStresser.cs @@ -78,6 +78,11 @@ public static void Stress() Console.WriteLine("https://www.example.com/path/with/percent%25encoded"); Console.WriteLine("https://www.example.com/path/with/dollar$sign"); Console.WriteLine("https://www.example.com/path/with/exclamation!mark"); + Console.WriteLine("https://www.example.com/;path/"); + Console.WriteLine("https://www.example.com/path/?query;string"); + Console.WriteLine("https://;www.example.com/"); + Console.WriteLine("https://www;.example.com/"); + Console.WriteLine("https://www.exa;mple.com/"); Console.Write("\x1b[0m"); // reset color diff --git a/src/Aspire.Dashboard/ConsoleLogs/UrlParser.cs b/src/Aspire.Dashboard/ConsoleLogs/UrlParser.cs index 0b19a200baa..e5e14f5d2f3 100644 --- a/src/Aspire.Dashboard/ConsoleLogs/UrlParser.cs +++ b/src/Aspire.Dashboard/ConsoleLogs/UrlParser.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Net; using System.Text; using System.Text.RegularExpressions; @@ -34,7 +35,7 @@ public static bool TryParse(string? text, Func? nonMatchFragment nextCharIndex = urlMatch.Index + urlMatch.Length; var url = text[urlStart..nextCharIndex]; - builder.Append(CultureInfo.InvariantCulture, $"{url}"); + builder.Append(CultureInfo.InvariantCulture, $"{WebUtility.HtmlEncode(url)}"); urlMatch = urlMatch.NextMatch(); } @@ -65,17 +66,9 @@ static void AppendNonMatchFragment(StringBuilder stringBuilder, Funchttp://bing.com/")] [InlineData("http://bing.com/dir", "http://bing.com/dir")] [InlineData("http://bing.com/index.aspx", "http://bing.com/index.aspx")] - [InlineData("http://bing", "http://bing")] + [InlineData("http://localhost", "http://localhost")] public void TryParse_SupportedUrlFormats(string input, string? expectedOutput) { var result = UrlParser.TryParse(input, WebUtility.HtmlEncode, out var modifiedText); @@ -71,6 +71,15 @@ public void TryParse_ExcludeInvalidTrailingChars(string input, string? expectedO Assert.Equal(expectedOutput, modifiedText); } + [Fact] + public void TryParse_QueryString() + { + var result = UrlParser.TryParse("https://www.example.com?query=string¶m=value", WebUtility.HtmlEncode, out var modifiedText); + Assert.True(result); + + Assert.Equal("https://www.example.com?query=string&param=value", modifiedText); + } + [Theory] [InlineData("http://www.localhost:8080")] [InlineData("HTTP://WWW.LOCALHOST:8080")] @@ -83,4 +92,17 @@ public void GenerateUrlRegEx_MatchUrlAfterContent(string content) var match = regex.Match(content); Assert.Equal("http://www.localhost:8080", match.Value.ToLowerInvariant()); } + + [Theory] + [InlineData("http://www.localhost:8080!", "http://www.localhost:8080!")] + [InlineData("http://www.localhost:8080/path!", "http://www.localhost:8080/path!")] + [InlineData("http://www.localhost:8080/path;", "http://www.localhost:8080/path")] + [InlineData("http://www.localhost:8080;", "http://www.localhost:8080")] + [InlineData("http://www.local;host:8080;", "http://www.local")] + public void GenerateUrlRegEx_MatchUrlBeforeContent(string content, string expected) + { + var regex = UrlParser.GenerateUrlRegEx(); + var match = regex.Match(content); + Assert.Equal(expected, match.Value.ToLowerInvariant()); + } }