diff --git a/internal/server/http_client.go b/internal/server/http_client.go index 1741779..a7026b3 100644 --- a/internal/server/http_client.go +++ b/internal/server/http_client.go @@ -31,9 +31,12 @@ func NewUpstreamClient(cfg *config.Config) *http.Client { timeout = cfg.Global.UpstreamTimeout.DurationValue() } + transport := defaultTransport.Clone() + // Use UpstreamTimeout as ResponseHeaderTimeout to avoid killing long streaming downloads. + transport.ResponseHeaderTimeout = timeout + return &http.Client{ - Timeout: timeout, - Transport: defaultTransport.Clone(), + Transport: transport, } } diff --git a/internal/server/http_client_test.go b/internal/server/http_client_test.go index 623c673..975e1ed 100644 --- a/internal/server/http_client_test.go +++ b/internal/server/http_client_test.go @@ -16,8 +16,12 @@ func TestNewUpstreamClientUsesConfigTimeout(t *testing.T) { } client := NewUpstreamClient(cfg) - if client.Timeout != 45*time.Second { - t.Fatalf("expected timeout 45s, got %s", client.Timeout) + transport, ok := client.Transport.(*http.Transport) + if !ok { + t.Fatalf("expected *http.Transport, got %T", client.Transport) + } + if transport.ResponseHeaderTimeout != 45*time.Second { + t.Fatalf("expected response header timeout 45s, got %s", transport.ResponseHeaderTimeout) } } diff --git a/specs/001-config-bootstrap/data-model.md b/specs/001-config-bootstrap/data-model.md index 23bfbca..c21cddf 100644 --- a/specs/001-config-bootstrap/data-model.md +++ b/specs/001-config-bootstrap/data-model.md @@ -15,7 +15,7 @@ - `MaxMemoryCacheSize` (bytes, optional, default 268435456) - `MaxRetries` (int >=0, default 3) - `InitialBackoff` (duration, default 1s) - - `UpstreamTimeout` (duration, default 30s) + - `UpstreamTimeout` (duration, default 30s, used as upstream response header timeout; body can stream longer) - **Validation Rules**: 路径必须存在或可创建;数值必须 >0;LogLevel 必须匹配允许枚举。 - **Relationships**: 被 `Config` 聚合并为 `HubConfig` 提供默认值。