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

Commit d0c98b8

Browse files
committed
Block API
1 parent dfbe002 commit d0c98b8

File tree

4 files changed

+121
-13
lines changed

4 files changed

+121
-13
lines changed

api.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (api *HttpApi) Dag() iface.DagAPI {
118118
}
119119

120120
func (api *HttpApi) Name() iface.NameAPI {
121-
return (*NameAPI)(api)
121+
return nil
122122
}
123123

124124
func (api *HttpApi) Key() iface.KeyAPI {

api_test.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package httpapi
33
import (
44
"context"
55
"fmt"
6-
"github.com/ipfs/iptb/testbed/interfaces"
76
"io/ioutil"
87
"os"
98
"path"
@@ -16,6 +15,7 @@ import (
1615
local "github.com/ipfs/iptb-plugins/local"
1716
"github.com/ipfs/iptb/cli"
1817
"github.com/ipfs/iptb/testbed"
18+
"github.com/ipfs/iptb/testbed/interfaces"
1919
)
2020

2121
type NodeProvider struct{}
@@ -39,7 +39,14 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int)
3939
}
4040

4141
c := cli.NewCli()
42-
if err := c.Run([]string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10), "--start"}); err != nil {
42+
43+
initArgs := []string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10)}
44+
if err := c.Run(initArgs); err != nil {
45+
return nil, err
46+
}
47+
48+
startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--offline=" + strconv.FormatBool(n == 1)}
49+
if err := c.Run(startArgs); err != nil {
4350
return nil, err
4451
}
4552

block.go

+99-10
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,127 @@
11
package httpapi
22

33
import (
4+
"bytes"
45
"context"
6+
"errors"
7+
"fmt"
58
"io"
69

10+
"github.com/ipfs/go-cid"
711
"github.com/ipfs/go-ipfs/core/coreapi/interface"
8-
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
12+
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
13+
mh "github.com/multiformats/go-multihash"
914
)
1015

1116
type BlockAPI HttpApi
1217

13-
func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...options.BlockPutOption) (iface.BlockStat, error) {
14-
return nil, ErrNotImplemented
18+
type blockStat struct {
19+
Key string
20+
BSize int `json:"Size"`
21+
}
22+
23+
func (s *blockStat) Size() int {
24+
return s.BSize
25+
}
26+
27+
func (s *blockStat) valid() (iface.ResolvedPath, error) {
28+
c, err := cid.Parse(s.Key)
29+
if err != nil {
30+
return nil, err
31+
}
32+
33+
return iface.IpldPath(c), nil
34+
}
35+
36+
func (s *blockStat) Path() iface.ResolvedPath {
37+
p, _ := s.valid()
38+
return p
39+
}
40+
41+
func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) {
42+
options, _, err := caopts.BlockPutOptions(opts...)
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
mht, ok := mh.Codes[options.MhType]
48+
if !ok {
49+
return nil, fmt.Errorf("unknowm mhType %d", options.MhType)
50+
}
51+
52+
req := api.core().request("block/put").
53+
Option("mhtype", mht).
54+
Option("mhlen", options.MhLength).
55+
Option("format", options.Codec).
56+
FileBody(r)
57+
58+
var out blockStat
59+
if err := req.Exec(ctx, &out); err != nil {
60+
return nil, err
61+
}
62+
if _, err := out.valid(); err != nil {
63+
return nil, err
64+
}
65+
66+
return &out, nil
1567
}
1668

1769
func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) {
1870
resp, err := api.core().request("block/get", p.String()).Send(context.Background())
1971
if err != nil {
2072
return nil, err
2173
}
74+
if resp.Error != nil {
75+
return nil, resp.Error
76+
}
2277

23-
//TODO: is close on the reader enough?
24-
//defer resp.Close()
78+
//TODO: make get return ReadCloser to avoid copying
79+
defer resp.Close()
80+
b := new(bytes.Buffer)
81+
if _, err := io.Copy(b, resp.Output); err != nil {
82+
return nil, err
83+
}
2584

26-
//TODO: make blockApi return ReadCloser
27-
return resp.Output, resp.Error
85+
return b, nil
2886
}
2987

30-
func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...options.BlockRmOption) error {
31-
return ErrNotImplemented
88+
func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockRmOption) error {
89+
options, err := caopts.BlockRmOptions(opts...)
90+
if err != nil {
91+
return err
92+
}
93+
94+
removedBlock := struct {
95+
Hash string `json:",omitempty"`
96+
Error string `json:",omitempty"`
97+
}{}
98+
99+
req := api.core().request("block/rm").
100+
Option("force", options.Force).
101+
Arguments(p.String())
102+
103+
if err := req.Exec(ctx, &removedBlock); err != nil {
104+
return err
105+
}
106+
107+
if removedBlock.Error != "" {
108+
return errors.New(removedBlock.Error)
109+
}
110+
111+
return nil
32112
}
33113

34114
func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) {
35-
return nil, ErrNotImplemented
115+
var out blockStat
116+
err := api.core().request("block/stat", p.String()).Exec(ctx, &out)
117+
if err != nil {
118+
return nil, err
119+
}
120+
if _, err := out.valid(); err != nil {
121+
return nil, err
122+
}
123+
124+
return &out, nil
36125
}
37126

38127
func (api *BlockAPI) core() *HttpApi {

requestbuilder.go

+12
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import (
55
"context"
66
"fmt"
77
"io"
8+
"io/ioutil"
89
"strconv"
910
"strings"
11+
12+
"github.com/ipfs/go-ipfs-files"
1013
)
1114

1215
// RequestBuilder is an IPFS commands request builder.
@@ -42,6 +45,15 @@ func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder {
4245
return r
4346
}
4447

48+
// FileBody sets the request body to the given reader wrapped into multipartreader.
49+
func (r *RequestBuilder) FileBody(body io.Reader) *RequestBuilder {
50+
pr, _ := files.NewReaderPathFile("/dev/stdin", ioutil.NopCloser(body), nil)
51+
d := files.NewMapDirectory(map[string]files.Node{"": pr})
52+
r.body = files.NewMultiFileReader(d, false)
53+
54+
return r
55+
}
56+
4557
// Option sets the given option.
4658
func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder {
4759
var s string

0 commit comments

Comments
 (0)