1package server
2
3import (
4 "bytes"
5
6 "github.com/bluesky-social/indigo/carstore"
7 "github.com/haileyok/cocoon/internal/helpers"
8 "github.com/ipfs/go-cid"
9 cbor "github.com/ipfs/go-ipld-cbor"
10 "github.com/ipld/go-car"
11 "github.com/labstack/echo/v4"
12)
13
14func (s *Server) handleGetBlocks(e echo.Context) error {
15 ctx := e.Request().Context()
16 did := e.QueryParam("did")
17 if did == "" {
18 return helpers.InputError(e, nil)
19 }
20
21 cidstrs, ok := e.QueryParams()["cids"]
22 if !ok {
23 return helpers.InputError(e, nil)
24 }
25 var 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 := s.getBlockstore(urepo.Repo.Did)
58
59 for _, c := range cids {
60 b, err := bs.Get(ctx, 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}