feat(routing/http): IPIP-518: HTTP(S) URLs in Routing V1 API#1051
feat(routing/http): IPIP-518: HTTP(S) URLs in Routing V1 API#1051
Conversation
…ing API Implements schema-agnostic support for HTTP(S) URLs alongside multiaddrs in the Delegated Routing V1 HTTP API as specified in IPIP-518. Key changes: - Add new Address type that accepts both multiaddrs (starting with /) and URIs - Update PeerRecord and BitswapRecord to use Addresses type instead of []Multiaddr - Implement defensive programming: unsupported addresses are skipped, not errors - Add special protocol filtering for http/https/tls matching - Maintain full backward compatibility with multiaddr-only implementations The implementation is schema-agnostic, accepting any valid URI scheme for future extensibility. URLs are preserved as-is without lossy conversion to multiaddrs, avoiding conversion issues documented in multiaddr#63. Ref: ipfs/specs#518
Implements backward compatibility layer for HTTP(S) URL to multiaddr conversion during transition period. Uses /https (not /tls/http) to match IPNI convention and /dns for dual-stack support. - Add ToMultiaddr() method and String() for Addresses type - Replace TODOs in contentrouter with actual conversion - Add comprehensive tests Temporary compatibility layer until ecosystem adopts IPIP-518 URLs.
Codecov Report❌ Patch coverage is @@ Coverage Diff @@
## main #1051 +/- ##
==========================================
+ Coverage 61.68% 61.96% +0.27%
==========================================
Files 265 268 +3
Lines 26513 26804 +291
==========================================
+ Hits 16355 16609 +254
- Misses 8469 8495 +26
- Partials 1689 1700 +11
... and 10 files with indirect coverage changes 🚀 New features to boost your workflow:
|
| // Returns nil if the address cannot be converted (e.g., non-HTTP schemes or invalid addresses). | ||
| // This is a temporary compatibility layer for the transition period while existing software | ||
| // expects multiaddrs with /http protocol to signal HTTP retrieval support. | ||
| func (a *Address) ToMultiaddr() multiaddr.Multiaddr { |
There was a problem hiding this comment.
An alternative to this that avoids hardcoded values for addrProto can be found here:
https://github.com/ipni/go-libipni/blob/main/maurl/convert.go#L110-L156
Both approaches work. The go-libipni version has had years of testing and operation if you want to cut and paste that one, but that does not mean it is necessarily better. I think perhaps using megular expressions would be better still.
There was a problem hiding this comment.
I am worried about unintended consequences if w blindly convert here like IPNI func does, let's keep as-is.
Mind, the only reason this func exist, is backward compatibility with existing HTTP support for trustless gateways which have "fake peerids" and "fake libp2p multiaddrs".
That is why we only do this for HTTP(S) schema URIs + have default ports.
There was a problem hiding this comment.
Found interesting inconsistency:
IPNI's FromURL passes url.PathEscape(u.Path) without stripping the leading /, producing %2Fpath instead of path so you have /http-path/%2Fpath instead of `/http-path/path.
The only spec I found is example in https://github.com/multiformats/multiaddr/blob/master/protocols/http-path.md
which suggests the leading / should be stripped to avoid %2F (means IPNI has a bug, but its probably too late to fix).
|
Triage: Consider updating IPIP to suggest different peer schema. Note: Should not assume trustless gateway when HTTP URI with no metadata |
…compat introduce GenericRecord (Schema=generic) as specified in the updated IPIP-518, keeping PeerRecord (Schema=peer) unchanged with []Multiaddr. type system: - add GenericRecord with duck-typed Addresses (multiaddrs + URIs) - revert PeerRecord.Addrs and BitswapRecord.Addrs to []Multiaddr - change Address constructors to return value types instead of pointers - remove special "tls" matching from HasProtocol (redundant with default) - simplify ToMultiaddr to use URL scheme directly (http or https) contentrouter (client-side GenericRecord -> peer.AddrInfo conversion): - convert GenericRecord to peer.AddrInfo for legacy libp2p routing APIs - if ID is a valid PeerID, convert regardless of Protocols (supports the legacy pattern where PeerID + /https multiaddr hints at a Trustless IPFS HTTP Gateway even without explicit protocol declaration) - if ID is not a PeerID but record has transport-ipfs-gateway-http + HTTP(S) URLs, derive PeerID from did:key: or generate a placeholder - HTTPS URLs become /dns/host/tcp/443/https multiaddrs via ToMultiaddr - extract filterAddrs helper for nil-safe []Multiaddr extraction - add MaxGenericRecordSize check in JSON deserialization path to match the existing NDJSON check filters (server-side): - add GenericRecord support to ApplyFiltersToIter - add applyGenericFilters for protocol and address filtering on GenericRecord (operates on Addresses directly, no conversion needed) - convert PeerRecord []Multiaddr to Addresses for filtering via applyAddrFilter, then convert back server and client: - serialize/deserialize GenericRecord in JSON and NDJSON responses - add GenericRecord to FindProviders end-to-end client test tests: - add GenericRecord JSON/NDJSON round-trip tests with Extra field preservation, unparseable address handling, and size limit enforcement - add contentrouter tests for PeerID, did:key, placeholder PeerID, empty Protocols, and HTTP URL conversion paths - add filter tests for mixed multiaddr+URL addresses and mixed PeerRecord+GenericRecord iterator streams - add server tests for mixed schema responses, protocol/addr filtering, NDJSON streaming, and Extra field serialization - document that PeerRecord Addrs rejects URLs at unmarshal time
# Conflicts: # CHANGELOG.md # routing/http/contentrouter/contentrouter.go # routing/http/filters/filters.go
5cb023a to
b5ccecd
Compare
…terop helpers - ToMultiaddr() now appends /http-path/ when the URL has a non-empty path, matching go-multiaddr http-path protocol conventions - moved peerIDFromDIDKey, peerIDPlaceholderFromArbitraryID, hasHTTPURL to contentrouter/interop.go for better organization - added unit tests for hasHTTPURL covering http, https, non-HTTP, multiaddr, mixed, empty, and invalid address cases - fixed staticcheck lint suppression for SchemaBitswap in ndjson test
b5ccecd to
0feb195
Compare
This PR implements IPIP-518 which extends
/routing/v1with support for URIs alongside multiaddrs.Changes
New
Addresstype (types/address.go)/) and URIs, following IPIP-518 parsing rulesHasProtocolhandles http/https semantics (e.g.https://matches both "http" and "https" queries)ToMultiaddr()converts HTTP(S) URLs to multiaddrs for backward compatibility with existing software that expects/dns/host/tcp/port/httpsformat, including/http-path/when the URL has a non-empty pathNew
GenericRecordtype (types/record_generic.go)Addresses(which accepts both URLs and multiaddrs) instead of[]MultiaddrExtramap for forward compatibility with future protocolsContentrouter integration (
contentrouter/contentrouter.go)readProviderResponsesconvertsGenericRecordtopeer.AddrInfofor legacy routing APIs:/httpsmultiaddr pattern)transport-ipfs-gateway-http+ HTTP(S) URLs: PeerID derived fromdid:key:(ed25519) or generated as a deterministic placeholdercontentrouter/interop.goFilter updates (
filters/filters.go)ApplyAddrFilterextended to handleAddresstype alongsideMultiaddrExisting types unchanged
PeerRecordandBitswapRecordcontinue to use[]Multiaddr(multiaddrs only)GenericRecord, which is the forward-looking record typeBackward compatibility
ToMultiaddr()so existing consumers (Kubo, someguy) receive addresses they can usePeerRecord.Addrsremains[]Multiaddrand rejects URLs at deserialization timeIPIP:
TODO