master
go 171 lines 4.46 KB
Raw
1 package commands
2
3 import (
4 "bytes"
5 "fmt"
6 "io"
7 "strings"
8
9 cmds "github.com/ipfs/go-ipfs-cmds"
10 "github.com/ipfs/kubo/core/commands/cmdenv"
11 mbase "github.com/multiformats/go-multibase"
12 )
13
14 var MbaseCmd = &cmds.Command{
15 Helptext: cmds.HelpText{
16 Tagline: "Encode and decode files or stdin with multibase format",
17 },
18 Subcommands: map[string]*cmds.Command{
19 "encode": mbaseEncodeCmd,
20 "decode": mbaseDecodeCmd,
21 "transcode": mbaseTranscodeCmd,
22 "list": basesCmd,
23 },
24 Extra: CreateCmdExtras(SetDoesNotUseRepo(true)),
25 }
26
27 const (
28 mbaseOptionName = "b"
29 )
30
31 var mbaseEncodeCmd = &cmds.Command{
32 Helptext: cmds.HelpText{
33 Tagline: "Encode data into multibase string",
34 LongDescription: `
35 This command expects a file name or data provided via stdin.
36
37 By default it will use URL-safe base64url encoding,
38 but one can customize used base with -b:
39
40 > echo hello | ipfs multibase encode -b base16 > output_file
41 > cat output_file
42 f68656c6c6f0a
43
44 > echo hello > input_file
45 > ipfs multibase encode -b base16 input_file
46 f68656c6c6f0a
47 `,
48 },
49 Arguments: []cmds.Argument{
50 cmds.FileArg("file", true, false, "data to encode").EnableStdin(),
51 },
52 Options: []cmds.Option{
53 cmds.StringOption(mbaseOptionName, "multibase encoding").WithDefault("base64url"),
54 },
55 Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error {
56 if err := req.ParseBodyArgs(); err != nil {
57 return err
58 }
59 encoderName, _ := req.Options[mbaseOptionName].(string)
60 encoder, err := mbase.EncoderByName(encoderName)
61 if err != nil {
62 return err
63 }
64 files := req.Files.Entries()
65 file, err := cmdenv.GetFileArg(files)
66 if err != nil {
67 return fmt.Errorf("failed to access file: %w", err)
68 }
69 buf, err := io.ReadAll(file)
70 if err != nil {
71 return fmt.Errorf("failed to read file contents: %w", err)
72 }
73 encoded := encoder.Encode(buf)
74 reader := strings.NewReader(encoded)
75 return resp.Emit(reader)
76 },
77 }
78
79 var mbaseDecodeCmd = &cmds.Command{
80 Helptext: cmds.HelpText{
81 Tagline: "Decode multibase string",
82 LongDescription: `
83 This command expects multibase inside of a file or via stdin:
84
85 > echo -n hello | ipfs multibase encode -b base16 > file
86 > cat file
87 f68656c6c6f
88
89 > ipfs multibase decode file
90 hello
91
92 > cat file | ipfs multibase decode
93 hello
94 `,
95 },
96 Arguments: []cmds.Argument{
97 cmds.FileArg("encoded_file", true, false, "encoded data to decode").EnableStdin(),
98 },
99 Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error {
100 if err := req.ParseBodyArgs(); err != nil {
101 return err
102 }
103 files := req.Files.Entries()
104 file, err := cmdenv.GetFileArg(files)
105 if err != nil {
106 return fmt.Errorf("failed to access file: %w", err)
107 }
108 encodedData, err := io.ReadAll(file)
109 if err != nil {
110 return fmt.Errorf("failed to read file contents: %w", err)
111 }
112 _, data, err := mbase.Decode(string(encodedData))
113 if err != nil {
114 return fmt.Errorf("failed to decode multibase: %w", err)
115 }
116 reader := bytes.NewReader(data)
117 return resp.Emit(reader)
118 },
119 }
120
121 var mbaseTranscodeCmd = &cmds.Command{
122 Helptext: cmds.HelpText{
123 Tagline: "Transcode multibase string between bases",
124 LongDescription: `
125 This command expects multibase inside of a file or via stdin.
126
127 By default it will use URL-safe base64url encoding,
128 but one can customize used base with -b:
129
130 > echo -n hello | ipfs multibase encode > file
131 > cat file
132 uaGVsbG8
133
134 > ipfs multibase transcode file -b base16 > transcoded_file
135 > cat transcoded_file
136 f68656c6c6f
137 `,
138 },
139 Arguments: []cmds.Argument{
140 cmds.FileArg("encoded_file", true, false, "encoded data to decode").EnableStdin(),
141 },
142 Options: []cmds.Option{
143 cmds.StringOption(mbaseOptionName, "multibase encoding").WithDefault("base64url"),
144 },
145 Run: func(req *cmds.Request, resp cmds.ResponseEmitter, env cmds.Environment) error {
146 if err := req.ParseBodyArgs(); err != nil {
147 return err
148 }
149 encoderName, _ := req.Options[mbaseOptionName].(string)
150 encoder, err := mbase.EncoderByName(encoderName)
151 if err != nil {
152 return err
153 }
154 files := req.Files.Entries()
155 file, err := cmdenv.GetFileArg(files)
156 if err != nil {
157 return fmt.Errorf("failed to access file: %w", err)
158 }
159 encodedData, err := io.ReadAll(file)
160 if err != nil {
161 return fmt.Errorf("failed to read file contents: %w", err)
162 }
163 _, data, err := mbase.Decode(string(encodedData))
164 if err != nil {
165 return fmt.Errorf("failed to decode multibase: %w", err)
166 }
167 encoded := encoder.Encode(data)
168 reader := strings.NewReader(encoded)
169 return resp.Emit(reader)
170 },
171 }