This repository has no description
2.3 kB
79 lines
1package xrpc
2
3import (
4 "fmt"
5 "net/http"
6
7 "github.com/bluesky-social/indigo/atproto/atclient"
8 "github.com/bluesky-social/indigo/atproto/syntax"
9 "tangled.org/core/api/tangled"
10 "tangled.org/core/gitutil"
11 "tangled.org/core/knotmirror/db"
12 "tangled.org/core/knotmirror/xrpc/gitea"
13)
14
15func (x *Xrpc) GetArchive(w http.ResponseWriter, r *http.Request) {
16 invalid := func(err error) {
17 writeJson(w, http.StatusBadRequest, atclient.ErrorBody{Name: "InvalidRequest", Message: err.Error()})
18 }
19
20 repoQuery := r.URL.Query().Get("repo")
21 repo, err := syntax.ParseDID(repoQuery)
22 if err != nil {
23 invalid(fmt.Errorf("repo parameter invalid: %s", repoQuery))
24 return
25 }
26
27 params, err := gitutil.ParseArchiveParams(r.URL.Query())
28 if err != nil {
29 invalid(err)
30 return
31 }
32
33 l := x.logger.With("repo", repo, "ref", params.Rev, "format", params.Format, "prefix", params.Prefix)
34 l.Debug("request")
35
36 ctx := r.Context()
37 proxy := func(err error, message string) {
38 l.Warn("local mirror failed, trying proxy", "err", err)
39 if !x.proxyToKnot(w, r, repo) {
40 writeJson(w, http.StatusInternalServerError, atclient.ErrorBody{Name: "InternalServerError", Message: message})
41 }
42 }
43
44 repoPath, err := x.makeRepoPath(ctx, repo)
45 if err != nil {
46 proxy(err, "failed to resolve repo")
47 return
48 }
49
50 commit, err := gitea.GetCommit(ctx, repoPath, params.Rev.Or(gitutil.RevHead).String())
51 if err != nil {
52 proxy(err, "failed to resolve ref")
53 return
54 }
55
56 mirrored, err := db.GetRepoByRepoDid(ctx, x.db, repo)
57 if err == nil && mirrored == nil {
58 err = fmt.Errorf("repo not found: %s", repo)
59 }
60 if err != nil {
61 proxy(err, "failed to retrieve repo name")
62 return
63 }
64
65 name := gitutil.RepoName(mirrored.Name)
66 resolvedRev := gitutil.RevFromHash(commit.Hash)
67 params.Rev = params.Rev.OrHash(commit.Hash)
68 params.Prefix = params.Prefix.OrDefault(name, params.Rev)
69
70 params.SetHeaders(w.Header(), name)
71 w.Header().Set("Link", gitutil.ImmutableLink(fmt.Sprintf("%s/xrpc/%s?%s",
72 x.cfg.BaseUrl(), tangled.GitTempGetArchiveNSID, params.WithRev(resolvedRev).Query(repo.String()).Encode(),
73 )))
74
75 if err := gitutil.WriteArchive(ctx, w, repoPath, resolvedRev, params.Format, params.Prefix); err != nil {
76 l.Error("writing archive", "err", err.Error(), "format", params.Format)
77 w.WriteHeader(http.StatusInternalServerError)
78 }
79}