Skip to content

Latest commit

 

History

History
1368 lines (934 loc) · 107 KB

CHANGELOG.md

File metadata and controls

1368 lines (934 loc) · 107 KB

Changelog

All notable changes to this project will be documented in this file.

Note:

Legend

The following emojis are used to highlight certain changes:

  • 🛠 - BREAKING CHANGE. Action is required if you use this functionality.
  • ✨ - Noteworthy change to be aware of.

[Unreleased]

Added

Changed

Removed

Fixed

Security

[v0.43.0]

Important

This is a bug fix release. It carries a minor version bump because the gateway no longer sends the deprecated X-Ipfs-Path header by default, replaced by Ipfs-Uri (IPIP-548). If you still need X-Ipfs-Path, set Config.DeprecatedXIpfsPath and call Headers.WithDeprecatedXIpfsPath before Headers.ApplyCors, and plan a migration to Ipfs-Uri.

Shipyard's IPFS work ends on September 30, 2026. Until then we ship security and bug fix releases if any are absolutely needed and still possible. After that date, no one at Shipyard maintains Boxo. If you depend on Boxo, read the announcement and bring your transition questions to the community forum.

Added

  • ✨ ipld/unixfs: reads of both PBNode field orders are now covered by tests, and a documented low-level opt-in (UnixFSProfile.PBNodeFieldOrder, applied via merkledag.DefaultPBNodeFieldOrder) lets writers that need streaming-friendly blocks encode the Data field before Links per IPIP-550. Off by default and selected by no named profile: UnixFS_v0_2015 and UnixFS_v1_2025 pin the canonical links-first order explicitly, so defaults and existing CIDs are unchanged. Enabling data-first changes the CID of every dag-pb node that has both fields (directories, HAMT shards, multi-chunk file roots), is process-wide (ApplyGlobals affects every merkledag.ProtoNode encoded in the process, not only UnixFS nodes), and re-encodes links-first directories in the new order the next time they are opened through the directory API and stored again (for example MFS directories on their next access). #1212
  • ✨ gateway: responses now include the Ipfs-Uri header with a canonical ipfs:// or ipns:// URI for the requested content path, and expose it via the default Access-Control-Expose-Headers. The header carries the content root in canonical form (base32 CIDv1 for /ipfs/, base36 CIDv1 for cryptographic /ipns/ names, lowercase FQDN for DNSLink) with percent-encoded path segments, so clients get a value that is safe in HTTP field context regardless of bytes in the underlying path. IPIP-548 #1209

Changed

  • 🛠 gateway: the deprecated X-Ipfs-Path response header is no longer sent by default; its value cannot represent all UnixFS file names and it is superseded by Ipfs-Uri. Action required: consumers that read X-Ipfs-Path should migrate to Ipfs-Uri; to restore the legacy header meanwhile, set Config.DeprecatedXIpfsPath and call Headers.WithDeprecatedXIpfsPath before Headers.ApplyCors so it is listed in Access-Control-Expose-Headers again. Even with the flag set, the header is omitted for content paths with bytes that cannot appear in an HTTP field value (Section 5.5 of RFC 9110), such as raw non-ASCII UnixFS file names: gateway-conformance fails a gateway that sends such values, and only Ipfs-Uri carries those paths. IPIP-548 #1209
  • gateway: conformance CI runs gateway-conformance v0.14.0, the first release with the IPIP-548 Ipfs-Uri tests. #1209
  • updated Go in go.mod to 1.26.0
  • upgrade to go-libp2p-kad-dht v0.42.2
  • upgrade to go.opentelemetry.io v1.46.0

Fixed

  • gateway: X-Ipfs-Path values no longer carry bytes that are invalid in an HTTP field value (Section 5.5 of RFC 9110). The header used to echo raw UnixFS file names, so non-ASCII paths arrived garbled or broke strict clients; when the header is enabled, it is now omitted for such paths, which only the percent-encoded Ipfs-Uri can carry. #1209
  • bootstrap: the saved backup peer list is no longer dialed when no bootstrap peers are configured. #1213

[v0.42.2]

Added

  • bitswap/network/httpnet: DefaultConnectFailureBackoff constant, the wait before Connect re-probes an endpoint after a failed probe.
  • bitswap/network/httpnet: CooldownTracker type with NewCooldownTracker, SharedCooldownTracker and the WithCooldownTracker option, for controlling where per-host backoff state lives.

Changed

  • ✨ bitswap/network/httpnet: removed the background ping loop that probed every connected HTTP peer with GET/HEAD /ipfs/bafkqaaa every 5 seconds for the lifetime of the process (old: fixed 5s cadence per peer, results discarded; new: no periodic probes). Idle HTTP peers generate no background traffic.
  • bitswap/network/httpnet: latency to HTTP peers is measured from the Connect probe and from real retrieval responses instead of periodic pings.
  • bitswap/network/httpnet: Connect and Ping honor per-host cooldowns; after a failed endpoint probe, Connect does not re-probe the host until Retry-After (when provided) or DefaultConnectFailureBackoff elapses (old: no backoff, re-probe on every call).
  • bitswap/network/httpnet: per-host cooldowns live in a process-wide registry (SharedCooldownTracker) so backoff deadlines survive short-lived Network instances (old: per-instance state, forgotten on every restart); Network.Stop no longer stops the registry, and WithCooldownTracker gives a Network a private one.

Removed

  • bitswap/network/httpnet: HTTP 410 is no longer accepted as a successful answer to the connection probe; it was a workaround for a provider that has since shut down. 410 on real block requests still counts as a valid "content unavailable" reply.

Fixed

  • bitswap/network/httpnet: message senders created while a host was in cooldown no longer treat that cooldown as permanent; the request path resumes once the cooldown expires.
  • bitswap/network/bsnet: peers already connected when Bitswap starts are now recognised. libp2p only reports connections opened after a notifier is registered, so a peer connected during node startup stayed invisible to Bitswap for the life of that connection, and no want was ever sent to it. Nodes with another way to find content usually masked this; nodes relying on an already-connected peer could wait forever.

[v0.42.1]

Added

  • gateway: added WithMaxTraversalDepth. It limits how deep BlocksBackend descends into a DAG while it serves a CAR response. Traversal keeps per-level state, so its cost grows with depth. The limit is on by default at DefaultMaxTraversalDepth (1024), well above anything UnixFS produces. A file reaches terabytes by depth 4, and a HAMT adds about 4 levels per million directory entries. Pass a positive value to set your own limit, or WithMaxTraversalDepth(0) to remove the limit. #1197

Changed

  • gateway: a CAR response that fails partway through now ends with [Gateway Error: CAR stream truncated, response is incomplete]. withRetrievalTimeout already uses the same marker when it cuts a response short. The gateway sets X-Stream-Error only once the body is streaming, so that header rarely reaches the client. A truncated CAR was otherwise indistinguishable from a complete one. The marker makes the trailing bytes invalid CAR, so a reader stops with an error instead of accepting a short DAG. This mostly helps operators. Gateways usually sit behind reverse proxies and third-party CDNs, so a short response leaves you guessing which hop cut it. Now the response says so itself. #1197
  • routing/http/server: /routing/v1 responses no longer let a cache serve a two-day-old answer while the origin is healthy. Peer addresses in routing results come from short-lived sources such as relay reservations. A stale window measured in days handed clients addresses that had stopped working long ago. stale-while-revalidate is now 10 minutes for responses with results, and 1 minute for empty ones. That covers a background refresh. stale-if-error applies only when the origin is failing, so responses with results keep the 48h Amino DHT expiration window. For empty responses it is 1 hour. max-age is unchanged. #1195
  • upgrade to go-libp2p v0.49.0

Fixed

  • bitswap/network: ExtractHTTPAddress now brackets an IPv6 literal when it builds the provider URL. A peer that announces /ip6/<addr>/tcp/443/tls/http is now usable as an HTTP provider. Without brackets, url.Parse rejected the address under Go 1.26 and later, and the peer was skipped. On earlier versions it parsed, but the authority split at the last colon, so the client dialed a host and port that do not exist. #1196

Security

[v0.42.0]

