diff --git a/gateway/blocks_backend.go b/gateway/blocks_backend.go index 4faadb206..fe188ae71 100644 --- a/gateway/blocks_backend.go +++ b/gateway/blocks_backend.go @@ -684,6 +684,12 @@ func (bb *BlocksBackend) IsCached(ctx context.Context, p path.Path) bool { return has } +var _ WithContextHint = (*BlocksBackend)(nil) + +func (bb *BlocksBackend) WrapContextForRequest(ctx context.Context) context.Context { + return blockservice.ContextWithSession(ctx, bb.blockService) +} + func (bb *BlocksBackend) ResolvePath(ctx context.Context, path path.ImmutablePath) (ContentPathMetadata, error) { roots, lastSeg, remainder, err := bb.getPathRoots(ctx, path) if err != nil { diff --git a/gateway/gateway.go b/gateway/gateway.go index b2edbf20c..aa0d59f43 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -386,6 +386,14 @@ type IPFSBackend interface { GetDNSLinkRecord(context.Context, string) (path.Path, error) } +// WithContextHint allows an [IPFSBackend] to inject custom [context.Context] configurations. +// This should be considered optional, consumers might only make a best effort attempt at calling WrapContextForRequest on requests. +type WithContextHint interface { + // WrapContextForRequest allows the backend to add request scopped modifications to the context, like debug values or value caches. + // There are no promises on actual usage in consumers. + WrapContextForRequest(context.Context) context.Context +} + // cleanHeaderSet is an helper function that cleans a set of headers by // (1) canonicalizing, (2) de-duplicating and (3) sorting. func cleanHeaderSet(headers []string) []string { diff --git a/gateway/handler.go b/gateway/handler.go index 1299c7e59..38a242d00 100644 --- a/gateway/handler.go +++ b/gateway/handler.go @@ -152,6 +152,11 @@ func (i *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 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) defer cancel() + + if withCtxWrap, ok := i.backend.(WithContextHint); ok { + ctx = withCtxWrap.WrapContextForRequest(ctx) + } + r = r.WithContext(ctx) switch r.Method {