Skip to content

Commit

Permalink
feat: expose routing v1 server via optional setting
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed May 15, 2023
1 parent 4acadd4 commit cc789aa
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 1 deletion.
4 changes: 4 additions & 0 deletions cmd/ipfs/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,10 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
opts = append(opts, corehttp.P2PProxyOption())
}

if cfg.Gateway.ExposeRoutingAPI.WithDefault(config.DefaultExposeRoutingAPI) {
opts = append(opts, corehttp.RoutingOption())
}

if len(cfg.Gateway.RootRedirect) > 0 {
opts = append(opts, corehttp.RedirectOption("", cfg.Gateway.RootRedirect))
}
Expand Down
9 changes: 8 additions & 1 deletion config/gateway.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package config

const DefaultInlineDNSLink = false
const (
DefaultInlineDNSLink = false
DefaultExposeRoutingAPI = false
)

type GatewaySpec struct {
// Paths is explicit list of path prefixes that should be handled by
Expand Down Expand Up @@ -59,4 +62,8 @@ type Gateway struct {
// PublicGateways configures behavior of known public gateways.
// Each key is a fully qualified domain name (FQDN).
PublicGateways map[string]*GatewaySpec

// ExposeRoutingAPI configures the gateway to expose a Routing v1 HTTP Server
// under /routing/v1: https://specs.ipfs.tech/routing/routing-v1/.
ExposeRoutingAPI Flag
}
102 changes: 102 additions & 0 deletions core/corehttp/routing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package corehttp

import (
"context"
"net"
"net/http"
"time"

"github.com/ipfs/boxo/routing/http/server"
"github.com/ipfs/boxo/routing/http/types"
"github.com/ipfs/boxo/routing/http/types/iter"
cid "github.com/ipfs/go-cid"
core "github.com/ipfs/kubo/core"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/routing"
"github.com/multiformats/go-multiaddr"
)

func RoutingOption() ServeOption {
return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
handler := server.Handler(&contentRouter{n})
mux.Handle("/routing/v1/", handler)
return mux, nil
}
}

type contentRouter struct {
n *core.IpfsNode
}

func (r *contentRouter) FindProviders(ctx context.Context, key cid.Cid) (iter.ResultIter[types.ProviderResponse], error) {
ctx, cancel := context.WithCancel(ctx)
ch := r.n.Routing.FindProvidersAsync(ctx, key, 20) // TODO: magic number, where to get this from
return iter.ToResultIter[types.ProviderResponse](&peerChanIter{
ch: ch,
cancel: cancel,
}), nil
}

func (r *contentRouter) Provide(ctx context.Context, req *server.WriteProvideRequest) (types.ProviderResponse, error) {
// Kubo /routing/v1 endpoint does not support write operations.
return nil, routing.ErrNotSupported
}

func (r *contentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) {
// Kubo /routing/v1 endpoint does not support write operations.
return 0, routing.ErrNotSupported
}

type peerChanIter struct {
ch <-chan peer.AddrInfo
cancel context.CancelFunc
next *peer.AddrInfo
}

func (it *peerChanIter) Next() bool {
addr, ok := <-it.ch
if ok {
it.next = &addr
return true
} else {
it.next = nil
return false
}
}

func (it *peerChanIter) Val() types.ProviderResponse {
if it.next == nil {
return nil
}

// We don't know what type of protocol this peer provides. It is likely Bitswap
// but it might not be. Therefore, we set an unknown protocol with an unknown schema.
rec := &providerRecord{
Protocol: "transport-unknown",
Schema: "unknown",
ID: it.next.ID,
Addrs: it.next.Addrs,
}

return rec
}

func (it *peerChanIter) Close() error {
it.cancel()
return nil
}

type providerRecord struct {
Protocol string
Schema string
ID peer.ID
Addrs []multiaddr.Multiaddr
}

func (pr *providerRecord) GetProtocol() string {
return pr.Protocol
}

func (pr *providerRecord) GetSchema() string {
return pr.Schema
}

0 comments on commit cc789aa

Please sign in to comment.