Skip to content

Commit 055ee78

Browse files
committed
feat: accept X-PEER-ID peer hint for content retrieval
- Parse peer multiaddress from X-PEER-ID and best-effort connect (5s timeout) - Middleware wired into gateway handler; non-blocking on failure - Improves Bitswap fetches and aligns with Pinning Service API “origins”
1 parent d4c535d commit 055ee78

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

handlers.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"runtime"
1010
"strconv"
1111
"strings"
12+
"time"
1213

1314
"github.com/ipfs/boxo/blockstore"
1415
leveldb "github.com/ipfs/go-ds-leveldb"
@@ -393,6 +394,9 @@ func setupGatewayHandler(cfg Config, nd *Node) (http.Handler, error) {
393394
// Add tracing.
394395
handler = withTracingAndDebug(handler, cfg.TracingAuthToken)
395396

397+
// Add peer hint support (X-PEER-ID).
398+
handler = withPeerHint(nd, handler)
399+
396400
return handler, nil
397401
}
398402

@@ -429,6 +433,34 @@ const NoBlockcacheHeader = "Rainbow-No-Blockcache"
429433

430434
type NoBlockcache struct{}
431435

436+
const PeerHintHeader = "X-PEER-ID"
437+
438+
// withPeerHint inspects the request for a Peer hint header and, if present,
439+
// attempts a short, best-effort libp2p connect to the provided multiaddress.
440+
// This increases the likelihood that Bitswap can retrieve content directly
441+
// from the hinted peer even if it is not advertising on DHT/IPNI.
442+
func withPeerHint(nd *Node, next http.Handler) http.Handler {
443+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
444+
if nd != nil && nd.host != nil {
445+
if maStr := r.Header.Get(PeerHintHeader); maStr != "" {
446+
if ai, err := peer.AddrInfoFromString(maStr); err != nil {
447+
goLog.Warnw("Invalid X-PEER-ID header", "value", maStr, "err", err)
448+
} else {
449+
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
450+
defer cancel()
451+
// Best-effort connect; do not fail the request on error.
452+
if err := nd.host.Connect(ctx, *ai); err != nil {
453+
goLog.Debugw("Failed to connect to hinted peer", "peer", ai.ID, "err", err)
454+
} else {
455+
goLog.Debugw("Connected to hinted peer", "peer", ai.ID)
456+
}
457+
}
458+
}
459+
}
460+
next.ServeHTTP(w, r)
461+
})
462+
}
463+
432464
// MutexFractionOption allows to set runtime.SetMutexProfileFraction via HTTP
433465
// using POST request with parameter 'fraction'.
434466
func MutexFractionOption(path string, mux *http.ServeMux) *http.ServeMux {

0 commit comments

Comments
 (0)