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