Skip to content
This repository was archived by the owner on Oct 5, 2023. It is now read-only.

Commit df916c7

Browse files
committed
Partial ipld node impl
1 parent 93943f7 commit df916c7

File tree

4 files changed

+151
-4
lines changed

4 files changed

+151
-4
lines changed

api.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package httpapi
22

33
import (
4-
"github.com/pkg/errors"
4+
"errors"
55
"io/ioutil"
66
gohttp "net/http"
77
"os"
@@ -12,7 +12,7 @@ import (
1212
homedir "github.com/mitchellh/go-homedir"
1313
ma "github.com/multiformats/go-multiaddr"
1414
manet "github.com/multiformats/go-multiaddr-net"
15-
)
15+
)
1616

1717
const (
1818
DefaultPathName = ".ipfs"
@@ -91,7 +91,7 @@ func (api *HttpApi) Unixfs() iface.UnixfsAPI {
9191
}
9292

9393
func (api *HttpApi) Block() iface.BlockAPI {
94-
return nil
94+
return (*BlockAPI)(api)
9595
}
9696

9797
func (api *HttpApi) Dag() iface.DagAPI {

block.go

+40
Original file line numberDiff line numberDiff line change
@@ -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+
}

ipldnode.go

+107
Original file line numberDiff line numberDiff line change
@@ -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{}

path.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (api *HttpApi) ResolvePath(ctx context.Context, path iface.Path) (iface.Res
3030
}
3131

3232
// 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)
3434
if err != nil {
3535
return nil, err
3636
}

0 commit comments

Comments
 (0)