microsoft / reverse-proxy

A toolkit for developing high-performance HTTP reverse proxy applications.
https://microsoft.github.io/reverse-proxy
MIT License
8.44k stars 829 forks source link

Timeout configure not work #2581

Closed CwjXFH closed 5 days ago

CwjXFH commented 3 weeks ago

Hi,

I configured the timeout as described in the documentation, but it didn't work.

Environment: sdk yarp version
.NET 8 2.2.0-preview.1.24266.1

My configuration and code are as follows:

{
  "ReverseProxy": {
    "Routes": {
      "test_header_route": {
        "ClusterId": "test_cluster",
        "Timeout": "00:00:01",
        // "TimeoutPolicy": "basicPolicy",
        "Match": {
          "Hosts": [
            "*"
          ],
          "Headers": [
            {
              "Name": "X-Custome-Id",
              "Values": [
                "666"
              ],
              "Mode": "ExactHeader"
            }
          ]
        }
      }
    },
    "Clusters": {
      "test_cluster": {
        "Destinations": {
          "node1": {
            "Address": "https://www.google.com",
            "Methods": [
              "POST",
              "GET"
            ]
          }
        }
      }
    }
  }
}
var builder = WebApplication.CreateBuilder(args);

builder.Services
    // .AddRequestTimeouts(opt => opt.DefaultPolicy = new Microsoft.AspNetCore.Http.Timeouts.RequestTimeoutPolicy { Timeout = TimeSpan.FromSeconds(1) }) work
        //.AddRequestTimeouts(opt => opt.AddPolicy("basicPolicy", TimeSpan.FromMilliseconds(1000))) not work
    .AddRequestTimeouts() // not work
    .AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));

var app = builder.Build();
app.UseRequestTimeouts();
app.MapReverseProxy();
await app.RunAsync();

The Timeout configuration is not working. I sent a request, and it takes about 15s to return 504 Gateway Timeout.

MihaZupan commented 3 weeks ago

I can't reproduce that.

Note that request timeouts do not apply when you have a debugger attached. Are you seeing the same behavior without one?

Side note: "Methods" as part of the destination config are not recognized by YARP and will be ignored.

CwjXFH commented 3 weeks ago

Hi,

I changed Timeout from 00:00:01 to 00:00:1 and it works, strange.

But when the request timed out, it returned a 400 instead of a 504.

MihaZupan commented 2 weeks ago

I changed Timeout from 00:00:01 to 00:00:1 and it works, strange.

Both are parsed to the same value when reading the configuration file and as such behave exactly the same way. Are you sure you did not make any other changes?

Are you able to create a minimal runnable repro for the issue?

But when the request timed out, it returned a 400 instead of a 504.

When a timeout is hit, you're effectively terminating the request from the client as far as YARP is concerned.

If you were seeing that in a browser, it's possible that you're seeing a manufactured error the browser came up with when the request failed.

Since the timeout can occur at any point during a request/response, it's also possible that YARP already responded with a status code, but the request was canceled while we were copying data back to the client. At that point, the status code has already been sent, so it can't change.

karelz commented 5 days ago

Triage: Closing as answered. Let us know if we missed anything.