Skip to content

Commit

Permalink
Attempt to preserve base of Cid's provided on the command line.
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
  • Loading branch information
kevina committed Sep 14, 2018
1 parent a2f4276 commit b50f7a7
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 105 deletions.
86 changes: 3 additions & 83 deletions core/apicid.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,11 @@ package core
import (
"encoding/json"

cidenc "github.com/ipfs/go-ipfs/core/cidenc"
cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
//path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
)

// CidEncoder is a type used to encode or recode Cid as the user
// specifies
type CidEncoder interface {
Encode(c cid.Cid) string
Recode(v string) (string, error)
}

// BasicCidEncoder is a basic CidEncoder that will encode Cid's using
// a specifed base, optionally upgrading a Cid if is Version 0
type BasicCidEncoder struct {
Base mbase.Encoder
Upgrade bool
}

var DefaultCidEncoder = BasicCidEncoder{
Base: mbase.MustNewEncoder(mbase.Base58BTC),
Upgrade: false,
}

// CidJSONBase is the base to use when Encoding into JSON.
//var CidJSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base58BTC)
var CidJSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base32)
Expand All @@ -47,10 +28,10 @@ func (c APICid) Cid() (cid.Cid, error) {
}

func (c APICid) String() string {
return c.Encode(DefaultCidEncoder)
return c.Encode(cidenc.Default)
}

