dotnet / dotnet/yarp

URL Rewriting doesn't work together with Yarp Proxy Forwarding

Open
#2,532 9 comments 0 reactions 1 assignee Claimed by @benjaminpetit View on GitHub
External: AspNetCore Type: Tracking
Dominant language
C#
Stars
9.6k
Forks
933
Avg merge
12d 18h
Merged PRs (30d)
2

Description

### Describe the bug
I reproduced it with the Blazor static SSR app.
I've been migrating an old ASP.Net WebForms app to Blazor static SSR.
Using Yarp to proxy not migrated page requests to the ASP.Net WebForms app.

Rewritten URLs to the new Blazor static SSR app are trying to be proxied to the old ASP.Net Webforms app.

### To Reproduce
Here is an app initialization code I use:
```c#
services.AddReverseProxy()
.LoadFromConfig(Configuration.GetSection("Migration:ReverseProxy"));
....
var rewriteOptions = new RewriteOptions()
// static cache folder rewrite rule
.Add(UrlRewritingUtility.RewriteCachedStaticFilePathRequests);
app.UseRewriter(rewriteOptions);
....
app.MapReverseProxy();
```

RewriteCachedStaticFilePathRequests - a simple rule to remove the virtual cache folder for the static resource urls:
something like:
https://localhost:7159/cache/211108_0636182/img/logo.png
to
https://localhost:7159/img/logo.png
```c#
public static class UrlRewritingUtility
{
private static Regex StaticFilesCachedPathRegex = new Regex(@"^(/cache/\d{6}_\d{7})(/.+)$",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

public static void RewriteCachedStaticFilePathRequests(RewriteContext context)
{
var request = context.HttpContext.Request;

var path = request.Path.Value;
if (path is null || path.Length <= 21 || !path.Contains("/cache/", StringComparison.CurrentCultureIgnoreCase))
return;

var m = StaticFilesCachedPathRegex.Match(path);

if (m.Success)
{
context.Result = RuleResult.SkipRemainingRules;
request.Path = m.Groups[2].Value;
}
}
}
```

Forwarding Proxy configuration is:
```json
"Migration": {
"ReverseProxy": {
"Routes": {
"fallbackRoute": {
"ClusterId": "fallbackCluster",
"Order": "1",
"Match": {
"Path": "/{**catch-all}"
//"Path": "/AppVDir/{**catch-all}" // virtual dir is here as w/o it UseRewriter doesn't work as expected.
}
}
},
"Clusters": {
"fallbackCluster": {
"Destinations": {
"fallbackApp": {
"Address": "https://localhost/" // should be w/o vdir if app.MapReverseProxy(); is used
}
}
}
}
}
},
```

Url Rewriter doesn't work correct if Yarp proxing is enabled.
It seems that Url is rewritten correct but the Forwarding Proxy still decided to send this rewritten request to the old app.

I figured out that if Match Path is set to: "/{**catch-all}" URL Rewriting doesn't work as expected. Setting it to the "/AppVDir/{**catch-all}" fixes the issue. Really, it works only in the development environment only in this case.

### Further technical details

.Net 8, Yarp.ReverseProxy 2.1.0

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.