@cryptotaxi247 / kubo / commits / ed9f2dd09

Implement DHT Api

This commit was moved from ipfs/go-ipfs-http-client@c77355067a22300a8abe6b93b354de0ae0a3b548

Łukasz Magiera committed Jan 15, 2019 at 17:01 UTC ed9f2dd091693e914e9de072b2c23c2f991210a6
2 files changed +99 -1
client/httpapi/api.go
+1 -1
@@ -158,7 +158,7 @@ func (api *HttpApi) Object() iface.ObjectAPI {
158 }
159
160 func (api *HttpApi) Dht() iface.DhtAPI {
161 - return nil
161 + return (*DhtAPI)(api)
162 }
163
164 func (api *HttpApi) Swarm() iface.SwarmAPI {
client/httpapi/dht.go new
+98
@@ -0,0 +1,98 @@
1 +package httpapi
2 +
3 +import (
4 + "context"
5 + "encoding/json"
6 + "github.com/ipfs/go-ipfs/core/coreapi/interface"
7 + caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
8 +
9 + "github.com/libp2p/go-libp2p-peer"
10 + "github.com/libp2p/go-libp2p-peerstore"
11 + notif "github.com/libp2p/go-libp2p-routing/notifications"
12 +)
13 +
14 +type DhtAPI HttpApi
15 +
16 +func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (peerstore.PeerInfo, error) {
17 + var out struct {
18 + Type notif.QueryEventType
19 + Responses []peerstore.PeerInfo
20 + }
21 + resp, err := api.core().request("dht/findpeer", p.Pretty()).Send(ctx)
22 + if err != nil {
23 + return peerstore.PeerInfo{}, err
24 + }
25 + if resp.Error != nil {
26 + return peerstore.PeerInfo{}, resp.Error
27 + }
28 + defer resp.Close()
29 + dec := json.NewDecoder(resp.Output)
30 + for {
31 + if err := dec.Decode(&out); err != nil {
32 + return peerstore.PeerInfo{}, err
33 + }
34 + if out.Type == notif.FinalPeer {
35 + return out.Responses[0], nil
36 + }
37 + }
38 +}
39 +
40 +func (api *DhtAPI) FindProviders(ctx context.Context, p iface.Path, opts ...caopts.DhtFindProvidersOption) (<-chan peerstore.PeerInfo, error) {
41 + options, err := caopts.DhtFindProvidersOptions(opts...)
42 + if err != nil {
43 + return nil, err
44 + }
45 + resp, err := api.core().request("dht/findprovs", p.String()).
46 + Option("num-providers", options.NumProviders).
47 + Send(ctx)
48 + if err != nil {
49 + return nil, err
50 + }
51 + if resp.Error != nil {
52 + return nil, resp.Error
53 + }
54 + res := make(chan peerstore.PeerInfo)
55 +
56 + go func() {
57 + defer resp.Close()
58 + defer close(res)
59 + dec := json.NewDecoder(resp.Output)
60 +
61 + for {
62 + var out struct {
63 + Type notif.QueryEventType
64 + Responses []peerstore.PeerInfo
65 + }
66 +
67 + if err := dec.Decode(&out); err != nil {
68 + return // todo: handle this somehow
69 + }
70 + if out.Type == notif.Provider {
71 + for _, pi := range out.Responses {
72 + select {
73 + case res <- pi:
74 + case <-ctx.Done():
75 + return
76 + }
77 + }
78 + }
79 + }
80 + }()
81 +
82 + return res, nil
83 +}
84 +
85 +func (api *DhtAPI) Provide(ctx context.Context, p iface.Path, opts ...caopts.DhtProvideOption) error {
86 + options, err := caopts.DhtProvideOptions(opts...)
87 + if err != nil {
88 + return err
89 + }
90 +
91 + return api.core().request("dht/provide", p.String()).
92 + Option("recursive", options.Recursive).
93 + Exec(ctx, nil)
94 +}
95 +
96 +func (api *DhtAPI) core() *HttpApi {
97 + return (*HttpApi)(api)
98 +}