Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

at master 2.9 kB View raw
1package xrpc 2 3import ( 4 "database/sql" 5 "encoding/json" 6 "errors" 7 "log/slog" 8 "net/http" 9 "time" 10 11 "github.com/bluesky-social/indigo/atproto/atclient" 12 "github.com/bluesky-social/indigo/util/ssrf" 13 "github.com/go-chi/chi/v5" 14 "github.com/redis/go-redis/v9" 15 "tangled.org/core/api/tangled" 16 "tangled.org/core/idresolver" 17 "tangled.org/core/knotmirror/config" 18 "tangled.org/core/knotmirror/knotstream" 19 "tangled.org/core/log" 20) 21 22type Xrpc struct { 23 cfg *config.Config 24 db *sql.DB 25 rdb *redis.Client 26 resolver *idresolver.Resolver 27 ks *knotstream.KnotStream 28 logger *slog.Logger 29 httpClient *http.Client 30 inflight *inflightTracker 31} 32 33func New(logger *slog.Logger, cfg *config.Config, db *sql.DB, rdb *redis.Client, resolver *idresolver.Resolver, ks *knotstream.KnotStream) *Xrpc { 34 httpClient := &http.Client{ 35 Timeout: 30 * time.Second, 36 } 37 if cfg.KnotSSRF { 38 httpClient.Transport = ssrf.PublicOnlyTransport() 39 } 40 return &Xrpc{ 41 cfg: cfg, 42 db: db, 43 rdb: rdb, 44 resolver: resolver, 45 ks: ks, 46 logger: log.SubLogger(logger, "xrpc"), 47 httpClient: httpClient, 48 inflight: newInflightTracker(), 49 } 50} 51 52func (x *Xrpc) Router() http.Handler { 53 r := chi.NewRouter() 54 r.Use(metricsMiddleware) 55 56 r.Group(func(r chi.Router) { 57 r.Use(x.inflight.middleware) 58 59 r.Get("/"+tangled.GitTempGetArchiveNSID, x.GetArchive) 60 r.Get("/"+tangled.GitTempGetBlobNSID, x.GetBlob) 61 r.Get("/"+tangled.GitTempGetBranchNSID, x.GetBranch) 62 // r.Get("/"+tangled.GitTempGetCommitNSID, x.GetCommit) // todo 63 // r.Get("/"+tangled.GitTempGetDiffNSID, x.GetDiff) // todo 64 // r.Get("/"+tangled.GitTempGetEntityNSID, x.GetEntity) // todo 65 // r.Get("/"+tangled.GitTempGetHeadNSID, x.GetHead) // todo 66 r.Get("/"+tangled.GitTempGetTagNSID, x.GetTag) // using types.Response 67 r.Get("/"+tangled.GitTempGetTreeNSID, x.GetTree) 68 r.Get("/"+tangled.GitTempListBranchesNSID, x.ListBranches) // wip, unknown output 69 r.Get("/"+tangled.GitTempListCommitsNSID, x.ListCommits) 70 r.Get("/"+tangled.GitTempListLanguagesNSID, x.ListLanguages) 71 r.Get("/"+tangled.GitTempListTagsNSID, x.ListTags) 72 r.Get("/"+tangled.RepoBlobNSID, x.RepoBlob) 73 r.Post("/"+tangled.SyncRequestCrawlNSID, x.RequestCrawl) 74 }) 75 76 return r 77} 78 79func writeJson(w http.ResponseWriter, status int, response any) error { 80 w.Header().Set("Content-Type", "application/json") 81 w.WriteHeader(status) 82 if err := json.NewEncoder(w).Encode(response); err != nil { 83 return err 84 } 85 return nil 86} 87 88func writeErr(w http.ResponseWriter, err error) error { 89 var apiErr *atclient.APIError 90 if errors.As(err, &apiErr) { 91 return writeJson(w, apiErr.StatusCode, atclient.ErrorBody{Name: apiErr.Name, Message: apiErr.Message}) 92 } 93 return writeJson(w, http.StatusInternalServerError, atclient.ErrorBody{Name: "InternalServerError", Message: "internal server error"}) 94}