forked from hailey.at/cocoon
An atproto PDS written in Go
at main 1.5 kB view raw
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 14type ComAtprotoSyncGetBlocksRequest struct { 15 Did string `query:"did"` 16 Cids []string `query:"cids"` 17} 18 19func (s *Server) handleGetBlocks(e echo.Context) error { 20 ctx := e.Request().Context() 21 logger := s.logger.With("name", "handleSyncGetBlocks") 22 23 var req ComAtprotoSyncGetBlocksRequest 24 if err := e.Bind(&req); err != nil { 25 return helpers.InputError(e, nil) 26 } 27 28 var cids []cid.Cid 29 30 for _, cs := range req.Cids { 31 c, err := cid.Cast([]byte(cs)) 32 if err != nil { 33 return err 34 } 35 36 cids = append(cids, c) 37 } 38 39 urepo, err := s.getRepoActorByDid(ctx, req.Did) 40 if err != nil { 41 return helpers.ServerError(e, nil) 42 } 43 44 buf := new(bytes.Buffer) 45 rc, err := cid.Cast(urepo.Root) 46 if err != nil { 47 return err 48 } 49 50 hb, err := cbor.DumpObject(&car.CarHeader{ 51 Roots: []cid.Cid{rc}, 52 Version: 1, 53 }) 54 55 if _, err := carstore.LdWrite(buf, hb); err != nil { 56 logger.Error("error writing to car", "error", err) 57 return helpers.ServerError(e, nil) 58 } 59 60 bs := s.getBlockstore(urepo.Repo.Did) 61 62 for _, c := range cids { 63 b, err := bs.Get(ctx, c) 64 if err != nil { 65 return err 66 } 67 68 if _, err := carstore.LdWrite(buf, b.Cid().Bytes(), b.RawData()); err != nil { 69 return err 70 } 71 } 72 73 return e.Stream(200, "application/vnd.ipld.car", bytes.NewReader(buf.Bytes())) 74}