···
func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) {
88
-
refParam := chi.URLParam(r, "ref")
88
+
ref := chi.URLParam(r, "ref")
89
+
ref, _ = url.PathUnescape(ref)
f, err := rp.repoResolver.Resolve(r)
log.Println("failed to get repo and knot", err)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
105
-
archiveBytes, err := tangled.RepoArchive(r.Context(), xrpcc, "tar.gz", "", refParam, repo)
107
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
108
-
log.Println("failed to call XRPC repo.archive", xrpcerr)
109
-
rp.pages.Error503(w)
112
-
rp.pages.Error404(w)
107
+
archiveBytes, err := tangled.RepoArchive(r.Context(), xrpcc, "tar.gz", "", ref, repo)
108
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
109
+
log.Println("failed to call XRPC repo.archive", xrpcerr)
110
+
rp.pages.Error503(w)
116
-
// Set headers for file download
117
-
filename := fmt.Sprintf("%s-%s.tar.gz", f.Name, refParam)
114
+
// Set headers for file download, just pass along whatever the knot specifies
115
+
safeRefFilename := strings.ReplaceAll(plumbing.ReferenceName(ref).Short(), "/", "-")
116
+
filename := fmt.Sprintf("%s-%s.tar.gz", f.Name, safeRefFilename)
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
w.Header().Set("Content-Type", "application/gzip")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(archiveBytes)))
···
ref := chi.URLParam(r, "ref")
141
+
ref, _ = url.PathUnescape(ref)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo)
163
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
164
-
log.Println("failed to call XRPC repo.log", xrpcerr)
165
-
rp.pages.Error503(w)
168
-
rp.pages.Error404(w)
162
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
163
+
log.Println("failed to call XRPC repo.log", xrpcerr)
164
+
rp.pages.Error503(w)
···
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
181
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
182
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
183
-
rp.pages.Error503(w)
176
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
177
+
log.Println("failed to call XRPC repo.tags", xrpcerr)
178
+
rp.pages.Error503(w)
tagMap := make(map[string][]string)
···
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
200
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
201
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
202
-
rp.pages.Error503(w)
193
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
194
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
195
+
rp.pages.Error503(w)
···
ref := chi.URLParam(r, "ref")
348
+
ref, _ = url.PathUnescape(ref)
var diffOpts types.DiffOpts
if d := r.URL.Query().Get("diff"); d == "split" {
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo)
379
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
380
-
log.Println("failed to call XRPC repo.diff", xrpcerr)
381
-
rp.pages.Error503(w)
384
-
rp.pages.Error404(w)
371
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
372
+
log.Println("failed to call XRPC repo.diff", xrpcerr)
373
+
rp.pages.Error503(w)
···
ref := chi.URLParam(r, "ref")
436
-
treePath := chi.URLParam(r, "*")
425
+
ref, _ = url.PathUnescape(ref)
// if the tree path has a trailing slash, let's strip it
429
+
treePath := chi.URLParam(r, "*")
430
+
treePath, _ = url.PathUnescape(treePath)
treePath = strings.TrimSuffix(treePath, "/")
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
xrpcResp, err := tangled.RepoTree(r.Context(), xrpcc, treePath, ref, repo)
454
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
455
-
log.Println("failed to call XRPC repo.tree", xrpcerr)
456
-
rp.pages.Error503(w)
459
-
rp.pages.Error404(w)
444
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
445
+
log.Println("failed to call XRPC repo.tree", xrpcerr)
446
+
rp.pages.Error503(w)
···
// redirects tree paths trying to access a blob; in this case the result.Files is unpopulated,
// so we can safely redirect to the "parent" (which is the same file).
501
-
unescapedTreePath, _ := url.PathUnescape(treePath)
502
-
if len(result.Files) == 0 && result.Parent == unescapedTreePath {
503
-
http.Redirect(w, r, fmt.Sprintf("/%s/blob/%s/%s", f.OwnerSlashRepo(), ref, result.Parent), http.StatusFound)
488
+
if len(result.Files) == 0 && result.Parent == treePath {
489
+
redirectTo := fmt.Sprintf("/%s/blob/%s/%s", f.OwnerSlashRepo(), url.PathEscape(ref), result.Parent)
490
+
http.Redirect(w, r, redirectTo, http.StatusFound)
user := rp.oauth.GetUser(r)
var breadcrumbs [][]string
510
-
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), ref)})
497
+
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), url.PathEscape(ref))})
for idx, elem := range strings.Split(treePath, "/") {
513
-
breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], elem)})
500
+
breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], url.PathEscape(elem))})
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
xrpcBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
547
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
548
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
549
-
rp.pages.Error503(w)
552
-
rp.pages.Error404(w)
533
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
534
+
log.Println("failed to call XRPC repo.tags", xrpcerr)
535
+
rp.pages.Error503(w)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
620
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
621
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
622
-
rp.pages.Error503(w)
625
-
rp.pages.Error404(w)
602
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
603
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
604
+
rp.pages.Error503(w)
···
ref := chi.URLParam(r, "ref")
633
+
ref, _ = url.PathUnescape(ref)
filePath := chi.URLParam(r, "*")
636
+
filePath, _ = url.PathUnescape(filePath)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Repo.Name)
resp, err := tangled.RepoBlob(r.Context(), xrpcc, filePath, false, ref, repo)
668
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
669
-
log.Println("failed to call XRPC repo.blob", xrpcerr)
670
-
rp.pages.Error503(w)
673
-
rp.pages.Error404(w)
649
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
650
+
log.Println("failed to call XRPC repo.blob", xrpcerr)
651
+
rp.pages.Error503(w)
// Use XRPC response directly instead of converting to internal types
var breadcrumbs [][]string
680
-
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), ref)})
658
+
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), url.PathEscape(ref))})
for idx, elem := range strings.Split(filePath, "/") {
683
-
breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], elem)})
661
+
breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], url.PathEscape(elem))})
···
// fetch the raw binary content using sh.tangled.repo.blob xrpc
repoName := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
713
-
blobURL := fmt.Sprintf("%s://%s/xrpc/sh.tangled.repo.blob?repo=%s&ref=%s&path=%s&raw=true",
714
-
scheme, f.Knot, url.QueryEscape(repoName), url.QueryEscape(ref), url.QueryEscape(filePath))
692
+
baseURL := &url.URL{
695
+
Path: "/xrpc/sh.tangled.repo.blob",
697
+
query := baseURL.Query()
698
+
query.Set("repo", repoName)
699
+
query.Set("ref", ref)
700
+
query.Set("path", filePath)
701
+
query.Set("raw", "true")
702
+
baseURL.RawQuery = query.Encode()
703
+
blobURL := baseURL.String()
···
ref := chi.URLParam(r, "ref")
758
+
ref, _ = url.PathUnescape(ref)
filePath := chi.URLParam(r, "*")
761
+
filePath, _ = url.PathUnescape(filePath)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Repo.Name)
777
-
blobURL := fmt.Sprintf("%s://%s/xrpc/sh.tangled.repo.blob?repo=%s&ref=%s&path=%s&raw=true",
778
-
scheme, f.Knot, url.QueryEscape(repo), url.QueryEscape(ref), url.QueryEscape(filePath))
769
+
baseURL := &url.URL{
772
+
Path: "/xrpc/sh.tangled.repo.blob",
774
+
query := baseURL.Query()
775
+
query.Set("repo", repo)
776
+
query.Set("ref", ref)
777
+
query.Set("path", filePath)
778
+
query.Set("raw", "true")
779
+
baseURL.RawQuery = query.Encode()
780
+
blobURL := baseURL.String()
req, err := http.NewRequest("GET", blobURL, nil)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
1368
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1369
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
1370
-
rp.pages.Error503(w)
1369
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1370
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
···
func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) {
ref := chi.URLParam(r, "ref")
1472
+
ref, _ = url.PathUnescape(ref)
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
1763
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1764
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
1765
-
rp.pages.Error503(w)
1768
-
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
1761
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1762
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
1763
+
rp.pages.Error503(w)
···
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
1804
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1805
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
1806
-
rp.pages.Error503(w)
1809
-
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
1798
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1799
+
log.Println("failed to call XRPC repo.tags", xrpcerr)
1800
+
rp.pages.Error503(w)
···
repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name)
branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo)
1881
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1882
-
log.Println("failed to call XRPC repo.branches", xrpcerr)
1883
-
rp.pages.Error503(w)
1886
-
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
1871
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1872
+
log.Println("failed to call XRPC repo.branches", xrpcerr)
1873
+
rp.pages.Error503(w)
···
tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo)
1899
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1900
-
log.Println("failed to call XRPC repo.tags", xrpcerr)
1901
-
rp.pages.Error503(w)
1904
-
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
1885
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1886
+
log.Println("failed to call XRPC repo.tags", xrpcerr)
1887
+
rp.pages.Error503(w)
···
compareBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, base, head)
1917
-
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1918
-
log.Println("failed to call XRPC repo.compare", xrpcerr)
1919
-
rp.pages.Error503(w)
1922
-
rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
1899
+
if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil {
1900
+
log.Println("failed to call XRPC repo.compare", xrpcerr)
1901
+
rp.pages.Error503(w)