1package server
2
3import (
4 "bytes"
5 "context"
6 "strings"
7
8 "github.com/bluesky-social/indigo/carstore"
9 "github.com/haileyok/cocoon/internal/helpers"
10 "github.com/ipfs/go-cid"
11 cbor "github.com/ipfs/go-ipld-cbor"
12 "github.com/ipld/go-car"
13 "github.com/labstack/echo/v4"
14)
15
16func (s *Server) handleGetBlocks(e echo.Context) error {
17 did := e.QueryParam("did")
18 cidsstr := e.QueryParam("cids")
19 if did == "" {
20 return helpers.InputError(e, nil)
21 }
22
23 cidstrs := strings.Split(cidsstr, ",")
24 cids := []cid.Cid{}
25
26 for _, cs := range cidstrs {
27 c, err := cid.Cast([]byte(cs))
28 if err != nil {
29 return err
30 }
31
32 cids = append(cids, c)
33 }
34
35 urepo, err := s.getRepoActorByDid(did)
36 if err != nil {
37 return helpers.ServerError(e, nil)
38 }
39
40 buf := new(bytes.Buffer)
41 rc, err := cid.Cast(urepo.Root)
42 if err != nil {
43 return err
44 }
45
46 hb, err := cbor.DumpObject(&car.CarHeader{
47 Roots: []cid.Cid{rc},
48 Version: 1,
49 })
50
51 if _, err := carstore.LdWrite(buf, hb); err != nil {
52 s.logger.Error("error writing to car", "error", err)
53 return helpers.ServerError(e, nil)
54 }
55
56 bs := s.getBlockstore(urepo.Repo.Did)
57
58 for _, c := range cids {
59 b, err := bs.Get(context.TODO(), c)
60 if err != nil {
61 return err
62 }
63
64 if _, err := carstore.LdWrite(buf, b.Cid().Bytes(), b.RawData()); err != nil {
65 return err
66 }
67 }
68
69 return e.Stream(200, "application/vnd.ipld.car", bytes.NewReader(buf.Bytes()))
70}