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

Commit

Permalink
Block API
Browse files Browse the repository at this point in the history
  • Loading branch information
magik6k committed Jan 7, 2019
1 parent dfbe002 commit d0c98b8
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 13 deletions.
2 changes: 1 addition & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (api *HttpApi) Dag() iface.DagAPI {
}

func (api *HttpApi) Name() iface.NameAPI {
return (*NameAPI)(api)
return nil
}

func (api *HttpApi) Key() iface.KeyAPI {
Expand Down
11 changes: 9 additions & 2 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package httpapi
import (
"context"
"fmt"
"github.com/ipfs/iptb/testbed/interfaces"
"io/ioutil"
"os"
"path"
Expand All @@ -16,6 +15,7 @@ import (
local "github.com/ipfs/iptb-plugins/local"
"github.com/ipfs/iptb/cli"
"github.com/ipfs/iptb/testbed"
"github.com/ipfs/iptb/testbed/interfaces"
)

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

c := cli.NewCli()
if err := c.Run([]string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10), "--start"}); err != nil {

initArgs := []string{"iptb", "--IPTB_ROOT", dir, "auto", "-type", "localipfs", "-count", strconv.FormatInt(int64(n), 10)}
if err := c.Run(initArgs); err != nil {
return nil, err
}

startArgs := []string{"iptb", "--IPTB_ROOT", dir, "start", "-wait", "--", "--offline=" + strconv.FormatBool(n == 1)}
if err := c.Run(startArgs); err != nil {
return nil, err
}

Expand Down
109 changes: 99 additions & 10 deletions block.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,127 @@
package httpapi

import (
"bytes"
"context"
"errors"
"fmt"
"io"

"github.com/ipfs/go-cid"
"github.com/ipfs/go-ipfs/core/coreapi/interface"
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
mh "github.com/multiformats/go-multihash"
)

type BlockAPI HttpApi

func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...options.BlockPutOption) (iface.BlockStat, error) {
return nil, ErrNotImplemented
type blockStat struct {
Key string
BSize int `json:"Size"`
}

func (s *blockStat) Size() int {
return s.BSize
}

func (s *blockStat) valid() (iface.ResolvedPath, error) {
c, err := cid.Parse(s.Key)
if err != nil {
return nil, err
}

return iface.IpldPath(c), nil
}

func (s *blockStat) Path() iface.ResolvedPath {
p, _ := s.valid()
return p
}

func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockPutOption) (iface.BlockStat, error) {
options, _, err := caopts.BlockPutOptions(opts...)
if err != nil {
return nil, err
}

mht, ok := mh.Codes[options.MhType]
if !ok {
return nil, fmt.Errorf("unknowm mhType %d", options.MhType)
}

req := api.core().request("block/put").
Option("mhtype", mht).
Option("mhlen", options.MhLength).
Option("format", options.Codec).
FileBody(r)

var out blockStat
if err := req.Exec(ctx, &out); err != nil {
return nil, err
}
if _, err := out.valid(); err != nil {
return nil, err
}

return &out, nil
}

func (api *BlockAPI) Get(ctx context.Context, p iface.Path) (io.Reader, error) {
resp, err := api.core().request("block/get", p.String()).Send(context.Background())
if err != nil {
return nil, err
}
if resp.Error != nil {
return nil, resp.Error
}

//TODO: is close on the reader enough?
//defer resp.Close()
//TODO: make get return ReadCloser to avoid copying
defer resp.Close()
b := new(bytes.Buffer)
if _, err := io.Copy(b, resp.Output); err != nil {
return nil, err
}

//TODO: make blockApi return ReadCloser
return resp.Output, resp.Error
return b, nil
}

func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...options.BlockRmOption) error {
return ErrNotImplemented
func (api *BlockAPI) Rm(ctx context.Context, p iface.Path, opts ...caopts.BlockRmOption) error {
options, err := caopts.BlockRmOptions(opts...)
if err != nil {
return err
}

removedBlock := struct {
Hash string `json:",omitempty"`
Error string `json:",omitempty"`
}{}

req := api.core().request("block/rm").
Option("force", options.Force).
Arguments(p.String())

if err := req.Exec(ctx, &removedBlock); err != nil {
return err
}

if removedBlock.Error != "" {
return errors.New(removedBlock.Error)
}

return nil
}

func (api *BlockAPI) Stat(ctx context.Context, p iface.Path) (iface.BlockStat, error) {
return nil, ErrNotImplemented
var out blockStat
err := api.core().request("block/stat", p.String()).Exec(ctx, &out)
if err != nil {
return nil, err
}
if _, err := out.valid(); err != nil {
return nil, err
}

return &out, nil
}

func (api *BlockAPI) core() *HttpApi {
Expand Down
12 changes: 12 additions & 0 deletions requestbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import (
"context"
"fmt"
"io"
"io/ioutil"
"strconv"
"strings"

"github.com/ipfs/go-ipfs-files"
)

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

// FileBody sets the request body to the given reader wrapped into multipartreader.
func (r *RequestBuilder) FileBody(body io.Reader) *RequestBuilder {
pr, _ := files.NewReaderPathFile("/dev/stdin", ioutil.NopCloser(body), nil)
d := files.NewMapDirectory(map[string]files.Node{"": pr})
r.body = files.NewMultiFileReader(d, false)

return r
}

// Option sets the given option.
func (r *RequestBuilder) Option(key string, value interface{}) *RequestBuilder {
var s string
Expand Down

0 comments on commit d0c98b8

Please sign in to comment.