| 1 | package dagcmd |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "io" |
| 6 | |
| 7 | "github.com/ipfs/boxo/path" |
| 8 | ipldlegacy "github.com/ipfs/go-ipld-legacy" |
| 9 | "github.com/ipfs/kubo/core/commands/cmdenv" |
| 10 | "github.com/ipfs/kubo/core/commands/cmdutils" |
| 11 | |
| 12 | "github.com/ipld/go-ipld-prime" |
| 13 | "github.com/ipld/go-ipld-prime/multicodec" |
| 14 | "github.com/ipld/go-ipld-prime/traversal" |
| 15 | mc "github.com/multiformats/go-multicodec" |
| 16 | |
| 17 | cmds "github.com/ipfs/go-ipfs-cmds" |
| 18 | ) |
| 19 | |
| 20 | func dagGet(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { |
| 21 | api, err := cmdenv.GetApi(env, req) |
| 22 | if err != nil { |
| 23 | return err |
| 24 | } |
| 25 | |
| 26 | codecStr, _ := req.Options["output-codec"].(string) |
| 27 | var codec mc.Code |
| 28 | if err := codec.Set(codecStr); err != nil { |
| 29 | return err |
| 30 | } |
| 31 | |
| 32 | p, err := cmdutils.PathOrCidPath(req.Arguments[0]) |
| 33 | if err != nil { |
| 34 | return err |
| 35 | } |
| 36 | |
| 37 | rp, remainder, err := api.ResolvePath(req.Context, p) |
| 38 | if err != nil { |
| 39 | return err |
| 40 | } |
| 41 | |
| 42 | obj, err := api.Dag().Get(req.Context, rp.RootCid()) |
| 43 | if err != nil { |
| 44 | return err |
| 45 | } |
| 46 | |
| 47 | universal, ok := obj.(ipldlegacy.UniversalNode) |
| 48 | if !ok { |
| 49 | return fmt.Errorf("%T is not a valid IPLD node", obj) |
| 50 | } |
| 51 | |
| 52 | finalNode := universal.(ipld.Node) |
| 53 | |
| 54 | if len(remainder) > 0 { |
| 55 | remainderPath := ipld.ParsePath(path.SegmentsToString(remainder...)) |
| 56 | |
| 57 | finalNode, err = traversal.Get(finalNode, remainderPath) |
| 58 | if err != nil { |
| 59 | return err |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | encoder, err := multicodec.LookupEncoder(uint64(codec)) |
| 64 | if err != nil { |
| 65 | return fmt.Errorf("invalid encoding: %s - %s", codec, err) |
| 66 | } |
| 67 | |
| 68 | r, w := io.Pipe() |
| 69 | go func() { |
| 70 | defer w.Close() |
| 71 | if err := encoder(finalNode, w); err != nil { |
| 72 | _ = w.CloseWithError(err) |
| 73 | } |
| 74 | }() |
| 75 | |
| 76 | return res.Emit(r) |
| 77 | } |