reverse-proxy icon indicating copy to clipboard operation
reverse-proxy copied to clipboard

Cannot use reverse proxy with multiple custom routes

Open bronthulke opened this issue 2 years ago • 3 comments

Describe the bug

I can't seem to get the reverse proxy working as expected when I have more than one route configured in my web app.

I'm using the reverse proxy in a .NET Framework to .NET 6 port. I'm using the "out of the box" configuration for YARP and I've added two routes as follows plus the reverse proxy mapping:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "EmbedScriptTrip",
        pattern: "embeds/script/trips/{alias}",
        defaults: new { controller = "Embeds", action = "GetTripsScript" });

    endpoints.MapReverseProxy();
});

What I'm expecting this to achieve is:

  • For a"default" route such as /home/index or /embed/index exists in this new app then use that, otherwise send it to the old app using the reverse proxy
  • similarly for the embeds/script/trips/ route, if it exists in the new app (which it does), use that, othewise send it to the old app using the reverse proxy

If I take out the endpoints.MapReverseProxy(); then the routes all work as expected:

/ goes to the home page of the new app /embed goes to the index page of the new app's Embeds controller /embed/script/trips/<some alias> goes to the new app's GetTripsScript action in the Embeds controller all other routes go to the old app

The issue I'm experiencing is that as soon as I reinstate that line to add in mapping for the reverse proxy, the "custom" route named "EmbedScriptTrip" stops working. If I have it reordered so that that route comes first, then THAT route works and the default route doesn't, and those / and /embed routes get proxied to the old app.

I've tried a bunch of alterative orders and can't seem to get to a situation where I have all my routes working AND the reverse proxying working for any routes that aren't existent in this new app .

Further technical details

  • YARP.ReverseProxy version 1.1.0
  • "new app" is .NET 6, "old app" that is being proxied to is .NET Framework 4.8
  • Running on Windows via the CLI (dotnet watch run) using Kestral

bronthulke avatar Nov 13 '22 05:11 bronthulke

We've found that setting the proxy route's Order property to a high value (1000) avoids these kinds of conflicts for routes with wildcards. https://microsoft.github.io/reverse-proxy/articles/config-files.html#all-config-properties

Tratcher avatar Nov 15 '22 16:11 Tratcher

Triage: Looks like something worth documenting in our docs. We have seen a few people to hit it and ask about it.

karelz avatar Nov 15 '22 18:11 karelz

That worked! I actually also now have two catch-alls, for different hosts, and this still works for that too. My current configuration looks like this:

"ReverseProxy": {
    "Routes": {
      "fallbackRoute": {
        "ClusterId": "fallbackClusterMainPlatform",
        "Order": "1000",
        "Match": {
          "Hosts": [ "maindomain.local" ],
          "Path": "{**catch-all}"
        }
      },
      "fallbackRouteSecondDomain": {
        "ClusterId": "fallbackClusterSecondDomain",
        "Order": "1000",
        "Match": {
          "Hosts": [ "seconddomain.awd.local" ],
          "Path": "{**catch-all}"
        }
      }
    },
    "Clusters": {
      "fallbackClusterMainPlatform": {
        "Destinations": {
          "fallbackApp": {
            "Address": "https://maindomain.local"
          }
        }
      },
      "fallbackClusterSecondDomain": {
        "Destinations": {
          "fallbackApp": {
            "Address": "https://seconddomain.local"
          }
        }
      }
    }
  }

And this still works - wonderful, thank you!

bronthulke avatar Nov 15 '22 22:11 bronthulke