github.com/go-crzy/go-git-http-xfer@v1.4.1-0.20210704194527-d62541d1b6b5/addon/handler/archive/archive.go (about) 1 package archive 2 3 import ( 4 "fmt" 5 "net/http" 6 "path" 7 "regexp" 8 "strings" 9 10 "net/url" 11 12 "github.com/go-crzy/go-git-http-xfer/githttpxfer" 13 ) 14 15 var ( 16 archiveRegexp = regexp.MustCompile(".*?(/archive/.*?\\.(zip|tar))$") 17 Pattern = func(u *url.URL) *githttpxfer.Match { 18 m := archiveRegexp.FindStringSubmatch(u.Path) 19 if m == nil { 20 return nil 21 } 22 suffix := m[1] 23 repoPath := strings.Replace(u.Path, suffix, "", 1) 24 filePath := strings.Replace(u.Path, repoPath+"/", "", 1) 25 return &githttpxfer.Match{repoPath, filePath} 26 } 27 Method = http.MethodGet 28 ) 29 30 func New(ghx *githttpxfer.GitHTTPXfer) *gitHTTPXfer { 31 return &gitHTTPXfer{ghx} 32 } 33 34 type gitHTTPXfer struct { 35 *githttpxfer.GitHTTPXfer 36 } 37 38 func (ghx *gitHTTPXfer) Archive(ctx githttpxfer.Context) { 39 40 res, repoPath, filePath := ctx.Response(), ctx.RepoPath(), ctx.FilePath() 41 42 repoName := strings.Split(path.Base(repoPath), ".")[0] 43 fileName := path.Base(filePath) 44 tree := fileName[0:strings.LastIndex(fileName, ".")] 45 ext := path.Ext(fileName) 46 format := strings.Replace(ext, ".", "", 1) 47 48 args := []string{"archive", "--format=" + format, "--prefix=" + repoName + "-" + tree + "/", tree} 49 cmd := ghx.Git.GitCommand(repoPath, args...) 50 cmd.Env = ctx.Env() 51 52 stdout, err := cmd.StdoutPipe() 53 if err != nil { 54 githttpxfer.RenderInternalServerError(res.Writer) 55 return 56 } 57 defer stdout.Close() 58 59 if err := cmd.Start(); err != nil { 60 githttpxfer.RenderInternalServerError(res.Writer) 61 return 62 } 63 64 res.SetContentType("application/octet-stream") 65 res.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName)) 66 res.Header().Add("Content-Transfer-Encoding", "binary") 67 68 if _, err := res.Copy(stdout); err != nil { 69 githttpxfer.RenderInternalServerError(res.Writer) 70 return 71 } 72 if err := cmd.Wait(); err != nil { 73 githttpxfer.RenderInternalServerError(res.Writer) 74 } 75 }