-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5789 from ipfs/kevina/multibase4
Add global option to specify the multibase encoding (server side)
- Loading branch information
Showing
33 changed files
with
905 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package cmdenv | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" | ||
cmds "gx/ipfs/QmWGm4AbZEbnmdgVTza52MSNpEmBdFVqzmAysRbjrRyGbH/go-ipfs-cmds" | ||
cidenc "gx/ipfs/QmdPQx9fvN5ExVwMhRmh7YpCQJzJrFhd1AjVBwJmRMFJeX/go-cidutil/cidenc" | ||
cmdkit "gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit" | ||
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase" | ||
) | ||
|
||
var OptionCidBase = cmdkit.StringOption("cid-base", "Multibase encoding used for version 1 CIDs in output.") | ||
var OptionUpgradeCidV0InOutput = cmdkit.BoolOption("upgrade-cidv0-in-output", "Upgrade version 0 to version 1 CIDs in output.") | ||
|
||
// GetCidEncoder processes the `cid-base` and `output-cidv1` options and | ||
// returns a encoder to use based on those parameters. | ||
func GetCidEncoder(req *cmds.Request) (cidenc.Encoder, error) { | ||
return getCidBase(req, true) | ||
} | ||
|
||
// GetLowLevelCidEncoder is like GetCidEncoder but meant to be used by | ||
// lower level commands. It differs from GetCidEncoder in that CIDv0 | ||
// are not, by default, auto-upgraded to CIDv1. | ||
func GetLowLevelCidEncoder(req *cmds.Request) (cidenc.Encoder, error) { | ||
return getCidBase(req, false) | ||
} | ||
|
||
func getCidBase(req *cmds.Request, autoUpgrade bool) (cidenc.Encoder, error) { | ||
base, _ := req.Options[OptionCidBase.Name()].(string) | ||
upgrade, upgradeDefined := req.Options[OptionUpgradeCidV0InOutput.Name()].(bool) | ||
|
||
e := cidenc.Default() | ||
|
||
if base != "" { | ||
var err error | ||
e.Base, err = mbase.EncoderByName(base) | ||
if err != nil { | ||
return e, err | ||
} | ||
if autoUpgrade { | ||
e.Upgrade = true | ||
} | ||
} | ||
|
||
if upgradeDefined { | ||
e.Upgrade = upgrade | ||
} | ||
|
||
return e, nil | ||
} | ||
|
||
// CidBaseDefined returns true if the `cid-base` option is specified | ||
// on the command line | ||
func CidBaseDefined(req *cmds.Request) bool { | ||
base, _ := req.Options["cid-base"].(string) | ||
return base != "" | ||
} | ||
|
||
// CidEncoderFromPath creates a new encoder that is influenced from | ||
// the encoded Cid in a Path. For CidV0 the multibase from the base | ||
// encoder is used and automatic upgrades are disabled. For CidV1 the | ||
// multibase from the CID is used and upgrades are enabled. | ||
// | ||
// This logic is intentionally fuzzy and will match anything of the form | ||
// `CidLike`, `CidLike/...`, or `/namespace/CidLike/...`. | ||
// | ||
// For example: | ||
// | ||
// * Qm... | ||
// * Qm.../... | ||
// * /ipfs/Qm... | ||
// * /ipns/bafybeiahnxfi7fpmr5wtxs2imx4abnyn7fdxeiox7xxjem6zuiioqkh6zi/... | ||
// * /bzz/bafybeiahnxfi7fpmr5wtxs2imx4abnyn7fdxeiox7xxjem6zuiioqkh6zi/... | ||
func CidEncoderFromPath(p string) (cidenc.Encoder, error) { | ||
components := strings.SplitN(p, "/", 4) | ||
|
||
var maybeCid string | ||
if components[0] != "" { | ||
// No leading slash, first component is likely CID-like. | ||
maybeCid = components[0] | ||
} else if len(components) < 3 { | ||
// Not enough components to include a CID. | ||
return cidenc.Encoder{}, fmt.Errorf("no cid in path: %s", p) | ||
} else { | ||
maybeCid = components[2] | ||
} | ||
c, err := cid.Decode(maybeCid) | ||
if err != nil { | ||
// Ok, not a CID-like thing. Keep the current encoder. | ||
return cidenc.Encoder{}, fmt.Errorf("no cid in path: %s", p) | ||
} | ||
if c.Version() == 0 { | ||
// Version 0, use the base58 non-upgrading encoder. | ||
return cidenc.Default(), nil | ||
} | ||
|
||
// Version 1+, extract multibase encoding. | ||
encoding, _, err := mbase.Decode(maybeCid) | ||
if err != nil { | ||
// This should be impossible, we've already decoded the cid. | ||
panic(fmt.Sprintf("BUG: failed to get multibase decoder for CID %s", maybeCid)) | ||
} | ||
|
||
return cidenc.Encoder{Base: mbase.MustNewEncoder(encoding), Upgrade: true}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package cmdenv | ||
|
||
import ( | ||
"testing" | ||
|
||
cidenc "gx/ipfs/QmdPQx9fvN5ExVwMhRmh7YpCQJzJrFhd1AjVBwJmRMFJeX/go-cidutil/cidenc" | ||
mbase "gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase" | ||
) | ||
|
||
func TestEncoderFromPath(t *testing.T) { | ||
test := func(path string, expected cidenc.Encoder) { | ||
actual, err := CidEncoderFromPath(path) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
if actual != expected { | ||
t.Errorf("CidEncoderFromPath(%s) failed: expected %#v but got %#v", path, expected, actual) | ||
} | ||
} | ||
p := "QmRqVG8VGdKZ7KARqR96MV7VNHgWvEQifk94br5HpURpfu" | ||
enc := cidenc.Default() | ||
test(p, enc) | ||
test(p+"/a", enc) | ||
test(p+"/a/b", enc) | ||
test(p+"/a/b/", enc) | ||
test(p+"/a/b/c", enc) | ||
test("/ipfs/"+p, enc) | ||
test("/ipfs/"+p+"/b", enc) | ||
|
||
p = "zb2rhfkM4FjkMLaUnygwhuqkETzbYXnUDf1P9MSmdNjW1w1Lk" | ||
enc = cidenc.Encoder{ | ||
Base: mbase.MustNewEncoder(mbase.Base58BTC), | ||
Upgrade: true, | ||
} | ||
test(p, enc) | ||
test(p+"/a", enc) | ||
test(p+"/a/b", enc) | ||
test(p+"/a/b/", enc) | ||
test(p+"/a/b/c", enc) | ||
test("/ipfs/"+p, enc) | ||
test("/ipfs/"+p+"/b", enc) | ||
test("/ipld/"+p, enc) | ||
test("/ipns/"+p, enc) // even IPNS should work. | ||
|
||
p = "bafyreifrcnyjokuw4i4ggkzg534tjlc25lqgt3ttznflmyv5fftdgu52hm" | ||
enc = cidenc.Encoder{ | ||
Base: mbase.MustNewEncoder(mbase.Base32), | ||
Upgrade: true, | ||
} | ||
test(p, enc) | ||
test("/ipfs/"+p, enc) | ||
test("/ipld/"+p, enc) | ||
|
||
for _, badPath := range []string{ | ||
"/ipld/", | ||
"/ipld", | ||
"/ipld//", | ||
"ipld//", | ||
"ipld", | ||
"", | ||
"ipns", | ||
"/ipfs/asdf", | ||
"/ipfs/...", | ||
"...", | ||
"abcdefg", | ||
"boo", | ||
} { | ||
_, err := CidEncoderFromPath(badPath) | ||
if err == nil { | ||
t.Errorf("expected error extracting encoder from bad path: %s", badPath) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.