An atproto PDS written in Go
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}