forked from tangled.org/core
Monorepo for Tangled

knotserver: allow downloading archives of refs with slashes in their names

This allows us to be more precise when downloading e.g. tags that have the
same name as branches (in which case Git defaults to the branch, not sure
what go-git does).

Signed-off-by: Winter <winter@winter.cafe>

authored by winter.bsky.social and committed by Tangled 9ff4785b fdcd5495

Changed files
+11 -3
knotserver
+11 -3
knotserver/routes.go
··· 361 362 ref := strings.TrimSuffix(file, ".tar.gz") 363 364 // This allows the browser to use a proper name for the file when 365 // downloading 366 - filename := fmt.Sprintf("%s-%s.tar.gz", name, ref) 367 setContentDisposition(w, filename) 368 setGZipMIME(w) 369 370 path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 371 - gr, err := git.Open(path, ref) 372 if err != nil { 373 notFound(w) 374 return ··· 377 gw := gzip.NewWriter(w) 378 defer gw.Close() 379 380 - prefix := fmt.Sprintf("%s-%s", name, ref) 381 err = gr.WriteTar(gw, prefix) 382 if err != nil { 383 // once we start writing to the body we can't report error anymore
··· 361 362 ref := strings.TrimSuffix(file, ".tar.gz") 363 364 + unescapedRef, err := url.PathUnescape(ref) 365 + if err != nil { 366 + notFound(w) 367 + return 368 + } 369 + 370 + safeRefFilename := strings.ReplaceAll(plumbing.ReferenceName(unescapedRef).Short(), "/", "-") 371 + 372 // This allows the browser to use a proper name for the file when 373 // downloading 374 + filename := fmt.Sprintf("%s-%s.tar.gz", name, safeRefFilename) 375 setContentDisposition(w, filename) 376 setGZipMIME(w) 377 378 path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 379 + gr, err := git.Open(path, unescapedRef) 380 if err != nil { 381 notFound(w) 382 return ··· 385 gw := gzip.NewWriter(w) 386 defer gw.Close() 387 388 + prefix := fmt.Sprintf("%s-%s", name, safeRefFilename) 389 err = gr.WriteTar(gw, prefix) 390 if err != nil { 391 // once we start writing to the body we can't report error anymore