@cryptotaxi247 / kubo / commits / e8da6e2cf

Block API

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

Łukasz Magiera committed Jan 7, 2019 at 23:44 UTC e8da6e2cf9a8fd40c5fd960a60ce1b1b27ada713
4 files changed +121 -13
client/httpapi/api.go
+1 -1
@@ -118,7 +118,7 @@ func (api *HttpApi) Dag() iface.DagAPI {
118 }
119
120 func (api *HttpApi) Name() iface.NameAPI {
121 - return (*NameAPI)(api)
121 + return nil
122 }
123
124 func (api *HttpApi) Key() iface.KeyAPI {
client/httpapi/api_test.go
+9 -2
@@ -3,7 +3,6 @@ package httpapi
3 import (
4 "context"
5 "fmt"
6 - "github.com/ipfs/iptb/testbed/interfaces"
6 "io/ioutil"
7 "os"
8 "path"
@@ -16,6 +15,7 @@ import (
15 local "github.com/ipfs/iptb-plugins/local"
16 "github.com/ipfs/iptb/cli"
17 "github.com/ipfs/iptb/testbed"
18 + "github.com/ipfs/iptb/testbed/interfaces"
19 )
20
21 type NodeProvider struct{}
@@ -39,7 +39,14 @@ func (NodeProvider) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int)
39 }
40
41 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 {
50 return nil, err
51 }
52
client/httpapi/block.go
+99 -10
@@ -1,17 +1,69 @@
1 package httpapi
2
3 import (
4 + "bytes"
5 "context"
6 + "errors"
7 + "fmt"
8 "io"
9
10 + "github.com/ipfs/go-cid"
11 "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"
14 )
15
16 type BlockAPI HttpApi
17
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
67 }
68
69 func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) {
@@ -19,20 +71,57 @@ func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) {
71 if err != nil {
72 return nil, err
73 }
74 + if resp.Error != nil {
75 + return nil, resp.Error
76 + }
77
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 + }
84
26 - //TODO: make blockApi return ReadCloser
27 - return resp.Output, resp.Error
85 + return b, nil
86 }
87
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
112 }
113
114 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
125 }
126
127 func (api *BlockAPI) core() *HttpApi {
client/httpapi/requestbuilder.go
+12
@@ -5,8 +5,11 @@ import (
5 "context"
6 "fmt"
7 "io"
8 + "io/ioutil"
9 "strconv"
10 "strings"
11 +
12 + "github.com/ipfs/go-ipfs-files"
13 )
14
15 // RequestBuilder is an IPFS commands request builder.
@@ -42,6 +45,15 @@ func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder {
45 return r
46 }
47
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 +
57 // Option sets the given option.
58 func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder {
59 var s string