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