fork of indigo with slightly nicer lexgen
at main 2.3 kB view raw
1package visual 2 3import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "fmt" 8 "io" 9 "log/slog" 10 "net/http" 11 "time" 12 13 lexutil "github.com/bluesky-social/indigo/lex/util" 14 "github.com/bluesky-social/indigo/util" 15 16 "github.com/carlmjohnson/versioninfo" 17) 18 19type AbyssClient struct { 20 Client http.Client 21 Host string 22 Password string 23 RatelimitBypass string 24} 25 26func NewAbyssClient(host, password, ratelimitBypass string) AbyssClient { 27 return AbyssClient{ 28 Client: *util.RobustHTTPClient(), 29 Host: host, 30 Password: password, 31 RatelimitBypass: password, 32 } 33} 34 35func (ac *AbyssClient) ScanBlob(ctx context.Context, blob lexutil.LexBlob, blobBytes []byte, params map[string]string) (*AbyssScanResp, error) { 36 37 slog.Debug("sending blob to abyss", "cid", blob.Ref.String(), "mimetype", blob.MimeType, "size", len(blobBytes)) 38 39 body := bytes.NewBuffer(blobBytes) 40 req, err := http.NewRequest("POST", ac.Host+"/xrpc/com.atproto.unspecced.scanBlob", body) 41 if err != nil { 42 return nil, err 43 } 44 45 q := req.URL.Query() 46 for k, v := range params { 47 q.Add(k, v) 48 } 49 req.URL.RawQuery = q.Encode() 50 51 req.SetBasicAuth("admin", ac.Password) 52 req.Header.Add("Content-Type", blob.MimeType) 53 req.Header.Add("Content-Length", fmt.Sprintf("%d", blob.Size)) 54 req.Header.Set("Accept", "application/json") 55 req.Header.Set("User-Agent", "indigo-automod/"+versioninfo.Short()) 56 if ac.RatelimitBypass != "" { 57 req.Header.Set("x-ratelimit-bypass", ac.RatelimitBypass) 58 } 59 60 start := time.Now() 61 defer func() { 62 duration := time.Since(start) 63 abyssAPIDuration.Observe(duration.Seconds()) 64 }() 65 66 req = req.WithContext(ctx) 67 res, err := ac.Client.Do(req) 68 if err != nil { 69 return nil, fmt.Errorf("abyss request failed: %v", err) 70 } 71 defer res.Body.Close() 72 73 abyssAPICount.WithLabelValues(fmt.Sprint(res.StatusCode)).Inc() 74 if res.StatusCode != 200 { 75 return nil, fmt.Errorf("abyss request failed statusCode=%d", res.StatusCode) 76 } 77 78 respBytes, err := io.ReadAll(res.Body) 79 if err != nil { 80 return nil, fmt.Errorf("failed to read abyss resp body: %v", err) 81 } 82 83 var respObj AbyssScanResp 84 if err := json.Unmarshal(respBytes, &respObj); err != nil { 85 return nil, fmt.Errorf("failed to parse abyss resp JSON: %v", err) 86 } 87 slog.Info("abyss-scan-response", "cid", blob.Ref.String(), "obj", respObj) 88 return &respObj, nil 89}