From b4bbf2a0109d7e5bd9921424f23bb94f2b7b39f5 Mon Sep 17 00:00:00 2001 From: Joshua Noble Date: Mon, 17 Nov 2025 14:13:30 -0500 Subject: [PATCH 1/2] feat(gateway): add configurable fallback timeout for the gateway handler --- CHANGELOG.md | 2 ++ gateway/handler.go | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1de21e675..0dd406b4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The following emojis are used to highlight certain changes: ### Added +- `gateway`: Added a configurable fallback timeout for the gateway handler, defaulting to 1 hour, overridable via the BOXO_GATEWAY_REQUEST_TIMEOUT environment variable. + ### Changed ### Removed diff --git a/gateway/handler.go b/gateway/handler.go index bc8c5da71..46e2ed41e 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "os" "mime" "net/http" "net/textproto" @@ -42,6 +43,21 @@ var ( noModtime = time.Unix(0, 0) // disables Last-Modified header if passed as modtime ) +// fallbackRequestTimeout defines the hard per-request timeout for the gateway handler. +// It defaults to 1h, but can be overridden via the BOXO_GATEWAY_REQUEST_TIMEOUT env var, +// which accepts Go duration strings (e.g., "90m", "2h", "5400s"). +var fallbackRequestTimeout = time.Hour + +func init() { + if v := os.Getenv("BOXO_GATEWAY_REQUEST_TIMEOUT"); v != "" { + if d, err := time.ParseDuration(v); err == nil && d > 0 { + fallbackRequestTimeout = d + } else { + log.Warnw("invalid BOXO_GATEWAY_REQUEST_TIMEOUT, using default 1h", "value", v, "error", err) + } + } +} + // handler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/) // (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link) type handler struct { @@ -159,7 +175,7 @@ func (i *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer panicHandler(w) // the hour is a hard fallback, we don't expect it to happen, but just in case - ctx, cancel := context.WithTimeout(r.Context(), time.Hour) + ctx, cancel := context.WithTimeout(r.Context(), fallbackRequestTimeout) defer cancel() if withCtxWrap, ok := i.backend.(WithContextHint); ok { From 47941ee045d9ea8fb55e4bf519cf15893d34c65b Mon Sep 17 00:00:00 2001 From: Joshua Noble Date: Mon, 17 Nov 2025 15:01:55 -0500 Subject: [PATCH 2/2] Fix formatting --- gateway/handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/handler.go b/gateway/handler.go index 46e2ed41e..97a4f59fe 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -5,11 +5,11 @@ import ( "errors" "fmt" "io" - "os" "mime" "net/http" "net/textproto" "net/url" + "os" gopath "path" "regexp" "runtime/debug"