forked from tangled.org/core
this repo has no description

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>

Changed files
+14 -3
knotserver
+14 -3
knotserver/routes.go
··· 361 361 362 362 ref := strings.TrimSuffix(file, ".tar.gz") 363 363 364 + unescapedRef, err := url.PathUnescape(ref) 365 + if err != nil { 366 + notFound(w) 367 + return 368 + } 369 + 370 + // refs/tags/* is way more common than refs/heads/*, so we can live with an ugly file/directory 371 + // name in the odd cases (e.g. refs-heads-master.tar.gz, but in that case the user should just 372 + // request master.tar.gz) 373 + safeRefFilename := strings.ReplaceAll(strings.TrimPrefix(unescapedRef, "refs/tags/"), "/", "-") 374 + 364 375 // This allows the browser to use a proper name for the file when 365 376 // downloading 366 - filename := fmt.Sprintf("%s-%s.tar.gz", name, ref) 377 + filename := fmt.Sprintf("%s-%s.tar.gz", name, safeRefFilename) 367 378 setContentDisposition(w, filename) 368 379 setGZipMIME(w) 369 380 370 381 path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r)) 371 - gr, err := git.Open(path, ref) 382 + gr, err := git.Open(path, unescapedRef) 372 383 if err != nil { 373 384 notFound(w) 374 385 return ··· 377 388 gw := gzip.NewWriter(w) 378 389 defer gw.Close() 379 390 380 - prefix := fmt.Sprintf("%s-%s", name, ref) 391 + prefix := fmt.Sprintf("%s-%s", name, safeRefFilename) 381 392 err = gr.WriteTar(gw, prefix) 382 393 if err != nil { 383 394 // once we start writing to the body we can't report error anymore