Added

  • namesys: DNSLink lookups now return the DNS TXT record's TTL, and the gateway uses it as Cache-Control: max-age for /ipns/<dnslink-host> responses. Clients cache a DNSLink website for exactly as long as its DNS record allows and fetch updates once it expires, instead of relying on a static default. #329
    • Requires a resolver that reports TTLs, such as DNS-over-HTTPS via go-doh-resolver v0.6.0. The OS resolver cannot report TTLs: Go's standard library net.Resolver returns only record values, and libp2p's default DNS wiring (madns.DefaultResolver) wraps it, so domains it serves keep the old behavior. In Kubo, a DNS.Resolvers entry for . covers all domains.
    • WithDNSResolver detects TTL support automatically. NewDNSResolverWithTTL, WithDNSResolverWithTTL, and LookupTXTWithTTLFunc take a TTL-aware lookup directly. NewDNSResolver and LookupTXTFunc are unchanged and report an unknown TTL (0).
  • gateway: GET/HEAD /ipfs/bafkqaaa?format=raw now always returns 200 with an empty body, so probing clients keep marking the gateway as functional even when its backend cannot serve identity CIDs. bitswap/network/httpnet sends this trustless gateway probe to check providers, and a failed probe drops the provider. Exported as gateway.EmptyIdentityCID. #1179
  • path: added NewPathFromURI, which accepts native IPFS URIs (ipfs://cid, ipns://name, ipld://cid, and the schemeless ipfs:/ipns:/ipld: forms) and rewrites them to canonical content paths, so values copied from browsers and other tools parse as-is. NewPath stays strict and still rejects URI-shaped input, leaving untrusted parsing such as DNSLink records unchanged. #1182
  • blockstore: CachedBlockstore now returns a value implementing the exported BloomCacheStatus interface (Wait/BloomActive/Rebuild) when a Bloom filter is configured, so callers can wait for and observe the result of the asynchronous filter build (previously these methods were unreachable on the unexported cache type), and retry a failed build with Rebuild. While a rebuild runs the filter is inactive (lookups fall through to the underlying blockstore, so results stay correct but unaccelerated) and it is activated again only on a complete enumeration. A new optional AllKeysChanWithErrer capability lets a Blockstore report an error that truncates AllKeysChan enumeration. #1184
  • mfs: added WithFetchTimeout, a time limit on how long MFS waits when it has to fetch part of a tree from the network. MFS can hold a tree whose contents are pulled in on demand, for example a reference made with ipfs files cp /ipfs/<cid>. If a needed part is unavailable, MFS would otherwise wait for it forever, freezing every MFS operation and blocking a clean shutdown; with a timeout the wait ends in an error instead. On by default at a generous DefaultFetchTimeout (5 minutes) that only affects unreachable data; pass WithFetchTimeout(0) to disable. #1185

Changed

  • namesys: a name that resolves through several hops (a DNSLink pointing at an IPNS name, or an IPNS chain) now uses the shortest TTL among them, so an update to any link in the chain reaches clients on time. Hops with an unknown TTL (0) are ignored; single-hop results are unchanged. #329
  • namesys: TTLs in results now respect the operator's cap. WithMaxCacheTTL (in Kubo: Ipns.MaxCacheTTL) bounds the reported TTL, so Cache-Control: max-age never promises freshness past it. Cached results report their remaining lifetime instead of the original TTL, so a late cache hit no longer restarts the full caching period on clients. A cap of 0 still means "no local cache" and leaves the reported TTL alone. #329
  • upgrade to go-multiaddr-dns v0.6.0 and go-doh-resolver v0.6.0, which add DNS TXT TTL reporting and turn on the DNSLink Cache-Control behavior above for DoH-backed setups.
  • 🛠 mfs: File.Open now takes a context.Context. Writing to a file whose data has to be fetched from the network (for example, a lazy reference created with ipfs files cp) now uses that context, so the write stops when the context is cancelled, such as on a client timeout or when MFS shuts down, instead of waiting forever for a block that never arrives. Callers must add a context argument; pass the request's context to let a timeout cancel the write. #1185
  • 🧪 testing: tests now use go-test v0.4.0 and math/rand/v2. go-test/random no longer has a global seed or a global sequence, so one test can no longer change the values another test expects to generate deterministically, a class of failure that showed up as an intermittent break in an unrelated test. A generator can also be reused now, instead of being rebuilt for every value. #1187
  • 🛠 routing/offline: the offline router now stores value records in the same datastore layout as the go-libp2p-kad-dht value store (v0.42.0+), so a node sharing one datastore between the offline router and a DHT resolves records offline that were published online and vice versa. That interop previously relied on both sides coincidentally using the same key derivation, which the kad-dht v0.42.0 layout change broke. Records written in the old layout (root-level base32 keys) are no longer read; GetValue also returns routing.ErrNotFound instead of leaking datastore.ErrNotFound for missing records, and re-validates stored records on read so expired records (e.g. IPNS past its EOL) are no longer returned. By default a stored record is served until it stops being valid (for IPNS, its EOL), unchanged from before; the new WithMaxRecordAge option adds an optional store-age cap. Retention also depends on what else uses the datastore: when a go-libp2p-kad-dht instance shares it (via dht.ValueDatastore), that DHT's value store drops records older than amino.DefaultMaxRecordAge on read and sweeps them in the background, regardless of this router's setting. So a node that also runs a DHT follows the DHT's age cap, while an offline-only node keeps records until their EOL. #1189
  • upgrade to go-libp2p-kad-dht v0.42.1, which includes a local record validation fix #1189
  • upgrade to go-unixfsnode v1.10.5
  • upgrade to go-cid v0.6.2
  • upgrade to go-libp2p v0.48.1-0.20260709142922-ec408fcc60c9 to get security and other fixes.

Removed

  • 🛠 util: removed the deprecated NewSeededRand and NewTimeSeededRand. Use go-test/random instead. #1187
  • Remove dependency on whyrusleeping/base32 so that boxo only depends on one base32 package, multiformats/go-base32.

Fixed

  • namesys: a custom sequence number of 0 is now rejected with ErrInvalidSequence also when the name has no existing record, matching the documented behavior that an explicitly supplied sequence must be at least 1.
  • gateway: 304 Not Modified responses to If-None-Match and If-Modified-Since now carry Etag and the Cache-Control their 200 counterpart sends, so a client cache renews its freshness window when it revalidates. A bare 304 left the stored response expired, forcing a revalidation round-trip on every request after the first expiry even when the gateway had just confirmed the content is unchanged. Together with the DNSLink TTL work above, this addresses #329 for web content; CAR and IPNS-record downloads keep their format-specific Etag handling.
  • gateway: fixed a data race in the remote blockstore, CAR fetcher, and value store. Each picked a gateway URL out of its list using a per-instance *rand.Rand, which is not safe to use from more than one goroutine, so a gateway serving requests in parallel was racing on every request. They now use the top-level math/rand/v2 functions, which are safe to share. #1187
  • blockstore: the Bloom filter cache no longer activates after an incomplete build. Previously, if AllKeysChan enumeration was truncated by a mid-iteration datastore error (which was only logged, never propagated) or by a cancelled context, the cache treated the closed channel as a complete build and activated a Bloom filter holding only a subset of the stored CIDs. It then answered "not present" conclusively for blocks that exist but were never indexed, reporting present blocks as missing (Has returns false, Get/GetSize/View return not-found, DeleteBlock becomes a silent no-op). The build now activates the filter only when enumeration is known to have completed; otherwise it records the error (observable via BloomCacheStatus.Wait) and the cache degrades to correct pass-through. This also fixes a race where a cancelled build could still mark the filter active. #1183

Security

  • go-libp2p update contains security enhancements for DoS/hardening
    • 3501 bounds protocols accepted per peer in identify (a peer could plant 1800+ protocol entries in your peerstore via chunked identify)
    • 3486 caps unconnected addrs per peer (stops DHT gossip flooding the peerstore with stale addrs; relevant to us)
    • 3500 caps webrtc remote addrs per ufrag
    • 3487 evicts stale certified addrs when a newer signed peer record drops them (an address a peer once advertised no longer lingers after removal)

[v0.41.0]

Added

  • ipld/merkledag/traverse: added the Visited interface and Options.Visited field, so callers can plug in their own set for skipping duplicates when SkipDuplicates is on. *go-cid.Set already works as one; a bounded or disk-backed set keeps memory low on very large DAGs.

Changed

Fixed

  • routing/http/server: GET /routing/v1/ipns/{name} no longer gives a cache a window that outlasts the record. It caps max-age to the record's remaining validity and sizes the stale window (stale-while-revalidate/stale-if-error) to the time left after it, so the two never cross the record's EOL. An expired record, or one whose ValidityType is not EOL (unknown expiration), returns Cache-Control: no-store, and a negative TTL no longer yields a negative max-age. #1166
  • gateway: serving a raw IPNS record (GET /ipns/{name}?format=ipns-record) now caps max-age to the record's remaining validity and never lets it go negative, so a cache cannot reuse the record past its EOL. #1166
  • namesys: the IPNS resolver now floors a negative record TTL at zero, so a malformed record can no longer surface a negative TTL through Result.TTL. #1166
  • namesys: a cache hit now reports the TTL remaining in the cache entry rather than the record's original TTL, so a late hit near a record's EOL can no longer advertise a freshness lifetime that outlives the record. #1166
  • ipns: NewRecord floors a negative TTL at zero and Validate rejects records carrying one. #1166
  • bitswap/network/bsnet: stop marking a peer unresponsive on a single failed send attempt. send() is retried by multiAttempt(), which already marks the peer once all retries are exhausted; marking on the first failure could permanently sideline a peer that had just reconnected (the disconnect notification being suppressed), hanging fetches from it until it fully disconnected. #1164

Security

  • tracing: bumped OpenTelemetry OTLP exporters to v1.43.0, which caps the HTTP exporter's response body at 4 MiB. A hostile or man-in-the-middle collector could otherwise exhaust its memory (CVE-2026-39882). The gRPC exporter is unaffected.

[v0.40.0]

Added

  • retrieval: added State.Snapshot, State.Apply, and State.Notify so consumers can stream State across a process boundary, e.g. to drive a live progress bar in Kubo's cat, get, or dag export. #1153
  • 🛠 pinning/pinner: added Pinner.Close() error. Close cancels every in-flight operation's context, including streaming goroutines from RecursiveKeys, DirectKeys, and InternalPins, and waits for them to return. A scalar method that observes the cancellation may return context.Canceled; a stream interrupted by Close may surface ErrClosed on the channel before it closes. After Close returns, every other method returns the new ErrClosed sentinel; streaming methods deliver it as StreamedPin.Err on a single entry, then close the channel. Close is idempotent and goroutine-safe. Action required: downstream Pinner implementations must add Close. #1150
  • pinning/pinner/dspinner: implements Close. Close cancels the contexts of in-flight operations, so snapshot iteration in RecursiveKeys/DirectKeys and DAG fetches in Pin bail out promptly instead of draining to completion. Close returns as soon as those operations honor their ctx. Hosts owning the datastore should call Close on the pinner before closing the datastore to avoid the use-after-close panic path in stores such as pebble. #1150
  • routing/http/types/iter: added Limit, an iterator that caps another iterator at a fixed number of values. #1157
  • routing/providerquerymanager: new WithFindPeerFallback option. When set, a one-shot FindPeer fallback runs if the first dial to a provider fails; the manager retries the dial with the fresh AddrInfo, but only if FindPeer surfaced at least one address that wasn't already in the routing-record set just tried. Rescues providers whose routing-record snapshot is thin or stale but whose actual addresses are still reachable, without wasting a retry on a duplicate address set. Disabled by default; pass WithFindPeerFallback(myDHT) to enable.

Changed

  • upgrade to go-libp2p-kad-dht v0.40.0

  • 🛠 files: the File interface no longer embeds io.Seeker. Seekability is now explicit in the type system instead of implied by an always-present Seek method that returned ErrNotSupported at runtime for non-seekable inputs. Callers that need to seek type-assert to io.Seeker; the assertion is an honest capability check rather than a guess. Seekable implementations (ReaderFile wrapping a seekable reader, Symlink, UnixFS files returned from the gateway and importer) still satisfy the assertion. Non-seekable implementations (HTTP multipart streams, WebFile) now fail the assertion at compile-aware sites instead of producing runtime errors deep in third-party code. The previous behavior forced downstream workarounds: e.g. ipfs/kubo#11253 had to wrap files.File in a plain io.Reader/io.Closer to strip Seek and force go-car's forward-only fallback, because go-car's NewBlockReader trusted the interface and called Seek, which failed with "operation not supported" on CARv2 imports over the HTTP API. With this change the trap stops existing.

    Action required. Replace direct Seek calls on files.File with a type assertion:

    // before
    n, err := f.Seek(offset, io.SeekStart)
    
    // after
    seeker, ok := f.(io.Seeker)
    if !ok {
        return fmt.Errorf("file does not support seeking")
    }
    n, err := seeker.Seek(offset, io.SeekStart)

    See ipfs/kubo#11254 for a worked example of the call-site update. #1128

  • ✨ routing/http/server: the Delegated Routing server now passes limit=0 (unbounded) to DelegatedRouter.FindProviders/FindPeers and applies the configured records limit itself, after filtering. Filtered requests now return a full page of results instead of fewer than requested. The server reads the delegate's iterator lazily and closes it once it has enough records. Action required: delegate implementations should return results lazily and stop work on Close. A delegate that previously used the limit argument to end its walk early should now end the walk on Close instead. #1157

  • path/resolver: ResolveToLastNode, ResolvePath, and ResolvePathComponents now populate retrieval.State on the request context when one is attached. They advance the state to PhasePathResolution, record the root CID from the input path, and record the terminal CID once resolution completes. Until now only the gateway backends populated these fields, leaving non-gateway callers (CLIs, custom tools) without phase or CID diagnostics on retrieval errors. The new calls are idempotent with the existing gateway-side ones, so behavior on the gateway path is unchanged.

Fixed

  • files: now builds under GOOS=js GOARCH=wasm and GOOS=wasip1 GOARCH=wasm. #935
  • routing/http/server: filtered /routing/v1/providers and /routing/v1/peers requests now return up to the configured records limit. Previously the limit was applied before filter-addrs/filter-protocols ran, so records dropped by the filters shrank the response below the limit. The limit now applies after filtering. #1157
  • routing/http/types/iter: Filter.Next now iterates instead of recursing on rejected values, so the goroutine stack stays flat even when a long run of records is filtered out. This matters now that the server pulls unbounded results from the delegate. #1157

[v0.39.0]

Added

  • gateway: Config.MaxDeserializedResponseSize allows setting a maximum file/directory size for deserialized gateway responses. Content exceeding this limit returns 410 Gone, directing users to run their own IPFS node. Trustless response formats (application/vnd.ipld.raw, application/vnd.ipld.car) are not affected. The size is read from the UnixFS root block, so no extra block fetches are needed for the check. #1138
  • gateway: Config.MaxUnixFSDAGResponseSize allows setting a maximum content size applied to all response formats (deserialized, raw blocks, CAR, TAR). Content exceeding this limit returns 410 Gone. For most handlers the check reuses size information already available in the request path; for CAR responses a lightweight Head call is made only when the limit is configured. #1138

Changed

  • bitswap/server: the default peer comparator now schedules peers fairly. A peer that has never been served, or has waited longer than 10s, outranks non-starved peers. Pending counts cap at 16 for ordering purposes, so peers with small wantlists no longer wait behind peers with large ones. The final tiebreak uses a per-process salted hash of peer.ID, so no peer can craft an ID that permanently outranks everyone. Engines built with WithTaskComparator keep their existing behavior. #1141
  • upgrade to go-libp2p-kad-dht v0.39.1

Fixed

  • bitswap/network/bsnet: SendMessage and handleNewStream now close streams in a background goroutine. Previously, stream.Close could hold the caller for up to DefaultNegotiationTimeout (10s) while lazyClientConn.Close waited for the remote peer to complete the multistream handshake. This saturated the bitswap TaskWorkerCount pool when peers were unresponsive and stopped bitswap from serving blocks to other peers. As a side effect, SendMessage no longer returns errors from stream.Close; close failures are logged at Debug. #1142
  • bitswap/server: a peer with a single pending want no longer waits behind peers with large wantlists. #1141
  • pinner/dspinner: RecursiveKeys and DirectKeys now snapshot the pin index under the read lock and release it before emitting pins, so a slow consumer (e.g. the reprovider draining the channel at DHT speed under Provide.Strategy=pinned*) can no longer starve Pin/Unpin/Flush writers. #1140

[v0.38.0]

Added

  • ipns: NewRecord accepts WithMetadata(map[string]any) option for storing custom scalar key-value pairs (string, []byte, int64, int, bool) in the signed DAG-CBOR data of IPNS records. Metadata can be read back via Record.Metadata (returns typed MetadataValue with Kind() discriminator) and iterated with Record.MetadataEntries. Reserved IPNS field names, empty keys, and unsupported value types are rejected. #1085
  • dag/walker: new package for memory-efficient DAG traversal with deduplication. VisitedTracker interface with BloomTracker (scalable bloom filter chain, ~4 bytes/CID vs ~75 bytes for a map) and MapTracker (exact, for tests). WalkDAG provides iterative DFS traversal with integrated dedup, supporting dag-pb, dag-cbor, raw, and other registered codecs. ~2x faster than the legacy go-ipld-prime selector-based traversal. WalkEntityRoots emits only entity roots (files, directories, HAMT shards) instead of every block, skipping internal file chunks. #1124
  • pinner: NewUniquePinnedProvider and NewPinnedEntityRootsProvider log and skip corrupted pin entries instead of aborting the provide cycle, allowing remaining pins to still be provided. #1124
  • routing/http/client: WithProviderInfoFunc option resolves provider addresses at provide-time instead of client construction time. This only impacts legacy HTTP-only custom routing setups that depend on IPIP-526 and were sending unresolved 0.0.0.0 addresses in provider records instead of actual interface addresses. #1115
  • chunker: added Register function to allow custom chunkers to be registered for use with FromString.
  • mfs: added Directory.Mode() and Directory.ModTime() getters to match the existing File.Mode() and File.ModTime() API. #1131

Changed

  • provider: NewPrioritizedProvider now continues to the next stream when one fails instead of stopping all streams. NewConcatProvider added for pre-deduplicated streams. #1124
  • chunker: FromString now rejects malformed size- strings with extra parameters (e.g. size-123-extra was previously silently accepted).
  • gateway: compliance with gateway-conformance v0.13
  • upgrade to go-libp2p v0.48.0
  • 🛠 mfs: replaced RootOption with a unified Option functional options pattern (e.g. WithCidBuilder, WithChunker, WithMaxLinks). NewRoot, NewEmptyRoot, MkdirWithOpts, and NewEmptyDirectory now accept ...Option. Mkdir takes a MkdirOpts struct (narrowed to Mkparents and Flush flags) followed by ...Option for directory configuration. #1125

Removed

  • gateway: removed dead DoH resolver for .crypto TLD (Unstoppable Domains) #772
  • cmd/boxo-migrate: removed code for go-ipfs migration -- no longer needed.
  • cmd/deprecator: removed code to deprecare relocated ipfs packages -- no longer needed.

Fixed

  • bitswap/server: incoming identity CIDs in wantlist messages are now silently ignored instead of killing the connection to the remote peer. Some IPFS implementations naively send identity CIDs, and disconnecting them for it caused unnecessary churn. #1117
  • bitswap/network: ExtractHTTPAddress now infers default ports for portless HTTP multiaddrs (e.g. /dns/host/https without /tcp/443). #1123
  • mfs: FileDescriptor operations are serialized with a mutex, preventing data races on the underlying DagModifier when FUSE mounts or Kubo RPC commands dispatch concurrent Read, Write, Seek, Truncate, Flush, or Close calls. Flush after Close returns ErrClosed. #1131 #1133
  • mfs: preserve CidBuilder and SizeEstimationMode across setNodeData(), Mkdir() and NewRoot(). #1125
  • mfs: closing a file descriptor after its directory entry was removed (e.g. FUSE RELEASE racing with RENAME) no longer re-adds the stale entry to the parent directory. #1134
  • mfs: SetMode and SetModTime no longer drop file content links when updating UnixFS metadata. #1134

[v0.37.0]

Added

  • ipld/unixfs/io: added SizeEstimationMode for configurable HAMT sharding threshold decisions. Supports legacy link-based estimation (SizeEstimationLinks), accurate block-based estimation (SizeEstimationBlock), or disabling size-based thresholds (SizeEstimationDisabled). #1088, IPIP-499
  • ipld/unixfs/io: added UnixFSProfile with UnixFS_v0_2015 and UnixFS_v1_2025 presets for CID-deterministic file and directory DAG construction. #1088, IPIP-499
  • files: NewSerialFileWithOptions now supports controlling whether symlinks are preserved or dereferenced before being added to IPFS. See SerialFileOptions.DereferenceSymlinks. #1088, IPIP-499

Changed

  • 🛠 chunker, ipld/unixfs/importer/helpers: block size limits raised from 1MiB to 2MiB to match the bitswap spec. Max chunker size is 2MiB - 256 bytes to leave room for protobuf framing when --raw-leaves=false. IPIP-499 profiles use lower chunk sizes (256KiB and 1MiB) and are not affected.
  • 🛠 chunker: DefaultBlockSize changed from const to var to allow runtime configuration via global profiles. #1088, IPIP-499
  • gateway: 🛠 ✨ IPIP-523 ?format= URL query parameter now takes precedence over Accept HTTP header, ensuring deterministic HTTP cache behavior and allowing browsers to use ?format= even when they send Accept headers with specific content types. #1074
  • gateway: 🛠 ✨ IPIP-524 codec conversions (e.g., dag-pb to dag-json, dag-json to dag-cbor) are no longer performed by default. Requesting a format that differs from the block's codec now returns HTTP 406 Not Acceptable with a hint to fetch raw blocks (?format=raw) and convert client-side. Set Config.AllowCodecConversion to true to restore the old behavior. #1077
  • gateway: compliance with gateway-conformance v0.10.0 (since v0.8: relaxed DAG-CBOR HTML preview cache headers, relaxed CAR 200/404 for missing paths, IPIP-523 format query precedence, IPIP-524 codec mismatch returns 406)
  • upgrade to go-ipld-prime v0.22.0
  • upgrade to go-libp2p-kad-dht v0.38.0

Removed

  • tracing: opentelemetry zipkin exporter (go.opentelemetry.io/otel/exporters/zipkin) is deprecated and has been removed. It is recommended to switch to OTLP. Configure your application to send traces using OTLP and enable Zipkin’s OTLP ingestion support.

Fixed

  • 🛠 ipld/unixfs/io: fixed HAMT sharding threshold comparison to use > instead of >=. A directory exactly at the threshold now stays as a basic (flat) directory, aligning behavior with code documentation and the JS implementation. This is a theoretical breaking change, but unlikely to impact real-world users as it requires a directory to be exactly at the threshold boundary. If you depend on the old behavior, adjust HAMTShardingSize to be 1 byte lower. #1088, IPIP-499
  • ipld/unixfs/mod: fixed sparse file writes in MFS. Writing past the end of a file (e.g., ipfs files write --offset 1000 /file on a smaller file) would lose data because expandSparse created the zero-padding node but didn't update the internal pointer. Subsequent writes went to the old unexpanded node.
  • ipld/unixfs/io: fixed mode/mtime metadata loss during Basic<->HAMT directory conversions. Previously, directories with WithStat(mode, mtime) would lose this metadata when converting between basic and sharded formats, or when reloading a HAMT directory from disk.

[v0.36.0]

Added

  • routing/http: GET /routing/v1/dht/closest/peers/{key} per IPIP-476
  • ipld/merkledag: Added fetched node size reporting to the progress tracker. See kubo#8915
  • gateway: Added a configurable fallback timeout for the gateway handler, defaulting to 1 hour. Configurable via MaxRequestDuration in the gateway config.

Changed

  • keystore: improve error messages and include key file name #1080
  • upgrade to go-libp2p-kad-dht v0.37.1
  • upgrade to go-libp2p v0.47.0

Fixed

  • bitswap/network: Fixed goroutine leak that could cause bitswap to stop serving blocks after extended uptime. The root cause is stream.Close() blocking indefinitely when remote peers are unresponsive during multistream handshake (go-libp2p#3448). This PR (#1083) adds a localized fix specific to bitswap's SendMessage by setting a read deadline before closing streams.

[v0.35.2]

Changed

  • upgrade to go-libp2p v0.45.0
  • upgrade to go-log/v2 v2.9.0
    • Applications using go-log (>=2.9)+go-libp2p(>=0.45) may need to initialize their application to bridge slog-based libraries to into go-log. See documentation for go-log release and slog integration.

[v0.35.1]

Added

  • new span for the handleIncoming bitswap client getter plus events when blocks are received.
  • mark opentelemetry spans, span attributes, and span events as being used by ProbeLab's analysis scripts

Changed

  • upgrade to go-dsqueue v0.1.0 - Fixes batch reuse that could cause panic.

Fixed

  • gateway: Fixed duplicate peer IDs appearing in retrieval timeout error messages
  • bitswap/client: fix tracing by using context to pass trace and retrieval state to session #1059
    • bitswap/client: propagate trace state when calling GetBlocks #1060
  • bitswap/network/httpnet: improved error detection on HTTP and block fetches:
    • Do not attempt to GET a test CID if the endpoint returns 429 to the test HEAD request.
    • Unify error parsing and handling of http statues and content.

[v0.35.0]

Added

  • pinning/pinner: Added CheckIfPinnedWithType method to Pinner interface for efficient type-specific pin checks with optional name loading (#1035)
    • Enables checking specific pin types (recursive, direct, indirect) without loading all pins
    • Optional includeNames parameter controls whether pin names are loaded from datastore
    • CheckIfPinned now delegates to CheckIfPinnedWithType for consistency
  • gateway: Enhanced error handling and UX for timeouts:
    • Added retrieval state tracking for timeout diagnostics. When retrieval timeouts occur, the error messages now include detailed information about which phase failed (path resolution, provider discovery, connecting, or data retrieval) and provider statistics including failed peer IDs #1015 #1023
    • Added Config.DiagnosticServiceURL to configure a CID retrievability diagnostic service. When set, 504 Gateway Timeout errors show a "Check CID retrievability" button linking to the service with ?cid=<failed-cid> #1023
    • Improved 504 error pages with "Retry" button, diagnostic service integration, and clear indication when timeout occurs on sub-resource vs root CID #1023
  • gateway: Added Config.MaxRangeRequestFileSize to protect against CDN issues with large file range requests. When set to a non-zero value, range requests for files larger than this limit return HTTP 501 Not Implemented with a suggestion to use verifiable block requests (application/vnd.ipld.raw) instead. This provides protection against Cloudflare's issue where range requests for files over 5GiB are silently ignored, causing excess bandwidth consumption and billing

Changed

  • routing/http: ✨ Delegated Routing V1 HTTP endpoints now return 200 with empty results instead of 404 when no records are found, per IPIP-513 (#1024)
    • Server endpoints (/routing/v1/providers/{cid}, /routing/v1/peers/{peer-id}, /routing/v1/ipns/{name}) return HTTP 200 with empty JSON arrays or appropriate content types for empty results
    • Client maintains backward compatibility by treating both 200 with empty results and 404 as "no records found"
    • IPNS endpoint distinguishes between valid records (Content-Type: application/vnd.ipfs.ipns-record) and no record found (any other content type)
  • verifcid: 🛠 Enhanced Allowlist interface with per-hash size limits (#1018)
    • Expanded Allowlist interface with MinDigestSize(code uint64) and MaxDigestSize(code uint64) methods for per-hash function size validation
    • Added public constants: DefaultMinDigestSize (20 bytes), DefaultMaxDigestSize (128 bytes for cryptographic hashes), and DefaultMaxIdentityDigestSize (128 bytes for identity CIDs)
    • DefaultAllowlist implementation now uses these constants and supports different size limits per hash type
    • Renamed errors for clarity: Added ErrDigestTooSmall and ErrDigestTooLarge as the new primary errors
    • ErrBelowMinimumHashLength and ErrAboveMaximumHashLength remain as deprecated aliases pointing to the new errors
  • bitswap: Updated to use verifcid.DefaultMaxDigestSize for MaximumHashLength constant
    • The default MaximumAllowedCid limit for incoming CIDs can be adjusted using bitswap.MaxCidSize or server.MaxCidSize options
  • 🛠 bitswap/client: The RebroadcastDelay option now takes a time.Duration value. This is a potentially BREAKING CHANGE. The time-varying functionality of delay.Delay was never used, so it was replaced with a fixed duration value. This also removes the github.com/ipfs/go-ipfs-delay dependency.
  • filestore: Support providing filestore-blocks. A new provider.MultihashProvider parameter has been added to filestore.New(). When used, the blocks handled by the Filestore's FileManager will be provided on write (Put and PutMany).

Removed

  • provider: Provide() calls are replaced with StartProviding() to benefit from the Reprovide Sweep improvement. See kubo#10834 and kad-dht#1095.- provider: Provide() calls are replaced with StartProviding() to benefit from the Reprovide Sweep improvement. See kubo#10834 and kad-dht#1095.

Fixed

  • routing/http/client:
    • Fixed off-by-one error in routing_http_client_length metric - the metric now correctly reports 0 for empty results instead of 1
    • Added metrics for IPNS operations (GetIPNS and PutIPNS) - these now report latency, status code, and result count (0 or 1 for GetIPNS)
    • Added simple counter metrics to avoid confusing histogram bucket math:
      • routing_http_client_requests_total - total requests including errors
      • routing_http_client_positive_responses_total - requests that returned at least 1 result
  • ipld/unixfs/mod:
    • DagModifier now correctly preserves raw node codec when modifying data under the chunker threshold, instead of incorrectly forcing everything to dag-pb
    • DagModifier prevents creation of identity CIDs exceeding verifcid.DefaultMaxIdentityDigestSize limit when modifying data, automatically switching to proper cryptographic hash while preserving small identity CIDs
    • DagModifier now supports appending data to a RawNode by automatically converting it into a UnixFS file structure where the original RawNode becomes the first leaf block, fixing previously impossible append operations that would fail with "expected protobuf dag node" errors
  • mfs:
    • Files with identity CIDs now properly inherit full CID prefix from parent directories (version, codec, hash type, length), not just hash type (#1018)

Security

  • verifcid: Now enforces maximum size limit of 128 bytes for identity CIDs to prevent abuse (#1018, ipfs/specs#512).
    • 🛠 Attempts to read CIDs with identity multihash digests longer than DefaultMaxIdentityDigestSize will now produce ErrDigestTooLarge error.
    • Identity CIDs can inline data directly, and without a size limit, they could embed arbitrary amounts of data. Limiting the size also protects gateways from poorly written clients that might send absurdly big data to the gateway encoded as identity CIDs only to retrieve it back. Note that identity CIDs do not provide integrity verification, making them vulnerable to bit flips. They should only be used in controlled contexts like raw leaves of a larger DAG. The limit is explicitly defined as DefaultMaxIdentityDigestSize (128 bytes).

[v0.34.0]

Added

  • autoconf: Client library for fetching, caching and expanding IPFS network configurations using "auto" placeholders
  • gateway: Added configurable limits for gateway resource protection:
    • Config.RetrievalTimeout: Maximum duration between writes of non-empty data to HTTP response body (default: 30s). Returns 504 Gateway Timeout when gateway cannot retrieve content within this period.
    • Config.MaxConcurrentRequests: Limits concurrent HTTP requests (default: 4096, suitable for most deployments). Returns 429 Too Many Requests with 60s Retry-After header when exceeded. To restore previous unlimited behavior set both RetrievalTimeout and MaxConcurrentRequests to 0.

      [!IMPORTANT] If your gateway returns many HTTP 429 responses while having available resources (CPU, memory), increase MaxConcurrentRequests. If experiencing high load or resource exhaustion, decrease it. See the MaxConcurrentRequests godoc for detailed tuning guidance.

    • Config.MetricsRegistry: Optional Prometheus registry for metrics isolation. When nil, uses the default global registry. Useful for testing and deployments with multiple gateway instances.
    • New middleware with Prometheus metrics:
      • ipfs_http_gw_concurrent_requests: Gauge tracking number of concurrent requests
      • ipfs_http_gw_responses_total{code}: Counter for all HTTP responses by status code
      • ipfs_http_gw_retrieval_timeouts_total{code,truncated}: Counter for retrieval timeout events with details on truncation
  • namesys/IPNSPublisher: option to PublishOptions that allows for setting a custom sequence number for the IPNS record with proper validation to prevent unintentional replay attacks. #962
  • blockstore: Added ValidatingBlockstore wrapper. This replaces the HashOnRead blockstore API.

Changed

  • bitswap/network: The connection event manager now has a SetListeners method. Both bsnet and httpnet now have options to provide the ConnectionEventManager during New(...). This allows sharing the connection event manager when using both. The connection manager SHOULD be shared when using both networks with the network.Router utility.
  • provider: Distribute the responsability of providing new blocks to the places that play a role in the different providing strategies #976. Refactor the logic to perform Provides, when the component has been given a provider:
    • Remove providing.Exchange
    • Provide directly from Blockstore when provider is set (via Option).
    • Provide directly from pinner/merkledag on dag traversal when provider is set (via Option).
    • Provide from MFS whenever there is a call to DAGService.Add and provider is set (via constructor param).
  • upgrade to go-libp2p v0.43.0
  • replace uber-go/multierr with errors.Join #996
  • updated Go in go.mod to 1.24.0 #999

Removed

  • blockstore: Removed HashOnRead API. This is a potentially BREAKING CHANGE for any users of the HashOnRead API. Use the ValidatingBlocksore instead.
    • The HashOnRead function was also removed from Filestore. To use this functionality, provide a ValidatingBlockstore when creating a new Filestore.

[v0.33.1]

Added

  • provider: Add ability to clear provide queue #978

Changed

  • bitswap/network: The connection event manager now has a SetListeners method. Both bsnet and httpnet now have options to provide the ConnectionEventManager during New(...). This allows sharing the connection event manager when using both. The connection manager SHOULD be shared when using both networks with the network.Router utility.
  • bootstrap: Relay-only peers (with /p2p-circuit/ addresses) are now filtered out when selecting backup bootstrap peers to improve reliability.
  • upgrade to go-libp2p v0.42.1

Fixed

[v0.33.0]

Added

  • bitswap/network/httpnet: New WithMetricsLabelsForEndpoints allows defining which hosts/endpoints can be used for labelling metrics that support such label. '*' enables this for all endpoints receiving HTTP requests, but may cause metric cardinality growth when too many endpoints exist. These labels allow tracking, for example, number or requests per response status AND endpoint used. Non-labelled request hosts are labelled with same value: other.

Changed

  • bitswap/client The bitswap client's traceability.Block is now disabled by default. It is only used for testing an debugging and is not needed for typical operation. Using it costs additional allocation. To enable traceability.Block, use the bitswap client option WithTraceBlock(true).
  • DontHaveTimeoutConfig's default MinTimeout is changed from 0 to 50ms #959 #965.
  • upgrade to go-libp2p v0.42.0

Removed

Fixed

  • bitswap/client: Fix sending extra wants #968 + #975
  • routing/http/client: Improve URL handling for delegated routing endpoints #971

Security

  • fix panic when incoming Bitswap protobuf message does not contain Wantlist #961

[v0.32.0]

Added

  • provider includes metrics on the number of keys provided so far(reprovider_provide_count) and the number of keys reprovided so far (reprovider_reprovide_count) #944
  • bitswap/client: New metrics:
    • ipfs_bitswap_wanthaves_broadcast: Count of want-haves broadcasts
    • ipfs_bitswap_haves_received: Count of total have responses
    • ipfs_bitswap_bcast_skips_total{: Count of broadcasts skipped as part of spam reduction logic (see "Changed" below)
    • ipfs_bitswap_unique_blocks_received: Count of non-duplicate blocks recieved

Changed

  • provider: previously, the code in this module was logging to reprovider.simple, provider.batched and provider.queue facilities. They have now been consolidated in a single provider logging facility, along with some adjustments to logging levels and extra debug statements.
  • bitswap/client: Added an opt-in ability to reduce bitswap broadcast volume by limiting broadcasts to peers that have previously responded as having wanted blocks and peers on local network. The following bitswap client options are available to configure the behavior of broadcast reduction:
    • BroadcastControlEnable enables or disables broadcast reduction logic. Setting this to false restores the previous broadcast behavior of sending broadcasts to all peers, and ignores all other BroadcastControl options. Default is false (disabled).
    • BroadcastControlMaxPeers sets a hard limit on the number of peers to send broadcasts to. A value of 0 means no broadcasts are sent. A value of -1 means there is no limit. Default is -1 (unlimited).
    • BroadcastControlLocalPeers enables or disables broadcast control for peers on the local network. If false, then always broadcast to peers on the local network. If true, apply broadcast control to local peers. Default is false (always broadcast to local peers).
    • BroadcastControlPeeredPeers enables or disables broadcast control for peers configured for peering. If false, then always broadcast to peers configured for peering. If true, apply broadcast control to peered peers. Default is false (always broadcast to peered peers).
    • BroadcastControlMaxRandomPeers sets the number of peers to broadcast to anyway, even though broadcast control logic has determined that they are not broadcast targets. Setting this to a non-zero value ensures at least this number of random peers receives a broadcast. This may be helpful in cases where peers that are not receiving broadcasts may have wanted blocks. Default is 0 (no random broadcasts).
    • BroadcastControlSendToPendingPeers enables or disables sending broadcasts to any peers to which there is a pending message to send. When true (enabled), this sends broadcasts to many more peers, but does so in a way that does not increase the number of separate broadcast messages. There is still the increased cost of the recipients having to process and respond to the broadcasts. Default is false.

Removed

  • bitswap/server do not allow override of peer ledger with WithPeerLedger #938

Fixed

[v0.31.0]

Added

  • bitswap/httpnet: New option WithMaxDontHaveErrors(int) (defaults to 100) will trigger disconnections from bitswap peers that cannot provide any of the blocks that are requested for the given number of requests in a row.. This is meant to limit bitswap HTTP-based optimistic requests for blocks to discovered endpoints, which were before considered permanently peered upon discovery.

Changed

  • upgrade to go-libp2p-kad-dht v0.33.1
  • deprecated WithPeerLedger option for bitswap server. Will remove option in next release. See issue #928
  • gateway: update backend car traversal to use go-car/v2 #925
    • This change may prohibit fetching DAGs from CAR files that have no roots.

[v0.30.0]

Added

  • Control over UnixFS DAG Width
    • We have made some changes to allow setting custom max width of UnixFS DAGs. This enables users to produce DAGs that follow current and future community conventions (see the related discussion).
    • ipld/unixfs: DagModifier now allows specifying file DAG Width (MaxLinks) #898
    • ipld/unixfs/io/directory: We have made some changes to unixfs directory tooling #906
      • We have exposed creator methods for new BasicDirectory and HAMTDirectory, that complement the existing NewDirectory() which creates dynamic directories.
      • We have added WithCidBuilder(...), WithMaxLinks(...), WithMaxHAMTFanout(...) and WithStat(...) as options to these new methods so that empty directories can be initilized as wished from the get-go.
      • WithMaxLinks(...) and WithMaxHAMTFanout(...) are new options that allow to set a limit to the number of children that a directory DAG node can have. For details on what they exactly do for each of the directory type, please check the documentation.
    • mfs supports as well the new MaxLinks and MaxHAMTFanout options. They have been made part of the MkdirOptions object and the methods NewEmptyDirectory() and NewEmptyRoot() have been added to facilitate the initialization of MFS objects. #906
  • provider: added support for walking partial DAGs in offline mode #905
    • a KeyChanFunc that traverses DAGs from a given root (NewDAGProvider).
    • a KeyChanFunc that buffers all the CIDs in memory from another KeyChanFunc (NewBufferedProvider).
    • fetcher/impl/blockservice: new option SkipNotFound for the IPLD fetcher. It will skip not found nodes when traversing the DAG. This allows offline traversal of DAGs when using, for example, an offline blockservice.
    • This enables use case of providing lazy-loaded, partially local DAGs (like ipfs files in Kubo's MFS implementation, see kubo#10386)
  • gateway: generated HTML with UnixFS directory listings now include a button for copying CIDs of child entities #899
  • bitswap/server: Add ability to enable/disable bitswap server using WithServerEnabled bitswap option (#911)[#911]

Changed

  • upgrade to go-libp2p v0.41.1
  • bitswap/network: Add a new requests_in_flight metric gauge that measures how many bitswap streams are being written or read at a given time.
  • improve speed of data onboarding by batching/bufering provider queue writes #888
  • provider: providing queue is now independent from reprovides, speeding up initial provides #907
    • renamed provider.ReproviderStats.TotalProvides => provider.ReproviderStats.TotalReprovides
    • renamed provider.ReproviderStats.AvgProvideDuration => provider.ReproviderStats.AvgReprovideDuration
  • provider/queue deduplicates CIDs #910

Fixed

  • gateway: query parameters are now supported and preserved in redirects triggered by a _redirects file #886
  • provider: adjusted first reprovide timing after node reboot #890
  • gateway: validate configuration and warn when UseSubdomains=true is used with IP-based hostnames #903

[v0.29.1]

Changed

  • bitswap/httpnet: do not follow redirects #878
  • provider: provider helper that buffers results to fix issues with slow re-providing #870

Fixed

  • fix(provider): don't reprovide if reprovideInterval is set to 0 #871
  • gateway: Skip DNSLink lookup for IP addresses to avoid unnecessary DNS queries #880
  • bitswap/client: Fix unintentional ignoring DontHaveTimeoutConfig #872

[v0.29.0]

Added

  • feat(bitswap/client): MinTimeout for DontHaveTimeoutConfig #865
  • ✨ httpnet: Transparent HTTP-block retrieval support over Trustless Gateways [#747]((#747):
    • Complements Bitswap as a block-retrieval mechanism, implementing bitswap/network.
    • Understands peers found in provider records with /.../http endpoints (trustless gateway).
    • Treats them as "Bitswap" peers, except instead of using Bitswap it makes HTTP/2 requests to discover (HEAD) and retrieve (GET) individual blocks (?format=raw).
    • A bitswap/network proxy implementation allows co-existance with standard bitswap/network/bsnet.
    • httpnet is not enabled by default. Upstream implementations may use it by modifying how they create the Bitswap network and initialize bitswap.

Changed

  • ipns: The DefaultRecordTTL changed from 1h to 5m #859
  • upgrade to go-libp2p v0.41.0
  • upgrade to go-libp2p-kad-dht [v0.30.2](github.com/libp2p/go-libp2p-kad-dht v0.30.2)
  • upgrade to go-datastore v0.8.2 - includes API updates and removes go-process
  • bitswap/client reduce lock scope of PeerManageer to help performance #860
  • NewFromIpfsHost() and the rest of the BitSwapNetwork implementation has moved from github.com/ipfs/boxo/bitswap/network to github.com/ipfs/boxo/bitswap/network/bsnet.

Removed

  • Removed dependency on github.com/hashicorp/go-multierror so that boxo only depends on one multi-error package, go.uber.org/multierr. #867

[v0.28.0]

Added

  • bitswap/client: Add DontHaveTimeoutConfig type alias and func DontHaveTimeoutConfig() to expose config defined in internal package.

Changed

  • move ipld/unixfs from gogo protobuf #841
  • provider: Prevent multiple instances of reprovider.Reprovide() from running at the same time. #834
  • upgrade to go-libp2p v0.40.0
  • upgrade to go-libp2p-kad-dht [v0.29.0](github.com/libp2p/go-libp2p-kad-dht v0.29.0)
  • move bitswap and filestore away from gogo protobuf #839
  • updated Go in go.mod to 1.23 #848

Note: This release contains changes to protocol buffer library code. If you depend on deterministic CIDs then please double-check,, before upgrading, that this release does not generate different CIDs.

Removed

Fixed

Security

[v0.27.4]

Fixed

  • Fix memory leaks due to not cleaning up wantlists #829, #833
  • ipns: Improved interop with legacy clients by restoring support for []byte CID in Value field. Value() will convert it to a valid path.Path. Empty Value() will produce NoopPath (/ipfs/bafkqaaa) to avoid breaking existing code that expects a valid record to always produce a valid content path. #830
  • gateway/blocks-backend: Removed IPLD decoding in GetBlock funciton in gateway's BlocksBackend. Now it's querying the blockService directly instead of dagService. #845

[v0.27.3]

Added

  • provider: Added ReprovideInterval and LastRun stats to the Reprovider #815

Removed

  • bitswap/client: Remove unused tracking of CID for interested sessions. #821

Fixed

  • bitswap/client: Fix runaway goroutine creation under high load. Under high load conditions, goroutines are created faster than they can complete and the more goroutines creates the slower them complete. This creates a positive feedback cycle that ends in OOM. The fix dynamically adjusts message send scheduling to avoid the runaway condition. #817
  • bitswap/client: Fix resource leak caused by recording the presence of blocks that no session cares about. #822

[v0.27.2]

Fixed

  • bitswap/client: Reverted attempt to send cancels with excluded peer due to additional issues with wantlist accounting #809

[v0.27.1]

Fixed

  • bitswap/client: Fixed fix sending cancels when excluding peer #805

[v0.27.0]

Added

  • gateway Support for custom DNSLink / DoH resolvers on localhost to simplify integration with non-ICANN DNS systems #645

Changed

  • gateway: The default DNSLink resolver for .eth TLD changed to https://dns.eth.limo/dns-query #781
  • gateway: The default DNSLink resolver for .crypto TLD changed to https://resolver.unstoppable.io/dns-query #782
  • upgrade to go-libp2p-kad-dht v0.28.2
  • bitswap/client: reduce lock scope in messagequeue: lock only needed sections #787
  • upgrade to go-libp2p v0.38.2

Fixed

  • gateway Fix redirect URLs for subdirectories with characters that need escaping. #779
  • ipns Fix ipns protobuf namespace conflicts by using full package name github.com/ipfs/boxo/ipns/pb/record.proto instead of the generic record.proto #794
  • unixfs Fix possible crash when modifying directory #798

[v0.26.0]

Added

  • bitswap/client: Improved timeout configuration for block requests
    • Exposed DontHaveTimeoutConfig to hold configuration values for dontHaveTimeoutMgr which controls how long to wait for requested block before emitting a synthetic DontHave response
    • Added DefaultDontHaveTimeoutConfig() to return a DontHaveTimeoutConfig populated with default values
    • Added optional WithDontHaveTimeoutConfig to allow passing a custom DontHaveTimeoutConfig
    • Setting SetSendDontHaves(false) works the same as before. Behind the scenes, it will disable dontHaveTimeoutMgr by passing a nil onDontHaveTimeout to newDontHaveTimeoutMgr.

Changed

  • 🛠 blockstore and blockservice's WriteThrough() option now takes an "enabled" parameter: WriteThrough(enabled bool).
  • Replaced unmaintained mock time implementation uses in tests: from => to
  • bitswap/client: if a libp2p connection has a context, use context.AfterFunc to cleanup the connection.
  • upgrade to go-libp2p-kad-dht v0.28.1
  • upgrade to go-libp2p v0.38.1
  • blockstore/blockservice: change option to WriteThrough(enabled bool) #749
  • mfs: improve mfs republisher #754

Fixed

  • mfs: directory cache is now cleared on Flush(), liberating the memory used by the otherwise ever-growing cache. References to directories and sub-directories should be renewed after flushing.
  • bitswap/client: Fix leak due to cid queue never getting cleaned up #756
  • bitswap: Drop stream references on Close/Reset 760

[v0.25.0]

Added

  • routing/http/server: added built-in Prometheus instrumentation to http delegated /routing/v1/ endpoints, with custom buckets for response size and duration to match real world data observed at the delegated-ipfs.dev instance. #718 #724
  • routing/http/server: added configurable routing timeout (DefaultRoutingTimeout being 30s) to prevent indefinite hangs during content/peer routing. Set custom duration via WithRoutingTimeout. #720
  • routing/http/server: exposes Prometheus metrics on prometheus.DefaultRegisterer and a custom one can be provided via WithPrometheusRegistry #722
  • gateway: NewCacheBlockStore and NewCarBackend will use prometheus.DefaultRegisterer when a custom one is not specified via WithPrometheusRegistry #722
  • filestore: added opt-in WithMMapReader option to FileManager to enable memory-mapped file reads #665
  • bitswap/routing ProviderQueryManager does not require calling Startup separate from New. #741
  • bitswap/routing ProviderQueryManager does not use lifecycle context.

Changed

  • bitswap, routing, exchange (#641):
    • ✨ Bitswap is no longer in charge of providing blocks to the network: providing functionality is now handled by a exchange/providing.Exchange, meant to be used with provider.System so that all provides follow the same rules (multiple parts of the code where handling provides) before.

    • 🛠 bitswap/client/internal/providerquerymanager has been moved to routing/providerquerymanager where it belongs. In order to keep compatibility, Bitswap now receives a routing.ContentDiscovery parameter which implements FindProvidersAsync(...) and uses it to create a providerquerymanager with the default settings as before. Custom settings can be used by using a custom providerquerymanager to manually wrap a ContentDiscovery object and pass that in as ContentDiscovery on initialization while setting bitswap.WithDefaultProviderQueryManager(false) (to avoid re-wrapping it again).

    • The renovated providedQueryManager will trigger lookups until it manages to connect to MaxProviders. Before it would lookup at most MaxInProcessRequests*MaxProviders and connection failures may have limited the actual number of providers found.

    • 🛠 We have aligned our routing-related interfaces with the libp2p routing ones, including in the reprovider.System.

    • In order to obtain exactly the same behavior as before (i.e. particularly ensuring that new blocks are still provided), what was done like:

      	bswapnet := network.NewFromIpfsHost(host, contentRouter)
      	bswap := bitswap.New(p.ctx, bswapnet, blockstore)
      	bserv = blockservice.New(blockstore, bswap)
    • becomes:

      	// Create network: no contentRouter anymore
      	bswapnet := network.NewFromIpfsHost(host)
      	// Create Bitswap: a new "discovery" parameter, usually the "contentRouter"
      	// which does both discovery and providing.
      	bswap := bitswap.New(p.ctx, bswapnet, discovery, blockstore)
      	// A provider system that handles concurrent provides etc. "contentProvider"
      	// is usually the "contentRouter" which does both discovery and providing.
      	// "contentProvider" could be used directly without wrapping, but it is recommended
      	// to do so to provide more efficiently.
      	provider := provider.New(datastore, provider.Online(contentProvider)
      	// A wrapped providing exchange using the previous exchange and the provider.
      	exch := providing.New(bswap, provider)
      
      	// Finally the blockservice
      	bserv := blockservice.New(blockstore, exch)
      	...
    • The above is only necessary if content routing is needed. Otherwise:

      	// Create network: no contentRouter anymore
      	bswapnet := network.NewFromIpfsHost(host)
      	// Create Bitswap: a new "discovery" parameter set to nil (disable content discovery)
      	bswap := bitswap.New(p.ctx, bswapnet, nil, blockstore)
      	// Finally the blockservice
      	bserv := blockservice.New(blockstore, exch)
  • routing/http/client: creating delegated routing client with New now defaults to querying delegated routing server with DefaultProtocolFilter (IPIP-484) #689
  • bitswap/client: Wait at lease one broadcast interval before resending wants to a peer. Check for peers to rebroadcast to more often than one broadcast interval.
  • No longer using github.com/jbenet/goprocess to avoid requiring in dependents. #710
  • pinning/remote/client: Refactor remote pinning Ls to take results channel instead of returning one. The previous Ls behavior is implemented by the GoLs function, which creates the channels, starts the goroutine that calls Ls, and returns the channels to the caller #738
  • updated to go-libp2p to v0.37.2

Fixed

  • Do not erroneously update the state of sent wants when a send a peer disconnected and the send did not happen. #452

[v0.24.3]

Changed

  • go.mod updates

Fixed

  • bitswap/client no longer logs "Received provider X for cid Y not requested to ERROR level, moved to DEBUG #771

[v0.24.2]

Changed

Fixed

  • bitswap/client: fix panic if current live count is greater than broadcast limit #702

[v0.24.1]

Changed

  • routing/http/client: creating delegated routing client with New now defaults to querying delegated routing server with DefaultProtocolFilter (IPIP-484) #689
  • updated go-libp2p to v0.36.5
  • updated dependencies #693
  • update go-libp2p-kad-dht to v0.27.0

Fixed

  • routing/http/client: optional address and protocol filter parameters from IPIP-484 use human-readable , instead of %2C. #688
  • bitswap/client Cleanup live wants when wants are canceled. This prevents live wants from continuing to get rebroadcasted even after the wants are canceled. #690
  • Fix problem adding invalid CID to exhausted wants list resulting in possible performance issue. #692

[v0.24.0]

Added

  • boxo/bitswap/server:
    • A new WithWantHaveReplaceSize(n) option can be used with bitswap.New to fine-tune cost-vs-performance. It sets the maximum size of a block in bytes up to which the bitswap server will replace a WantHave with a WantBlock response. Setting this to 0 disables this WantHave replacement and means that block sizes are not read when processing WantHave requests. #672
  • routing/http:
    • added support for address and protocol filtering to the delegated routing server (IPIP-484) #671 #678
    • added support for address and protocol filtering to the delegated routing client (IPIP-484) #678. To add filtering to the client, use the WithFilterAddrs and WithFilterProtocols options when creating the client.Client-side filtering for servers that don't support filtering is enabled by default. To disable it, use the disableLocalFiltering option when creating the client.

Changed

Removed

Fixed

  • unixfs/hamt: Log error instead of panic if both link and shard are nil #393
  • pinner/dspinner: do not hang when listing keys and the out channel is no longer read #727

Security

[v0.23.0]

Added

  • files, ipld/unixfs, mfs and tar now support optional UnixFS 1.5 mode and modification time metadata #653
  • gateway deserialized responses will have Last-Modified set to value from optional UnixFS 1.5 modification time field (if present in DAG) and a matching If-Modified-Since will return 304 Not Modified (UnixFS 1.5 files only) #659

Changed

  • updated Go in go.mod to 1.22 #661
  • updated go-libp2p to v0.36.3
  • chunker refactored to reduce overall memory use by reducing heap fragmentation #649
  • bitswap/server minor performance improvements in concurrent operations #666
  • removed dependency on go-ipfs-blocksutil #656

[v0.22.0]

Changed

  • go-libp2p dependency updated to v0.36 (release notes)
  • bitswap/server minor memory use and performance improvements #634
  • bitswap unify logger names to use uniform format bitswap/path/pkgname #637
  • gateway now always returns meaningful cache-control headers for generated HTML listings of UnixFS directories #643
  • util generate random test data using ipfs/go-test instead of internal util code #638
  • bitswap/server PeerLedger.Wants now returns bool (interface change from Wants(p peer.ID, e wl.Entry) to Wants(p peer.ID, e wl.Entry) bool) #629

Fixed

  • boxo/gateway now correctly returns 404 Status Not Found instead of 500 when the requested content cannot be found due to offline exchange, gateway running in no-fetch (non-recursive) mode, or a similar restriction that only serves a specific set of CIDs. #630
  • bitswap/client fix memory leak in BlockPresenceManager due to unlimited map growth. #636
  • bitswap/network fixed race condition when a timeout occurred before hole punching completed while establishing a first-time stream to a peer behind a NAT #651
  • bitswap: wantlist overflow handling now cancels existing entries to make room for newer entries. This fix prevents the wantlist from filling up with CIDs that the server does not have. #629
  • 🛠 bitswap & bitswap/server no longer provide to content routers, instead you can use the provider package because it uses a datastore queue and batches calls to ProvideMany.

[v0.21.0]

Changed

Removed

  • 🛠 routing/none removed ConstructNilRouting, if you need this functionality you can use the Null Router from go-libp2p-routing-helpers.

Fixed

  • routing/http: the FindPeer now returns routing.ErrNotFound when no addresses are found
  • routing/http: the FindProvidersAsync no longer causes a goroutine buildup

[v0.20.0]

Added

  • ✨ gateway has new backend possibilities:
    • NewRemoteBlocksBackend allows you to create a gateway backend that uses one or multiple other gateways as backend. These gateways must support RAW block requests (application/vnd.ipld.raw), as well as IPNS Record requests (application/vnd.ipfs.ipns-record). With this, we also introduced NewCacheBlockStore, NewRemoteBlockstore and NewRemoteValueStore.
    • NewRemoteCarBackend allows you to create a gateway backend that uses one or multiple Trustless Gateways as backend. These gateways must support CAR requests (application/vnd.ipld.car), as well as the extensions describe in IPIP-402. With this, we also introduced NewCarBackend, NewRemoteCarFetcher and NewRetryCarFetcher.
  • gateway now sets the Content-Location header for requests with non-default content format, as a result of content negotiation. This allows generic and misconfigured HTTP caches to store Deserialized, CAR and Block responses separately, under distinct cache keys.
  • gateway now supports car-dups, car-order and car-version as query parameters in addition to the application/vnd.ipld.car parameters sent via Accept header. The parameters in the Accept header have always priority, but including them in URL simplifies HTTP caching and allows use in Content-Location header on CAR responses to maximize interoperability with wide array of HTTP caches.
  • bitswap/server now allows to override the default peer ledger with WithPeerLedger.

Fixed

  • routing/http/server now returns 404 Status Not Found when no records can be found.
  • routing/http/server now supports legacy RSA PeerIDs encoded as Base58 Multihash

[v0.19.0]

Added

  • routing/http/server now adds Cache-Control HTTP header to GET requests: 15 seconds for empty responses, or 5 minutes for responses with providers.
  • routing/http/server the /ipns endpoint is more friendly to users opening URL in web browsers: returns Content-Disposition header and defaults to application/vnd.ipfs.ipns-record response when Accept is missing.
  • provider:
    • Exports a NewPrioritizedProvider, which can be used to prioritize certain providers while ignoring duplicates.
    • 🛠️ NewPinnedProvider now prioritizes root blocks, even if onlyRoots is set to false.

Changed

  • go version changed to 1.21

Fixed

  • 🛠️routing/http/server: delegated peer routing endpoint now supports both Peer ID string notations from libp2p specs.
  • bitswap: add missing client WithBlockReceivedNotifier and WithoutDuplicatedBlockStats options to the exchange.

[v0.18.0]

Added

  • blockservice now has ContextWithSession and EmbedSessionInContext functions, which allows to embed a session in a context. Future calls to BlockGetter.GetBlock, BlockGetter.GetBlocks and NewSession will use the session in the context.
  • blockservice.NewWritethrough deprecated function has been removed, instead you can do blockservice.New(..., ..., WriteThrough()) like previously.
  • gateway: a new header configuration middleware has been added to replace the existing header configuration, which can be used more generically.
  • namesys now has a WithMaxCacheTTL option, which allows you to define a maximum TTL that will be used for caching IPNS entries.

Fixed

  • 🛠 boxo/gateway: when making a trustless CAR request with the "entity-bytes" parameter, using a negative index greater than the underlying entity length could trigger reading more data than intended
  • 🛠 boxo/gateway: the header configuration Config.Headers and AddAccessControlHeaders has been replaced by the new middleware provided by NewHeaders.
  • 🛠 routing/http/client: the default HTTP client is no longer a global singleton. Therefore, using WithUserAgent won't modify the user agent of existing routing clients. This will also prevent potential race conditions. In addition, incompatible options will now return errors instead of silently failing.

[v0.17.0]

Added

  • 🛠 pinning/pinner: you can now give a custom name when pinning a CID. To reflect this, the Pinner has been adjusted. Note that calling Pin for the same CID with a different name will replace its current name by the newly given name.

Removed

  • 🛠 tracing jaeger exporter has been removed due to it's deprecation and removal from upstream, you should use otlp exporter instead. See the docs for an example.

[v0.16.0]

Changed

  • 🛠 boxo/namesys: now fails when multiple valid DNSLink entries are found for the same domain. This used to cause undefined behavior before. Now, we return an error, according to the specification.

Removed

  • 🛠 boxo/gateway: removed support for undocumented legacy ipfs-404.html. Use _redirects instead.
  • 🛠 boxo/namesys: removed support for legacy DNSLink entries at the root of the domain. Use _dnslink. TXT record instead.
  • 🛠 boxo/coreapi, an intrinsic part of Kubo, has been removed and moved to kubo/core/coreiface.

Fixed

  • boxo/gateway
    • a panic (which is recovered) could sporadically be triggered inside a CAR request, if the right conditions were met.
    • no longer emits http: superfluous response.WriteHeader warnings when an error happens.

[v0.15.0]

Changed

[v0.14.0]

Added

  • boxo/gateway:
    • A new WithResolver(...) option can be used with NewBlocksBackend(...) allowing the user to pass their custom Resolver implementation.
    • The gateway now sets a Cache-Control header for requests under the /ipns/ namespace if the TTL for the corresponding IPNS Records or DNSLink entities is known.
  • boxo/bitswap/client:
    • A new WithoutDuplicatedBlockStats() option can be used with bitswap.New and bsclient.New. This disable accounting for duplicated blocks, which requires a blockstore.Has() lookup for every received block and thus, can impact performance.
  • ✨ Migrated repositories into Boxo

Changed

  • boxo/gateway
    • 🛠 The IPFSBackend interface was updated to make the responses of the Head method more explicit. It now returns a HeadResponse instead of a files.Node.
  • boxo/routing/http/client.Client is now exported. This means you can now pass it around functions, or add it to a struct if you want.
  • 🛠 The path package has been massively refactored. With this refactor, we have condensed the different path-related and/or Kubo-specific packages under a single generic one. Therefore, there are many breaking changes. Please consult the documentation for more details on how to use the new package.
    • Note: content paths created with boxo/path are automatically normalized:
      • Replace multiple slashes with a single slash.
      • Eliminate each . path name element (the current directory).
      • Eliminate each inner .. path name element (the parent directory) along with the non-.. element that precedes it.
      • Eliminate .. elements that begin a rooted path: that is, replace "/.." by "/" at the beginning of a path.
  • 🛠 The signature of CoreAPI.ResolvePath in coreiface has changed to now return the remainder segments as a second return value, matching the signature of resolver.ResolveToLastNode.
  • 🛠 routing/http/client.FindPeers now returns iter.ResultIter[types.PeerRecord] instead of iter.ResultIter[types.Record]. The specification indicates that records for this method will always be Peer Records.
  • 🛠 The namesys package has been refactored. The following are the largest modifications:
    • The options in coreiface/options/namesys have been moved to namesys and their names have been made more consistent.
    • Many of the exported structs and functions have been renamed in order to be consistent with the remaining packages.
    • namesys.Resolver.Resolve now returns a TTL, in addition to the resolved path. If the TTL is unknown, 0 is returned. IPNSResolver is able to resolve a TTL, while DNSResolver is not.
    • namesys/resolver.ResolveIPNS has been moved to namesys.ResolveIPNS and now returns a TTL in addition to the resolved path.
  • ✨ boxo/ipns record defaults follow recommendations from IPNS Record Specification:
    • DefaultRecordTTL is now set to 1h
    • DefaultRecordLifetime follows the increased expiration window of Amino DHT (go-libp2p-kad-dht#793) and is set to 48h
  • 🛠 The gateway's IPFSBackend.ResolveMutable is now expected to return a TTL in addition to the resolved path. If the TTL is unknown, 0 should be returned.

Removed

  • 🛠 util.MultiErr has been removed. Please use Go's native support for wrapping errors, or errors.Join instead.

Fixed

Security

[v0.13.1]

Added

  • An option DisableHTMLErrors has been added to gateway.Config. When this option is true, pretty HTML error pages for web browsers are disabled. Instead, a text/plain page with the raw error message as the body is returned.

Changed

Removed

Fixed

Security

[v0.13.0]

Added

  • ✨ The routing/http implements Delegated Peer Routing introduced in IPIP-417.

Changed

  • 🛠 The routing/http package received the following modifications:
    • Client GetIPNSRecord and PutIPNSRecord have been renamed to GetIPNS and PutIPNS, respectively. Similarly, the required function names in the server ContentRouter have also been updated.
    • ReadBitswapProviderRecord has been renamed to BitswapRecord and marked as deprecated. From now on, please use the protocol-agnostic PeerRecord for most use cases. The new Peer Schema has been introduced in IPIP-417.

Removed

  • 🛠 The routing/http package experienced following removals:
    • Server and client no longer support the experimental Provide method. ProvideBitswap is still usable, but marked as deprecated. A protocol-agnostic provide mechanism is being worked on in IPIP-378.
    • Server no longer exports FindProvidersPath and ProvidePath.

Fixed

  • The normalization of DNSLink identifiers in gateway has been corrected in the edge case where the value passed to the path component of the URL is already normalized.

Security

[v0.12.0]

Added

  • The routing/http client and server now support Delegated IPNS at /routing/v1 as per IPIP-379.
  • 🛠 The verifycid package has been updated with the new Allowlist interface as part of reducing globals efforts.
  • The blockservice and provider packages has been updated to accommodate for changes in verifycid.

Changed

Removed

Fixed

  • HTTP Gateway API: Not having a block will result in a 5xx error rather than 404
  • HTTP Gateway API: CAR requests will return 200s and a CAR file proving a requested path does not exist rather than returning an error
  • 🛠 MultiFileReader has been updated with a new header with the encoded file name instead of the plain filename, due to a regression found in net/textproto. This only affects files with binary characters in their name. By keeping the old header, we maximize backwards compatibility.
    New Client Old Client
    New Server ✅ 🟡*
    Old Server ✅ ✅
    *Old clients can only send Unicode file paths to the server.

Security

[v0.11.0]

Added

  • ✨ The gateway now supports the optional order and dups CAR parameters from IPIP-412.
    • The BlocksBackend only implements order=dfs (Depth-First Search) ordering, which was already the default behavior.
    • If a request specifies no dups, response with dups=n is returned, which was already the default behavior.
    • If a request explicitly specifies a CAR order other than dfs, it will result in an error.
    • The only change to the default behavior on CAR responses is that we follow IPIP-412 and make order=dfs;dups=n explicit in the returned Content-Type HTTP header.
  • ✨ While the call signature remains the same, the blocks that Bitswap returns can now be cast to traceability.Block, which will additionally tell you where the Block came from and how long it took to fetch. This helps consumers of Bitswap collect better metrics on Bitswap behavior.

Changed

  • 🛠 The ipns package has been refactored.
    • You should no longer use the direct Protobuf version of the IPNS Record. Instead, we have a shiny new ipns.Record type that wraps all the required functionality to work the best as possible with IPNS v2 Records. Please check the documentation for more information, and follow ipfs/specs#376 for related IPIP.
    • There is no change to IPNS Records produced by boxo/ipns, it still produces both V1 and V2 signatures by default, it is still backward-compatible.

Removed

  • 🛠 ipld/car has been removed. Please use ipld/go-car instead. More information regarding this decision can be found in issue 218.

Fixed

  • Removed mentions of unused ARC algorithm (#336)
  • Handle _redirects file when If-None-Match header is present (#412)

Security

[0.10.3] - 2023-08-08

Added

Changed

Removed

Fixed

  • Handle _redirects file when If-None-Match header is present (#412)

Security

[0.10.2] - 2023-06-29

Fixed

  • Gateway: include CORS on subdomain redirects.
  • Gateway: ensure 'X-Ipfs-Root' header is valid.

[0.10.1] - 2023-06-19

Added

None.

Changed

None.

Removed

None.

Fixed

  • Allow CAR requests with a path when DeserializedResponses is false.

Security

None.

[0.10.0] - 2023-06-09

Added

  • ✨ The gateway now supports partial CAR exports via query parameters from IPIP-402.

Changed

  • 🛠 A few trivial breaking changes have been done to the gateway:
    • The signature of IPFSBackend.GetCAR has been adapted to support IPIP-402 CAR Parameters.
    • A few variables have been renamed for consistency:
      • WithHostname -> NewHostnameHandler
      • Specification -> PublicGateway
      • NewErrorResponse -> NewErrorStatusCode
      • NewErrorResponseForCode -> NewErrorStatusCodeFromStatus
      • BlocksGateway -> BlocksBackend
      • BlocksGatewayOption -> BlocksBackendOption
      • NewBlocksGateway -> NewBlocksBackend
    • Some functions that are not supposed to be outside of the package were removed: ServeContent.

Removed

None.

Fixed

None.

Security

None.

[0.9.0] - 2023-06-08

Added

  • ✨ gateway The gateway were updated to provide better features for users and gateway implementers:
    • New human-friendly error messages.
    • Updated, higher-definition icons in directory listings.
    • Customizable menu items next to "About IPFS" and "Install IPFS".
    • Valid DAG-CBOR and DAG-JSON blocks now provide a preview, where links can be followed.
  • ipns add ValidateWithPeerID and UnmarshalIpnsEntry helpers. (https://github.com/ipfs/boxo/pulls/292)
  • 🛠 coreiface/tests add *testing.T argument to the swarm provider. (https://github.com/ipfs/boxo/pulls/321)

Changed

  • 🛠 boxo/pinner some listing methods have been changed to now return a <-chan StreamedCid. This allows the consumption of pins while the pinner is listing them, which for large pinset can take a long time. (https://github.com/ipfs/boxo/pulls/336) The concerned methods are:
    • DirectKeys
    • RecursiveKeys
    • InternalKeys
  • 🛠 provider/batched.New has been moved to provider.New and arguments has been changed. (https://github.com/ipfs/boxo/pulls/273)
    • A routing system is now passed with the provider.Online option, by default the system run in offline mode (push stuff onto the queue).
    • When using provider.Online calling the .Run method is not required anymore, the background worker is implicitly started in the background by provider.New.
    • You do not have to pass a queue anymore, you pass a datastore.Datastore exclusively.
  • 🛠 provider.NewOfflineProvider has been renamed to provider.NewNoopProvider to show more clearly that is does nothing. (https://github.com/ipfs/boxo/pulls/273)
  • 🛠 provider.Provider and provider.Reprovider has been merged under one provider.System. (https://github.com/ipfs/boxo/pulls/273)
  • 🛠 routing/http responses now return a streaming iter.ResultIter generic interface. (https://github.com/ipfs/boxo/pulls/18)
  • 🛠 coreiface add options and AllowOffline option to RoutingAPI.Put. (https://github.com/ipfs/boxo/pulls/278)
  • 🛠 gateway now has deserialized responses turned off by default. This can be configured via DeserializedResponses. (#252)

Removed

Fixed

Security

None

[0.8.1] - 2023-04-25

Added

  • gateway trace context header support (#256)

Changed

  • gateway widen duration histograms and cleanup (#265)

Deprecated

None

Removed

None

Fixed

  • gateway panic on path without enough components (#272)

Security

None

[0.8.0] - 2023-04-05

Added

  • ✨ Migrated repositories into Boxo (#220)
    • github.com/ipfs/interface-go-ipfs-core => ./coreiface
    • github.com/ipfs/go-pinning-service-http-client => ./pinning/remote/client
    • github.com/ipfs/go-path => ./path
    • github.com/ipfs/go-namesys => ./namesys
    • github.com/ipfs/go-mfs => ./mfs
    • github.com/ipfs/go-ipfs-provider => ./provider
    • github.com/ipfs/go-ipfs-pinner => ./pinning/pinner
    • github.com/ipfs/go-ipfs-keystore => ./keystore
    • github.com/ipfs/go-filestore => ./filestore
    • github.com/ipfs/go-ipns => ./ipns
    • github.com/ipfs/go-blockservice => ./blockservice
    • github.com/ipfs/go-ipfs-chunker => ./chunker
    • github.com/ipfs/go-fetcher => ./fetcher
    • github.com/ipfs/go-ipfs-blockstore => ./blockstore
    • github.com/ipfs/go-ipfs-posinfo => ./filestore/posinfo
    • github.com/ipfs/go-ipfs-util => ./util
    • github.com/ipfs/go-ipfs-ds-help => ./datastore/dshelp
    • github.com/ipfs/go-verifcid => ./verifcid
    • github.com/ipfs/go-ipfs-exchange-offline => ./exchange/offline
    • github.com/ipfs/go-ipfs-routing => ./routing
    • github.com/ipfs/go-ipfs-exchange-interface => ./exchange
    • github.com/ipfs/go-unixfs => ./ipld/unixfs
    • github.com/ipfs/go-merkledag => ./ipld/merkledag
    • github.com/ipld/go-car => ./ipld/car
  • ✨ Added a migration tool to aid in migrating from the migrated repositories to Boxo, see the documentation here: https://github.com/ipfs/boxo/blob/main/README.md#migrating-to-boxo (#226)
    • Added a check to ensure the migration tool is only run in a Git repository (with an optional override flag)
  • ✨ Added tracing and metrics to the refactored gateway for its IPFS backend

Changed

  • Removed a mention of "bitswap" in blockservice debug logs
  • Changed the Bitswap message package from "bitswap.message.pb" to "bitswap.message.v1.pb" to avoid protobuf panics due to duplicate registration with go-bitswap (#212)
  • ✨ Remove a busyloop in blockservice getBlocks by removing batching when caching (#232)

Deprecated

None

Removed

None

Fixed

  • Ensure dag-cbor/json codecs are registered in the gateway handler (#223)
  • ✨ Refactor the Gateway API to operate on higher level semantics (#176)
  • Fixed a panic in the gateway handler when returning errors (#255)

Security

None