-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes encoded values on Blazor Router #53470
Conversation
a67e10b
to
ace334c
Compare
ace334c
to
a12be23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great!
@@ -112,9 +113,11 @@ private static string[] GetTemplates(Type componentType) | |||
[UnconditionalSuppressMessage("Trimming", "IL2067", Justification = "Application code does not get trimmed, and the framework does not define routable components.")] | |||
internal static RouteTable Create(Dictionary<Type, string[]> templatesByHandler, IServiceProvider serviceProvider) | |||
{ | |||
var routeOptions = Options.Create(new RouteOptions()); | |||
routeOptions.Value.SetParameterPolicy("regex", typeof(RegexInlineRouteConstraint)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure if this is part of dealing with encoding or if it's addressing a separate issue. Could you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is addressing a separate issue, we weren't wiring up the regex, which was needed to test this fully, as it doesn't affect other constraints that the Blazor router supports and we don't have support for authoring custom constraints either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we effectively added a whole new feature with this line of code then? I'm totally fine with this being added, assuming it doesn't appreciably impact the default bundle size for a Blazor WebAssembly app.
Could you confirm if that's the case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in the process of confirming the bundle size, it's not a feature, it's a bug fix IMO. It works on SSR routing but won't work once it becomes interactive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, please do confirm! I think we still have a choice of whether to include that feature for interactive mode, given that it's never worked on interactive mode in the past.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've taken out the regex bit and will put it on a separate commit.
...testassets/Components.TestServer/RazorComponents/Pages/Routing/Encoded/EncodedCatchAll.razor
Show resolved
Hide resolved
@@ -0,0 +1,24 @@ | |||
@page "/🙂/routing/constrained-catch-all/{*parameter:regex(http:%2F%2Fwww\\.example\\.com%2Flogin%2Fcallback\\/another)}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is a bit extreme, but I wanted to make sure we cover all the edge cases correctly, as this is very tricky.
As part of the routing unification process we switched the way we were decoding the URL prior to feeding it to routing and that introduced a small regression in interactive routing compared to .NET 7.0. This commit fixes that regression by using the same logic for decoding the URL in the client that is used on the server. In addition to that, the Blazor router now post processes the URL to replace instances of `%2F` with `/` when providing values to maintain the behavior in 7.0 where it used UnescapeDataString. This also makes the routing on the server and on the client consistent in their handling of encoded `/` characters.
a12be23
to
11b7c57
Compare
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/aspnetcore/actions/runs/7616006018 |
@javiercn backporting to release/8.0 failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: [Blazor] Fixed encoded values on Blazor Router
Using index info to reconstruct a base tree...
M src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
Falling back to patching base and 3-way merge...
Auto-merging src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
CONFLICT (content): Merge conflict in src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 [Blazor] Fixed encoded values on Blazor Router
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128 Please backport manually! |
@javiercn an error occurred while backporting to release/8.0, please check the run log for details! Error: git am failed, most likely due to a merge conflict. |
As part of the routing unification process we switched the way we were decoding the URL prior to feeding it to routing and that introduced a small regression in interactive routing compared to .NET 7.0. This commit fixes that regression by using the same logic for decoding the URL in the client that is used on the server. In addition to that, the Blazor router now post processes the URL to replace instances of `%2F` with `/` when providing values to maintain the behavior in 7.0 where it used UnescapeDataString. This also makes the routing on the server and on the client consistent in their handling of encoded `/` characters.
As part of the routing unification process we switched the way we were decoding the URL prior to feeding it to routing and that introduced a small regression in interactive routing compared to .NET 7.0. This commit fixes that regression by using the same logic for decoding the URL in the client that is used on the server. In addition to that, the Blazor router now post processes the URL to replace instances of `%2F` with `/` when providing values to maintain the behavior in 7.0 where it used UnescapeDataString. This also makes the routing on the server and on the client consistent in their handling of encoded `/` characters.
Fix handling of encoded
/
in URLs within the Blazor router.Fixes #52808, #53138, #53262
In .NET 8.0 we unified the routing system for ASP.NET Core and Blazor in order to bridge the functionality gaps and provide a consistent experience for SSR and interactive routing.
As part of such, we had to make adjustments to account for some of the quirks of the Blazor router (where it would behave slightly different than the ASP.NET Core router).
As part of this, we were decoding the entire URL before passing it to the Blazor router instead of (as it did before), splitting each segment and decoding each segment individually.
This introduced a regression when using URLs that contained encoded segments with
/
in them, as the router would then treat the/
as a path separator instead of part of the segment and we would not be able to route correctly.To fix this, we now decode each segment individually inside the router when the code runs as part of Blazor. In addition to that, when the routing happens server side, we now post-process the resulting values to URL decode them so that they match the behavior of the Blazor router.
To summarize, here is the before and after behavior:
Before:
/some/{parameter}
/some/encoded%2Fvalue
parameter = "encoded/value"
/some/{parameter}
/some/encoded%2Fvalue
parameter = "encoded%2Fvalue"
/some/{parameter}
/some/encoded%2Fvalue
After:
/some/{parameter}
/some/encoded%2Fvalue
parameter = "encoded/value"
/some/{parameter}
/some/encoded%2Fvalue
parameter = "encoded/value"
/some/{parameter}
/some/encoded%2Fvalue
parameter = "encoded/value"