1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-08-26 18:21:01 +00:00

refactor(fetcher): use time.Duration for client timeout values

All functions use time.Duration, so instead of converting everywhere, do it once.
This commit is contained in:
gudvinr 2025-08-18 23:10:18 +03:00 committed by Frédéric Guillot
parent 71af68becd
commit 30453ad7ec
5 changed files with 51 additions and 22 deletions

View file

@ -1607,12 +1607,22 @@ func TestMediaProxyHTTPClientTimeout(t *testing.T) {
t.Fatalf(`Parsing failure: %v`, err) t.Fatalf(`Parsing failure: %v`, err)
} }
expected := 24 expected := 24 * time.Second
result := opts.MediaProxyHTTPClientTimeout() result := opts.MediaProxyHTTPClientTimeout()
if result != expected { if result != expected {
t.Fatalf(`Unexpected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected) t.Fatalf(`Unexpected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected)
} }
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT"
})
expectedSerialized := 24
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
} }
func TestDefaultMediaProxyHTTPClientTimeoutValue(t *testing.T) { func TestDefaultMediaProxyHTTPClientTimeoutValue(t *testing.T) {
@ -1630,6 +1640,16 @@ func TestDefaultMediaProxyHTTPClientTimeoutValue(t *testing.T) {
if result != expected { if result != expected {
t.Fatalf(`Unexpected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected) t.Fatalf(`Unexpected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected)
} }
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT"
})
expectedSerialized := int(defaultMediaProxyHTTPClientTimeout / time.Second)
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
} }
func TestMediaProxyCustomURL(t *testing.T) { func TestMediaProxyCustomURL(t *testing.T) {
@ -1706,12 +1726,22 @@ func TestHTTPClientTimeout(t *testing.T) {
t.Fatalf(`Parsing failure: %v`, err) t.Fatalf(`Parsing failure: %v`, err)
} }
expected := 42 expected := 42 * time.Second
result := opts.HTTPClientTimeout() result := opts.HTTPClientTimeout()
if result != expected { if result != expected {
t.Fatalf(`Unexpected HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected) t.Fatalf(`Unexpected HTTP_CLIENT_TIMEOUT value, got %d instead of %d`, result, expected)
} }
sorted := opts.SortedOptions(false)
i := slices.IndexFunc(sorted, func(opt *option) bool {
return opt.Key == "HTTP_CLIENT_TIMEOUT"
})
expectedSerialized := 42
if got := sorted[i].Value; got != expectedSerialized {
t.Fatalf(`Unexpected value in option output, got %q instead of %q`, got, expectedSerialized)
}
} }
func TestDefaultHTTPClientTimeoutValue(t *testing.T) { func TestDefaultHTTPClientTimeoutValue(t *testing.T) {

View file

@ -52,7 +52,7 @@ const (
defaultCleanupArchiveUnreadDays = 180 defaultCleanupArchiveUnreadDays = 180
defaultCleanupArchiveBatchSize = 10000 defaultCleanupArchiveBatchSize = 10000
defaultCleanupRemoveSessionsDays = 30 defaultCleanupRemoveSessionsDays = 30
defaultMediaProxyHTTPClientTimeout = 120 defaultMediaProxyHTTPClientTimeout = 120 * time.Second
defaultMediaProxyMode = "http-only" defaultMediaProxyMode = "http-only"
defaultMediaResourceTypes = "image" defaultMediaResourceTypes = "image"
defaultMediaProxyURL = "" defaultMediaProxyURL = ""
@ -74,7 +74,7 @@ const (
defaultOauth2OidcProviderName = "OpenID Connect" defaultOauth2OidcProviderName = "OpenID Connect"
defaultOAuth2Provider = "" defaultOAuth2Provider = ""
defaultDisableLocalAuth = false defaultDisableLocalAuth = false
defaultHTTPClientTimeout = 20 defaultHTTPClientTimeout = 20 * time.Second
defaultHTTPClientMaxBodySize = 15 defaultHTTPClientMaxBodySize = 15
defaultHTTPClientProxy = "" defaultHTTPClientProxy = ""
defaultHTTPServerTimeout = 300 * time.Second defaultHTTPServerTimeout = 300 * time.Second
@ -145,7 +145,7 @@ type options struct {
createAdmin bool createAdmin bool
adminUsername string adminUsername string
adminPassword string adminPassword string
mediaProxyHTTPClientTimeout int mediaProxyHTTPClientTimeout time.Duration
mediaProxyMode string mediaProxyMode string
mediaProxyResourceTypes []string mediaProxyResourceTypes []string
mediaProxyCustomURL *url.URL mediaProxyCustomURL *url.URL
@ -165,7 +165,7 @@ type options struct {
oidcProviderName string oidcProviderName string
oauth2Provider string oauth2Provider string
disableLocalAuth bool disableLocalAuth bool
httpClientTimeout int httpClientTimeout time.Duration
httpClientMaxBodySize int64 httpClientMaxBodySize int64
httpClientProxyURL *url.URL httpClientProxyURL *url.URL
httpClientProxies []string httpClientProxies []string
@ -567,8 +567,8 @@ func (o *options) MediaCustomProxyURL() *url.URL {
return o.mediaProxyCustomURL return o.mediaProxyCustomURL
} }
// MediaProxyHTTPClientTimeout returns the time limit in seconds before the proxy HTTP client cancel the request. // MediaProxyHTTPClientTimeout returns the time limit before the proxy HTTP client cancel the request.
func (o *options) MediaProxyHTTPClientTimeout() int { func (o *options) MediaProxyHTTPClientTimeout() time.Duration {
return o.mediaProxyHTTPClientTimeout return o.mediaProxyHTTPClientTimeout
} }
@ -588,7 +588,7 @@ func (o *options) HasSchedulerService() bool {
} }
// HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request. // HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request.
func (o *options) HTTPClientTimeout() int { func (o *options) HTTPClientTimeout() time.Duration {
return o.httpClientTimeout return o.httpClientTimeout
} }
@ -743,7 +743,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
"HTTP_CLIENT_MAX_BODY_SIZE": o.httpClientMaxBodySize, "HTTP_CLIENT_MAX_BODY_SIZE": o.httpClientMaxBodySize,
"HTTP_CLIENT_PROXIES": clientProxyURLsRedacted, "HTTP_CLIENT_PROXIES": clientProxyURLsRedacted,
"HTTP_CLIENT_PROXY": clientProxyURLRedacted, "HTTP_CLIENT_PROXY": clientProxyURLRedacted,
"HTTP_CLIENT_TIMEOUT": o.httpClientTimeout, "HTTP_CLIENT_TIMEOUT": int(o.httpClientTimeout.Seconds()),
"HTTP_CLIENT_USER_AGENT": o.httpClientUserAgent, "HTTP_CLIENT_USER_AGENT": o.httpClientUserAgent,
"HTTP_SERVER_TIMEOUT": int(o.httpServerTimeout.Seconds()), "HTTP_SERVER_TIMEOUT": int(o.httpServerTimeout.Seconds()),
"HTTP_SERVICE": o.httpService, "HTTP_SERVICE": o.httpService,
@ -774,7 +774,7 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
"POLLING_LIMIT_PER_HOST": o.pollingLimitPerHost, "POLLING_LIMIT_PER_HOST": o.pollingLimitPerHost,
"POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit, "POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
"POLLING_SCHEDULER": o.pollingScheduler, "POLLING_SCHEDULER": o.pollingScheduler,
"MEDIA_PROXY_HTTP_CLIENT_TIMEOUT": o.mediaProxyHTTPClientTimeout, "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT": int(o.mediaProxyHTTPClientTimeout.Seconds()),
"MEDIA_PROXY_RESOURCE_TYPES": o.mediaProxyResourceTypes, "MEDIA_PROXY_RESOURCE_TYPES": o.mediaProxyResourceTypes,
"MEDIA_PROXY_MODE": o.mediaProxyMode, "MEDIA_PROXY_MODE": o.mediaProxyMode,
"MEDIA_PROXY_PRIVATE_KEY": mediaProxyPrivateKeyValue, "MEDIA_PROXY_PRIVATE_KEY": mediaProxyPrivateKeyValue,

View file

@ -161,7 +161,7 @@ func (p *parser) parseLines(lines []string) (err error) {
case "SCHEDULER_ROUND_ROBIN_MAX_INTERVAL": case "SCHEDULER_ROUND_ROBIN_MAX_INTERVAL":
p.opts.schedulerRoundRobinMaxInterval = parseInterval(value, time.Minute, defaultSchedulerRoundRobinMaxInterval) p.opts.schedulerRoundRobinMaxInterval = parseInterval(value, time.Minute, defaultSchedulerRoundRobinMaxInterval)
case "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT": case "MEDIA_PROXY_HTTP_CLIENT_TIMEOUT":
p.opts.mediaProxyHTTPClientTimeout = parseInt(value, defaultMediaProxyHTTPClientTimeout) p.opts.mediaProxyHTTPClientTimeout = parseInterval(value, time.Second, defaultMediaProxyHTTPClientTimeout)
case "MEDIA_PROXY_MODE": case "MEDIA_PROXY_MODE":
p.opts.mediaProxyMode = parseString(value, defaultMediaProxyMode) p.opts.mediaProxyMode = parseString(value, defaultMediaProxyMode)
case "MEDIA_PROXY_RESOURCE_TYPES": case "MEDIA_PROXY_RESOURCE_TYPES":
@ -206,7 +206,7 @@ func (p *parser) parseLines(lines []string) (err error) {
case "DISABLE_LOCAL_AUTH": case "DISABLE_LOCAL_AUTH":
p.opts.disableLocalAuth = parseBool(value, defaultDisableLocalAuth) p.opts.disableLocalAuth = parseBool(value, defaultDisableLocalAuth)
case "HTTP_CLIENT_TIMEOUT": case "HTTP_CLIENT_TIMEOUT":
p.opts.httpClientTimeout = parseInt(value, defaultHTTPClientTimeout) p.opts.httpClientTimeout = parseInterval(value, time.Second, defaultHTTPClientTimeout)
case "HTTP_CLIENT_MAX_BODY_SIZE": case "HTTP_CLIENT_MAX_BODY_SIZE":
p.opts.httpClientMaxBodySize = int64(parseInt(value, defaultHTTPClientMaxBodySize) * 1024 * 1024) p.opts.httpClientMaxBodySize = int64(parseInt(value, defaultHTTPClientMaxBodySize) * 1024 * 1024)
case "HTTP_CLIENT_PROXY": case "HTTP_CLIENT_PROXY":

View file

@ -18,14 +18,14 @@ import (
) )
const ( const (
defaultHTTPClientTimeout = 20 defaultHTTPClientTimeout = 20 * time.Second
defaultAcceptHeader = "application/xml, application/atom+xml, application/rss+xml, application/rdf+xml, application/feed+json, text/html, */*;q=0.9" defaultAcceptHeader = "application/xml, application/atom+xml, application/rss+xml, application/rdf+xml, application/feed+json, text/html, */*;q=0.9"
) )
type RequestBuilder struct { type RequestBuilder struct {
headers http.Header headers http.Header
clientProxyURL *url.URL clientProxyURL *url.URL
clientTimeout int clientTimeout time.Duration
useClientProxy bool useClientProxy bool
withoutRedirects bool withoutRedirects bool
ignoreTLSErrors bool ignoreTLSErrors bool
@ -104,7 +104,7 @@ func (r *RequestBuilder) WithCustomFeedProxyURL(proxyURL string) *RequestBuilder
return r return r
} }
func (r *RequestBuilder) WithTimeout(timeout int) *RequestBuilder { func (r *RequestBuilder) WithTimeout(timeout time.Duration) *RequestBuilder {
r.clientTimeout = timeout r.clientTimeout = timeout
return r return r
} }
@ -185,7 +185,7 @@ func (r *RequestBuilder) ExecuteRequest(requestURL string) (*http.Response, erro
} }
client := &http.Client{ client := &http.Client{
Timeout: time.Duration(r.clientTimeout) * time.Second, Timeout: r.clientTimeout,
} }
if r.withoutRedirects { if r.withoutRedirects {

View file

@ -232,9 +232,9 @@ func TestRequestBuilder_CustomAcceptHeaderNotOverridden(t *testing.T) {
func TestRequestBuilder_WithTimeout(t *testing.T) { func TestRequestBuilder_WithTimeout(t *testing.T) {
builder := NewRequestBuilder() builder := NewRequestBuilder()
builder = builder.WithTimeout(30) builder = builder.WithTimeout(30 * time.Second)
if builder.clientTimeout != 30 { if builder.clientTimeout != 30*time.Second {
t.Errorf("Expected timeout to be 30, got %d", builder.clientTimeout) t.Errorf("Expected timeout to be 30, got %d", builder.clientTimeout)
} }
} }
@ -382,9 +382,8 @@ func TestRequestBuilder_ChainedMethods(t *testing.T) {
WithUserAgent("TestAgent/1.0", "DefaultAgent/1.0"). WithUserAgent("TestAgent/1.0", "DefaultAgent/1.0").
WithCookie("test=value"). WithCookie("test=value").
WithETag("etag123"). WithETag("etag123").
WithTimeout(10). WithTimeout(10 * time.Second).
ExecuteRequest(server.URL) ExecuteRequest(server.URL)
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %v", err) t.Fatalf("Expected no error, got %v", err)
} }
@ -409,7 +408,7 @@ func TestRequestBuilder_TimeoutConfiguration(t *testing.T) {
builder := NewRequestBuilder() builder := NewRequestBuilder()
start := time.Now() start := time.Now()
_, err := builder.WithTimeout(1).ExecuteRequest(server.URL) _, err := builder.WithTimeout(1 * time.Second).ExecuteRequest(server.URL)
duration := time.Since(start) duration := time.Since(start)
if err == nil { if err == nil {