web frontend for git (tangled's grandpa)
7
fork

Configure Feed

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

routes: Add handler to generate tar gz file

authored by

Gabriel A. Giovanini and committed by
Anirudh Oppiliappan
acac8d47 86b2bf47

+68
+1
routes/handler.go
··· 39 39 mux.HandleFunc("GET /{name}/tree/{ref}/{rest...}", d.RepoTree) 40 40 mux.HandleFunc("GET /{name}/blob/{ref}/{rest...}", d.FileContent) 41 41 mux.HandleFunc("GET /{name}/log/{ref}", d.Log) 42 + mux.HandleFunc("GET /{name}/archive/{file}", d.Archive) 42 43 mux.HandleFunc("GET /{name}/commit/{ref}", d.Diff) 43 44 mux.HandleFunc("GET /{name}/refs/{$}", d.Refs) 44 45 mux.HandleFunc("GET /{name}/{rest...}", d.Multiplex)
+53
routes/routes.go
··· 1 1 package routes 2 2 3 3 import ( 4 + "compress/gzip" 4 5 "fmt" 5 6 "html/template" 6 7 "log" ··· 9 10 "path/filepath" 10 11 "sort" 11 12 "strconv" 13 + "strings" 12 14 "time" 13 15 14 16 "git.icyphox.sh/legit/config" ··· 233 235 d.showFile(contents, data, w) 234 236 } 235 237 return 238 + } 239 + 240 + func (d *deps) Archive(w http.ResponseWriter, r *http.Request) { 241 + name := r.PathValue("name") 242 + if d.isIgnored(name) { 243 + d.Write404(w) 244 + return 245 + } 246 + 247 + file := r.PathValue("file") 248 + 249 + // TODO: extend this to add more files compression (e.g.: xz) 250 + if !strings.HasSuffix(file, ".tar.gz") { 251 + d.Write404(w) 252 + return 253 + } 254 + 255 + ref := strings.TrimSuffix(file, ".tar.gz") 256 + 257 + // This allows the browser to use a proper name for the file when 258 + // downloading 259 + filename := fmt.Sprintf("%s-%s.tar.gz", name, ref) 260 + setContentDisposition(w, filename) 261 + setGZipMIME(w) 262 + 263 + path := filepath.Join(d.c.Repo.ScanPath, name) 264 + gr, err := git.Open(path, ref) 265 + if err != nil { 266 + d.Write404(w) 267 + return 268 + } 269 + 270 + gw := gzip.NewWriter(w) 271 + defer gw.Close() 272 + 273 + prefix := fmt.Sprintf("%s-%s", name, ref) 274 + err = gr.WriteTar(gw, prefix) 275 + if err != nil { 276 + // once we start writing to the body we can't report error anymore 277 + // so we are only left with printing the error. 278 + log.Println(err) 279 + return 280 + } 281 + 282 + err = gw.Flush() 283 + if err != nil { 284 + // once we start writing to the body we can't report error anymore 285 + // so we are only left with printing the error. 286 + log.Println(err) 287 + return 288 + } 236 289 } 237 290 238 291 func (d *deps) Log(w http.ResponseWriter, r *http.Request) {
+14
routes/util.go
··· 3 3 import ( 4 4 "io/fs" 5 5 "log" 6 + "net/http" 6 7 "os" 7 8 "path/filepath" 8 9 "strings" ··· 88 89 func (d *deps) category(path string) string { 89 90 return strings.TrimPrefix(filepath.Dir(strings.TrimPrefix(path, d.c.Repo.ScanPath)), string(os.PathSeparator)) 90 91 } 92 + 93 + func setContentDisposition(w http.ResponseWriter, name string) { 94 + h := "inline; filename=\"" + name + "\"" 95 + w.Header().Add("Content-Disposition", h) 96 + } 97 + 98 + func setGZipMIME(w http.ResponseWriter) { 99 + setMIME(w, "application/gzip") 100 + } 101 + 102 + func setMIME(w http.ResponseWriter, mime string) { 103 + w.Header().Add("Content-Type", mime) 104 + }