@cryptotaxi247 / kubo / commits / 6c927fd96

Partial ipld node impl

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

Łukasz Magiera committed Nov 6, 2018 at 14:38 UTC 6c927fd9624807e124f0376445c41daaa975fbd8
4 files changed +151 -4
client/httpapi/api.go
+3 -3
@@ -1,7 +1,7 @@
1 package httpapi
2
3 import (
4 - "github.com/pkg/errors"
4 + "errors"
5 "io/ioutil"
6 gohttp "net/http"
7 "os"
@@ -12,7 +12,7 @@ import (
12 homedir "github.com/mitchellh/go-homedir"
13 ma "github.com/multiformats/go-multiaddr"
14 manet "github.com/multiformats/go-multiaddr-net"
15 - )
15 +)
16
17 const (
18 DefaultPathName = ".ipfs"
@@ -91,7 +91,7 @@ func (api *HttpApi) Unixfs() iface.UnixfsAPI {
91 }
92
93 func (api *HttpApi) Block() iface.BlockAPI {
94 - return nil
94 + return (*BlockAPI)(api)
95 }
96
97 func (api *HttpApi) Dag() iface.DagAPI {
client/httpapi/block.go new
+40
@@ -0,0 +1,40 @@
1 +package httpapi
2 +
3 +import (
4 + "context"
5 + "io"
6 +
7 + "github.com/ipfs/go-ipfs/core/coreapi/interface"
8 + "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
9 +)
10 +
11 +type BlockAPI HttpApi
12 +
13 +func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...options.BlockPutOption) (iface.BlockStat, error) {
14 + return nil, ErrNotImplemented
15 +}
16 +
17 +func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) {
18 + resp, err := api.core().request("block/get", p.String()).Send(context.Background())
19 + if err != nil {
20 + return nil, err
21 + }
22 +
23 + //TODO: is close on the reader enough?
24 + //defer resp.Close()
25 +
26 + //TODO: make blockApi return ReadCloser
27 + return resp.Output, resp.Error
28 +}
29 +
30 +func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...options.BlockRmOption) error {
31 + return ErrNotImplemented
32 +}
33 +
34 +func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) {
35 + return nil, ErrNotImplemented
36 +}
37 +
38 +func (api *BlockAPI) core() *HttpApi {
39 + return (*HttpApi)(api)
40 +}
client/httpapi/ipldnode.go new
+107
@@ -0,0 +1,107 @@
1 +package httpapi
2 +
3 +import (
4 + "context"
5 + "fmt"
6 + "github.com/pkg/errors"
7 + "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
8 + "io/ioutil"
9 + "strconv"
10 +
11 + "github.com/ipfs/go-ipfs/core/coreapi/interface"
12 +
13 + ipfspath "gx/ipfs/QmRG3XuGwT7GYuAqgWDJBKTzdaHMwAnc1x7J2KHEXNHxzG/go-path"
14 + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
15 +)
16 +
17 +type ipldNode struct {
18 + ctx context.Context //TODO: should we re-consider adding ctx to ipld interfaces?
19 + path iface.ResolvedPath
20 + api *HttpApi
21 +}
22 +
23 +func (n *ipldNode) RawData() []byte {
24 + r, err := n.api.Block().Get(n.ctx, n.path)
25 + if err != nil {
26 + panic(err) // TODO: eww, should we add errors too / better ideas?
27 + }
28 +
29 + b, err := ioutil.ReadAll(r)
30 + if err != nil {
31 + panic(err)
32 + }
33 +
34 + return b
35 +}
36 +
37 +func (n *ipldNode) Cid() cid.Cid {
38 + return n.path.Cid()
39 +}
40 +
41 +func (n *ipldNode) String() string {
42 + return fmt.Sprintf("[Block %s]", n.Cid())
43 +}
44 +
45 +func (n *ipldNode) Loggable() map[string]interface{} {
46 + return nil //TODO: we can't really do better here, can we?
47 +}
48 +
49 +// TODO: should we use 'full'/real ipld codecs for this? js-ipfs-api does that.
50 +// We can also give people a choice
51 +func (n *ipldNode) Resolve(path []string) (interface{}, []string, error) {
52 + p := ipfspath.Join([]string{n.path.String(), ipfspath.Join(path)})
53 +
54 + var out interface{}
55 + n.api.request("dag/get", p).Exec(n.ctx, &out)
56 +
57 + // TODO: this is more than likely wrong, fix if we decide to stick with this 'http-ipld-node' hack
58 + for len(path) > 0 {
59 + switch o := out.(type) {
60 + case map[string]interface{}:
61 + v, ok := o[path[0]]
62 + if !ok {
63 + // TODO: ipld links
64 + return nil, nil, errors.New("no element under this path")
65 + }
66 + out = v
67 + case []interface{}:
68 + n, err := strconv.ParseUint(path[0], 10, 32)
69 + if err != nil {
70 + return nil, nil, err
71 + }
72 + if len(o) < int(n) {
73 + return nil, nil, errors.New("no element under this path")
74 + }
75 + out = o[n]
76 + }
77 + path = path[1:]
78 + }
79 +
80 + return out, path, nil
81 +}
82 +
83 +func (n *ipldNode) Tree(path string, depth int) []string {
84 + panic("implement me")
85 +}
86 +
87 +func (n *ipldNode) ResolveLink(path []string) (*ipld.Link, []string, error) {
88 + panic("implement me")
89 +}
90 +
91 +func (n *ipldNode) Copy() ipld.Node {
92 + panic("implement me")
93 +}
94 +
95 +func (n *ipldNode) Links() []*ipld.Link {
96 + panic("implement me")
97 +}
98 +
99 +func (n *ipldNode) Stat() (*ipld.NodeStat, error) {
100 + panic("implement me")
101 +}
102 +
103 +func (n *ipldNode) Size() (uint64, error) {
104 + panic("implement me")
105 +}
106 +
107 +var _ ipld.Node = &ipldNode{}
client/httpapi/path.go
+1 -1
@@ -30,7 +30,7 @@ func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.Res
30 }
31
32 // TODO:
33 - ipath, err := ipfspath.FromSegments("/" +path.Namespace() + "/", out.Cid.String(), out.RemPath)
33 + ipath, err := ipfspath.FromSegments("/"+path.Namespace()+"/", out.Cid.String(), out.RemPath)
34 if err != nil {
35 return nil, err
36 }