func (c APICid) Encode(enc CidEncoder) string {
func (c APICid) Encode(enc cidenc.Interface) string {
if c.str == "" {
return ""
}
Expand All @@ -68,64 +49,3 @@ func (c *APICid) UnmarshalJSON(b []byte) error {
func (c APICid) MarshalJSON() ([]byte, error) {
return json.Marshal(c.str)
}

func (enc BasicCidEncoder) Encode(c cid.Cid) string {
if c.Version() == 0 {
c = cid.NewCidV1(c.Type(), c.Hash())
}
return c.Encode(enc.Base)
}

func (enc BasicCidEncoder) Recode(v string) (string, error) {
skip, err := enc.NoopRecode(v)
if skip || err != nil {
return v, err
}

c, err := cid.Decode(v)
if err != nil {
return v, err
}

return enc.Encode(c), nil
}

func (enc BasicCidEncoder) NoopRecode(v string) (bool, error) {
if len(v) < 2 {
return false, cid.ErrCidTooShort
}
ver := cidVer(v)
skip := ver == 0 && !enc.Upgrade || ver == 1 && v[0] == byte(enc.Base.Encoding())
return skip, nil
}

func cidVer(v string) int {
if len(v) == 46 && v[:2] == "Qm" {
return 0
} else {
return 1
}
}

// func (enc *CidEncoder) Scan(cids ...string) {
// if enc.Override == nil {
// enc.Override = map[cid.Cid]string{}
// }
// for _, p := range cids {
// //segs := path.FromString(p).Segments()
// //v := segs[0]
// //if v == "ipfs" && len(segs) > 0 {
// // v = segs[1]
// //}
// v := p
// skip, err := enc.noopRecode(v)
// if skip || err != nil {
// continue
// }
// c, err := cid.Decode(v)
// if err != nil {
// continue
// }
// enc.Override[c] = v
// }
// }
129 changes: 129 additions & 0 deletions core/cidenc/encoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package cidenc

import (
cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
)

// Encoder is a type used to encode or recode Cid as the user
// specifies
type Interface interface {
Encode(c cid.Cid) string
Recode(v string) (string, error)
}

// Basic is a basic Encoder that will encode Cid's using
// a specifed base, optionally upgrading a Cid if is Version 0
type Encoder struct {
Base mbase.Encoder
Upgrade bool
}

var Default = Encoder{
Base: mbase.MustNewEncoder(mbase.Base58BTC),
Upgrade: false,
}

func (enc Encoder) Encode(c cid.Cid) string {
if enc.Upgrade && c.Version() == 0 {
c = cid.NewCidV1(c.Type(), c.Hash())
}
return c.Encode(enc.Base)
}

func (enc Encoder) Recode(v string) (string, error) {
skip, err := enc.NoopRecode(v)
if skip || err != nil {
return v, err
}

c, err := cid.Decode(v)
if err != nil {
return v, err
}

return enc.Encode(c), nil
}

func (enc Encoder) NoopRecode(v string) (bool, error) {
if len(v) < 2 {
return false, cid.ErrCidTooShort
}
ver := cidVer(v)
skip := ver == 0 && !enc.Upgrade || ver == 1 && v[0] == byte(enc.Base.Encoding())
return skip, nil
}

func cidVer(v string) int {
if len(v) == 46 && v[:2] == "Qm" {
return 0
} else {
return 1
}
}

// On error an unmodified encoder will be returned so it is safe to
// ignore the error
func (enc Encoder) FromPath(p string) (Encoder, error) {
v := extractCidString(p)
if cidVer(v) == 0 {
return Encoder{enc.Base, false}, nil
}
e, err := mbase.NewEncoder(mbase.Encoding(v[0]))
if err != nil {
return enc, err
}
return Encoder{e, true}, nil
}

func extractCidString(p string) string {
segs := path.FromString(p).Segments()
v := segs[0]
if v == "ipfs" && len(segs) > 0 {
v = segs[1]
}
return v
}

type WithOverride struct {
base Encoder
override map[cid.Cid]string
}

func (enc Encoder) WithOverride(cids ...string) Interface {
override := map[cid.Cid]string{}
for _, p := range cids {
v := p
skip, err := enc.NoopRecode(v)
if skip || err != nil {
continue
}
c, err := cid.Decode(v)
if err != nil {
continue
}
override[c] = v
}
if len(override) == 0 {
return enc
}
return WithOverride{enc, override}
}

func (enc WithOverride) Encode(c cid.Cid) string {
v, ok := enc.override[c]
if ok {
return v
}
return enc.base.Encode(c)
}

func (enc WithOverride) Recode(v string) (string, error) {
c, err := cid.Decode(v)
if err != nil {
return v, err
}

return enc.Encode(c), nil
}
2 changes: 1 addition & 1 deletion core/commands/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ You can now check what blocks have been created by:
log.Warning("cannot determine size of input file")
}

err := HandleCidBase(req)
_, err := HandleCidBase(nil, req)
if err != nil {
re.SetError(err, cmdkit.ErrNormal)
return re
Expand Down
2 changes: 1 addition & 1 deletion core/commands/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ The JSON output contains type information.
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
err := HandleCidBaseLegacy(res.Request())
_, err := HandleCidBaseLegacy(nil, res.Request())
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions core/commands/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ var addPinCmd = &cmds.Command{
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
err := HandleCidBaseLegacy(res.Request())
enc, err := HandleCidBaseWithOverrideLegacy(res.Request())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -167,7 +167,7 @@ var addPinCmd = &cmds.Command{

buf := new(bytes.Buffer)
for _, k := range added {
fmt.Fprintf(buf, "pinned %s %s\n", k, pintype)
fmt.Fprintf(buf, "pinned %s %s\n", k.Encode(enc), pintype)
}
return buf, nil
},
Expand Down Expand Up @@ -214,7 +214,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
err := HandleCidBaseLegacy(res.Request())
enc, err := HandleCidBaseWithOverrideLegacy(res.Request())
if err != nil {
return nil, err
}
Expand All @@ -230,7 +230,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)

buf := new(bytes.Buffer)
for _, k := range added.Pins {
fmt.Fprintf(buf, "unpinned %s\n", k)
fmt.Fprintf(buf, "unpinned %s\n", k.Encode(enc))
}
return buf, nil
},
Expand Down Expand Up @@ -326,7 +326,7 @@ Example:
Type: RefKeyList{},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
err := HandleCidBaseLegacy(res.Request())
_, err := HandleCidBaseLegacy(nil, res.Request())
if err != nil {
return nil, err
}
Expand Down
13 changes: 12 additions & 1 deletion core/commands/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

cmds "github.com/ipfs/go-ipfs/commands"
"github.com/ipfs/go-ipfs/core"
cidenc "github.com/ipfs/go-ipfs/core/cidenc"
e "github.com/ipfs/go-ipfs/core/commands/e"
ncmd "github.com/ipfs/go-ipfs/core/commands/name"
ns "github.com/ipfs/go-ipfs/namesys"
Expand Down Expand Up @@ -84,6 +85,16 @@ Resolve the value of an IPFS DAG path:
name := req.Arguments()[0]
recursive, _, _ := req.Option("recursive").Bool()

enc := cidenc.Default // make local copy
defined, err := HandleCidBaseLegacy(&enc, req)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
if !defined {
enc, _ = enc.FromPath(name)
}

// the case when ipns is resolved step by step
if strings.HasPrefix(name, "/ipns/") && !recursive {
rc, rcok, _ := req.Option("dht-record-count").Int()
Expand Down Expand Up @@ -129,7 +140,7 @@ Resolve the value of an IPFS DAG path:

c := node.Cid()

res.SetOutput(&ncmd.ResolvedPath{Path: path.FromCid(c)})
res.SetOutput(&ncmd.ResolvedPath{Path: path.FromString("/ipfs/" + enc.Encode(c))})
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
Expand Down
Loading

0 comments on commit b50f7a7

Please sign in to comment.