Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The following emojis are used to highlight certain changes:
- Configurable routing timeouts: new options `RAINBOW_HTTP_ROUTERS_TIMEOUT` and `RAINBOW_ROUTING_TIMEOUT` (and the similar command-line flags) allow setting timeouts for routing operations. The former does it for delegated http routing requests. The latter specifies a timeout for routing requests.
- Added `BITSWAP_ENABLE_DUPLICATE_BLOCK_STATS`: Controls whether bitswap duplicate block statistics are collected. This is disabled by default since it has a performance impact.
- Allow specifying a DNSLink safelist: `RAINBOW_DNSLINK_GATEWAY_DOMAINS` defines which dnslink domains are allowed to use this gateway.
- ✨ Add support for pin origins via `X-PIN-ORIGINS` request header. Accepts a comma-separated list of IPFS peer multiaddresses; the gateway attempts short, best-effort libp2p connects to accelerate retrieval when peers don’t advertise via DHT/IPNI.

### Changed

Expand Down
49 changes: 49 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"runtime"
"strconv"
"strings"
"time"

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

// Add pin origins support (X-PIN-ORIGINS).
handler = withPinOrigins(nd, handler)

return handler, nil
}

Expand Down Expand Up @@ -429,6 +433,51 @@ const NoBlockcacheHeader = "Rainbow-No-Blockcache"

type NoBlockcache struct{}

const PinOriginsHeader = "X-PIN-ORIGINS"

// withPinOrigins inspects the request for pin origins header(s) and, if present,
// attempts short, best-effort libp2p connects to the provided multiaddresses.
// This increases the likelihood that Bitswap can retrieve content directly
// from the specified origins even if they are not advertising on DHT/IPNI.
func withPinOrigins(nd *Node, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if nd != nil && nd.host != nil {
// Collect all header values and split by comma to support multiple origins.
rawValues := append([]string{}, r.Header.Values(PinOriginsHeader)...)
if len(rawValues) != 0 {
unique := make(map[string]struct{})
for _, v := range rawValues {
for _, part := range strings.Split(v, ",") {
s := strings.TrimSpace(part)
if s == "" {
continue
}
unique[s] = struct{}{}
}
}
for maStr := range unique {
ai, err := peer.AddrInfoFromString(maStr)
if err != nil {
goLog.Warnw("Invalid peer origin value", "value", maStr, "err", err)
continue
}
// Fire-and-forget connects to speed up retrieval; don't block the request path.
go func(ai peer.AddrInfo) {
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
if err := nd.host.Connect(ctx, ai); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 this feels like a hack – forcing connection here ignores routing system and retrieval system (bitswap sessions etc). passing provider hints should likely work in a way where we inject them into routing system, this way these hints are not used when not necessary

goLog.Debugw("Failed to connect to hinted peer", "peer", ai.ID, "err", err)
return
}
goLog.Debugw("Connected to hinted peer", "peer", ai.ID)
}(*ai)
}
}
}
next.ServeHTTP(w, r)
})
}

// MutexFractionOption allows to set runtime.SetMutexProfileFraction via HTTP
// using POST request with parameter 'fraction'.
func MutexFractionOption(path string, mux *http.ServeMux) *http.ServeMux {
Expand Down
Loading