Monorepo for Tangled
tangled.org
1package blobstore
2
3import (
4 "context"
5 "fmt"
6 "io"
7 "net/http"
8 "net/url"
9
10 "github.com/bluesky-social/indigo/atproto/identity"
11 "github.com/bluesky-social/indigo/atproto/syntax"
12 "github.com/ipfs/go-cid"
13)
14
15type Pds struct {
16 dir identity.Directory
17}
18
19func NewPdsBlobStore(dir identity.Directory) *Pds {
20 return &Pds{dir}
21}
22
23var _ BlobStore = (*Pds)(nil)
24
25func (s *Pds) MakeBlobUrl(ctx context.Context, did syntax.DID, cid cid.Cid) (string, error) {
26 id, err := s.dir.LookupDID(ctx, did)
27 if err != nil {
28 return "", err
29 }
30
31 url, _ := url.Parse(fmt.Sprintf("%s/xrpc/com.atproto.sync.getBlob", id.PDSEndpoint()))
32 q := url.Query()
33 q.Set("did", did.String())
34 q.Set("cid", cid.String())
35 url.RawQuery = q.Encode()
36
37 return url.String(), nil
38}
39
40func (s *Pds) GetBlob(ctx context.Context, did syntax.DID, cid cid.Cid) (io.ReadCloser, error) {
41 url, err := s.MakeBlobUrl(ctx, did, cid)
42 if err != nil {
43 return nil, err
44 }
45
46 req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
47 resp, err := http.DefaultClient.Do(req)
48 if err != nil {
49 return nil, err
50 }
51
52 if resp.StatusCode != http.StatusOK {
53 return nil, fmt.Errorf("unexpected status: %s", resp.Status)
54 }
55
56 return resp.Body, nil
57}