An atproto PDS written in Go
at 0.3 1.4 kB view raw
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}