Currently, the guidance generates code in the back-end services that fills in the PathBase with the contents of X-Forwarded-Prefix value (if present), to correct the base paths used in various scenarios:
// Always replace the virtual path of this backend with the one from the yarp. Required for swagger and hangfire when hosted in IISHost!
app.Use((context, next) =>
{
var pathBase = context.Request.Headers["X-Forwarded-Prefix"];
if (!string.IsNullOrWhiteSpace(pathBase))
context.Request.PathBase = new PathString(pathBase);
return next();
});
This works because it assumes that the service shares the same host name and scheme as the Yarp. In fact, it is assumed that the PathBase is always /Yarp, except in Development scenarios where the PathBase will be empty (because the Yarp is also hosted on localhost, but using another port).
However, if a controller method needs to compute the URI of its endpoint, it should be able to compute it like this:
var uriBuilder = new UriBuilder(Request.Scheme, Request.Host.Host);
if (Request.Host.Port is not null)
uriBuilder.Port = Request.Host.Port.Value;
uriBuilder.Path = Request.PathBase.ToUriComponent() + "/whatever";
var endpoint = uriBuilder.ToString();
This works except in Development scenarios. because the Host will still be the service host, not the Yarp host!
To correct this, the above code should also set the other forwarded headers like this:
// Always replace the scheme, host and pathbase of this backend with the ones forwarded by Yarp. Required for swagger and hangfire when hosted in IISHost!
app.Use((context, next) =>
{
const string HeadedrPrefix = "X-Forwarded-"; // this can change
var pathBase = context.Request.Headers[HeadedrPrefix + "Prefix"];
if (!string.IsNullOrWhiteSpace(pathBase))
context.Request.PathBase = new PathString(pathBase);
var forwardedHost = context.Request.Headers[HeadedrPrefix + "Host"];
if (!string.IsNullOrWhiteSpace(forwardedHost))
context.Request.Host = HostString.FromUriComponent(forwardedHost);
var forwardedProto = context.Request.Headers[HeadedrPrefix + "Proto"];
if (!string.IsNullOrWhiteSpace(forwardedProto))
context.Request.Scheme = forwardedProto;
return next();
});
Currently, the guidance generates code in the back-end services that fills in the
PathBase
with the contents ofX-Forwarded-Prefix
value (if present), to correct the base paths used in various scenarios:This works because it assumes that the service shares the same host name and scheme as the Yarp. In fact, it is assumed that the PathBase is always
/Yarp
, except inDevelopment
scenarios where the PathBase will be empty (because the Yarp is also hosted on localhost, but using another port).However, if a controller method needs to compute the URI of its endpoint, it should be able to compute it like this:
This works except in
Development
scenarios. because theHost
will still be the service host, not the Yarp host!To correct this, the above code should also set the other forwarded headers like this:
Note that the
X-Forwarded-
has been explicitly factored out, since this is something that can be changed (see The section about X-Forwarded- in the documentation).