forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
1package knotserver 2 3import ( 4 "compress/gzip" 5 "fmt" 6 "net/http" 7 "strings" 8 9 securejoin "github.com/cyphar/filepath-securejoin" 10 "github.com/go-chi/chi/v5" 11 "github.com/go-git/go-git/v5/plumbing" 12 "tangled.org/core/knotserver/git" 13) 14 15func (h *Knot) Archive(w http.ResponseWriter, r *http.Request) { 16 var ( 17 did = chi.URLParam(r, "did") 18 name = chi.URLParam(r, "name") 19 ref = chi.URLParam(r, "ref") 20 ) 21 repo, err := securejoin.SecureJoin(did, name) 22 if err != nil { 23 gitError(w, "repository not found", http.StatusNotFound) 24 h.l.Error("git: failed to secure join repo path", "handler", "InfoRefs", "error", err) 25 return 26 } 27 28 repoPath, err := securejoin.SecureJoin(h.c.Repo.ScanPath, repo) 29 if err != nil { 30 gitError(w, "repository not found", http.StatusNotFound) 31 h.l.Error("git: failed to secure join repo path", "handler", "InfoRefs", "error", err) 32 return 33 } 34 35 gr, err := git.Open(repoPath, ref) 36 37 immutableLink := fmt.Sprintf( 38 "https://%s/%s/%s/archive/%s", 39 h.c.Server.Hostname, 40 did, 41 name, 42 gr.Hash(), 43 ) 44 45 safeRefFilename := strings.ReplaceAll(plumbing.ReferenceName(ref).Short(), "/", "-") 46 filename := fmt.Sprintf("%s-%s.tar.gz", name, safeRefFilename) 47 w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename)) 48 w.Header().Set("Content-Type", "application/gzip") 49 w.Header().Set("Link", fmt.Sprintf("<%s>; rel=\"immutable\"", immutableLink)) 50 51 gw := gzip.NewWriter(w) 52 defer gw.Close() 53 54 err = gr.WriteTar(gw, "") 55 if err != nil { 56 // once we start writing to the body we can't report error anymore 57 // so we are only left with logging the error 58 h.l.Error("writing tar file", "error", err) 59 return 60 } 61 62 err = gw.Flush() 63 if err != nil { 64 // once we start writing to the body we can't report error anymore 65 // so we are only left with logging the error 66 h.l.Error("flushing", "error", err.Error()) 67 return 68 } 69}