mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-23 03:17:43 +08:00
Implement Object API
This commit was moved from ipfs/go-ipfs-http-client@38149e46c8
This commit is contained in:
parent
9d647d011e
commit
eaa19388d4
@ -67,7 +67,7 @@ func (api *BlockAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.BlockP
|
||||
}
|
||||
|
||||
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())
|
||||
resp, err := api.core().request("block/get", p.String()).Send(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package httpapi
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
|
||||
@ -20,11 +19,11 @@ type ipldNode struct {
|
||||
api *HttpApi
|
||||
}
|
||||
|
||||
func (a *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node {
|
||||
func (api *HttpApi) nodeFromPath(ctx context.Context, p iface.ResolvedPath) ipld.Node {
|
||||
return &ipldNode{
|
||||
ctx: ctx,
|
||||
path: p,
|
||||
api: a,
|
||||
api: api,
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +46,7 @@ func (n *ipldNode) Cid() cid.Cid {
|
||||
}
|
||||
|
||||
func (n *ipldNode) String() string {
|
||||
return fmt.Sprintf("[Block %s]", n.Cid())
|
||||
return n.Cid().String()
|
||||
}
|
||||
|
||||
func (n *ipldNode) Loggable() map[string]interface{} {
|
||||
|
||||
@ -59,10 +59,10 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
var out struct{
|
||||
Was string
|
||||
Now string
|
||||
Id string
|
||||
var out struct {
|
||||
Was string
|
||||
Now string
|
||||
Id string
|
||||
Overwrite bool
|
||||
}
|
||||
err = api.core().request("key/rename", oldName, newName).
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/ipfs/go-cid"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-ipld-format"
|
||||
"github.com/ipfs/go-merkledag"
|
||||
)
|
||||
|
||||
type ObjectAPI HttpApi
|
||||
@ -37,44 +40,219 @@ func (api *ObjectAPI) New(ctx context.Context, opts ...caopts.ObjectNewOption) (
|
||||
return api.core().nodeFromPath(ctx, iface.IpfsPath(c)), nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Put(context.Context, io.Reader, ...caopts.ObjectPutOption) (iface.ResolvedPath, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) Put(ctx context.Context, r io.Reader, opts ...caopts.ObjectPutOption) (iface.ResolvedPath, error) {
|
||||
options, err := caopts.ObjectPutOptions(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out objectOut
|
||||
err = api.core().request("object/put").
|
||||
Option("inputenc", options.InputEnc).
|
||||
Option("datafieldenc", options.DataType).
|
||||
Option("pin", options.Pin).
|
||||
FileBody(r).
|
||||
Exec(ctx, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := cid.Parse(out.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iface.IpfsPath(c), nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Get(context.Context, iface.Path) (format.Node, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) Get(ctx context.Context, p iface.Path) (format.Node, error) {
|
||||
r, err := api.core().Block().Get(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return merkledag.DecodeProtobuf(b)
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Data(context.Context, iface.Path) (io.Reader, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) Data(ctx context.Context, p iface.Path) (io.Reader, error) {
|
||||
resp, err := api.core().request("object/data", p.String()).Send(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Error != nil {
|
||||
return nil, resp.Error
|
||||
}
|
||||
|
||||
//TODO: make Data return ReadCloser to avoid copying
|
||||
defer resp.Close()
|
||||
b := new(bytes.Buffer)
|
||||
if _, err := io.Copy(b, resp.Output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Links(context.Context, iface.Path) ([]*format.Link, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) Links(ctx context.Context, p iface.Path) ([]*format.Link, error) {
|
||||
var out struct {
|
||||
Links []struct {
|
||||
Name string
|
||||
Hash string
|
||||
Size uint64
|
||||
}
|
||||
}
|
||||
if err := api.core().request("object/links", p.String()).Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*format.Link, len(out.Links))
|
||||
for i, l := range out.Links {
|
||||
c, err := cid.Parse(l.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res[i] = &format.Link{
|
||||
Cid: c,
|
||||
Name: l.Name,
|
||||
Size: l.Size,
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Stat(context.Context, iface.Path) (*iface.ObjectStat, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) Stat(ctx context.Context, p iface.Path) (*iface.ObjectStat, error) {
|
||||
var out struct {
|
||||
Hash string
|
||||
NumLinks int
|
||||
BlockSize int
|
||||
LinksSize int
|
||||
DataSize int
|
||||
CumulativeSize int
|
||||
}
|
||||
if err := api.core().request("object/stat", p.String()).Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := cid.Parse(out.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &iface.ObjectStat{
|
||||
Cid: c,
|
||||
NumLinks: out.NumLinks,
|
||||
BlockSize: out.BlockSize,
|
||||
LinksSize: out.LinksSize,
|
||||
DataSize: out.DataSize,
|
||||
CumulativeSize: out.CumulativeSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) AddLink(ctx context.Context, base iface.Path, name string, child iface.Path, opts ...caopts.ObjectAddLinkOption) (iface.ResolvedPath, error) {
|
||||
panic("implement me")
|
||||
options, err := caopts.ObjectAddLinkOptions(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out objectOut
|
||||
err = api.core().request("object/patch/add-link", base.String(), name, child.String()).
|
||||
Option("create", options.Create).
|
||||
Exec(ctx, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := cid.Parse(out.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iface.IpfsPath(c), nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) RmLink(ctx context.Context, base iface.Path, link string) (iface.ResolvedPath, error) {
|
||||
panic("implement me")
|
||||
var out objectOut
|
||||
err := api.core().request("object/patch/rm-link", base.String(), link).
|
||||
Exec(ctx, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := cid.Parse(out.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iface.IpfsPath(c), nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) AppendData(context.Context, iface.Path, io.Reader) (iface.ResolvedPath, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) AppendData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) {
|
||||
var out objectOut
|
||||
err := api.core().request("object/patch/append-data", p.String()).
|
||||
FileBody(r).
|
||||
Exec(ctx, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := cid.Parse(out.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iface.IpfsPath(c), nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) SetData(context.Context, iface.Path, io.Reader) (iface.ResolvedPath, error) {
|
||||
panic("implement me")
|
||||
func (api *ObjectAPI) SetData(ctx context.Context, p iface.Path, r io.Reader) (iface.ResolvedPath, error) {
|
||||
var out objectOut
|
||||
err := api.core().request("object/patch/set-data", p.String()).
|
||||
FileBody(r).
|
||||
Exec(ctx, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := cid.Parse(out.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iface.IpfsPath(c), nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Diff(context.Context, iface.Path, iface.Path) ([]iface.ObjectChange, error) {
|
||||
panic("implement me")
|
||||
type change struct {
|
||||
Type iface.ChangeType
|
||||
Path string
|
||||
Before cid.Cid
|
||||
After cid.Cid
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) Diff(ctx context.Context, a iface.Path, b iface.Path) ([]iface.ObjectChange, error) {
|
||||
var out struct {
|
||||
Changes []change
|
||||
}
|
||||
if err := api.core().request("object/diff", a.String(), b.String()).Exec(ctx, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]iface.ObjectChange, len(out.Changes))
|
||||
for i, ch := range out.Changes {
|
||||
res[i] = iface.ObjectChange{
|
||||
Type: ch.Type,
|
||||
Path: ch.Path,
|
||||
}
|
||||
if ch.Before != cid.Undef {
|
||||
res[i].Before = iface.IpfsPath(ch.Before)
|
||||
}
|
||||
if ch.After != cid.Undef {
|
||||
res[i].After = iface.IpfsPath(ch.After)
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (api *ObjectAPI) core() *HttpApi {
|
||||
|
||||
@ -83,8 +83,8 @@ func (api *PinAPI) Update(ctx context.Context, from iface.Path, to iface.Path, o
|
||||
}
|
||||
|
||||
type pinVerifyRes struct {
|
||||
Cid string
|
||||
JOk bool `json:"Ok"`
|
||||
Cid string
|
||||
JOk bool `json:"Ok"`
|
||||
JBadNodes []*badNode `json:"BadNodes,omitempty"`
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ func (r *pinVerifyRes) BadNodes() []iface.BadPinNode {
|
||||
}
|
||||
|
||||
type badNode struct {
|
||||
Cid string
|
||||
Cid string
|
||||
JErr string `json:"Err"`
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user