Request timeouts reported as ForwarderError.RequestCanceled instead of RequestTimedOut
Hello,
Confirming the same behavior on the 2.2.0 release, but let me add more details. But when the request timed out, it returned a 400 instead of a 504.
Trying to configure timeouts with
ForwarderRequestConfig.ActivityTimeouton a cluster andTimeout/TimeoutPolicyon a route, but results are different: the first configuration returns504 Gateway Timeout, second -400 Bad Request. Shouldn't the results be the same?@MihaZupan, created a repository, please have a look. Are you able to create a minimal runnable repro for the issue?
Originally posted by @alekseikhripunov in #2581
When using request timeouts (timeout configuration on the route), that timeout works by signaling the HttpContext.RequestAborted CancellationToken.
YARP currently assumes that token getting cancelled is the result of the client disconnecting and reports a 400 status code.
We could detect this case by looking for the IHttpRequestTimeoutFeature, similar to how we already handle ActivityTimeouts differently.
https://github.com/microsoft/reverse-proxy/blob/ed43822e2fc0d6006f3ea4085ee48118bc173514/src/ReverseProxy/Forwarder/HttpForwarder.cs#L637-L639
https://github.com/microsoft/reverse-proxy/blob/ed43822e2fc0d6006f3ea4085ee48118bc173514/src/ReverseProxy/Forwarder/HttpForwarder.cs#L665-L670
As a workaround, you could insert a middleware along the lines of
app.Use(async (context, next) =>
{
await next();
if (context.RequestAborted.IsCancellationRequested &&
!context.Response.HasStarted &&
context.Features.Get<IHttpRequestTimeoutFeature>() is { } timeoutFeature &&
timeoutFeature.RequestTimeoutToken.IsCancellationRequested)
{
context.Response.StatusCode = StatusCodes.Status504GatewayTimeout;
}
});
When using request timeouts (timeout configuration on the route), that timeout works by signaling the
HttpContext.RequestAbortedCancellationToken.YARP currently assumes that token getting cancelled is the result of the client disconnecting and reports a 400 status code. We could detect this case by looking for the
IHttpRequestTimeoutFeature, similar to how we already handleActivityTimeouts differently.https://github.com/microsoft/reverse-proxy/blob/ed43822e2fc0d6006f3ea4085ee48118bc173514/src/ReverseProxy/Forwarder/HttpForwarder.cs#L637-L639
https://github.com/microsoft/reverse-proxy/blob/ed43822e2fc0d6006f3ea4085ee48118bc173514/src/ReverseProxy/Forwarder/HttpForwarder.cs#L665-L670
Met the same issue, looking forward the improvement in YARP side.