checkFiles reads, and discards, the file contents for each of the given file refs. It is used to check that all files requested for download are readable before starting to reply and/or creating a zip archive of them. It recursively checks directories as well. It also populates dh.pathByRef.
(ctx context.Context, parentPath string, fileRefs []blob.Ref)
| 434 | // starting to reply and/or creating a zip archive of them. It recursively |
| 435 | // checks directories as well. It also populates dh.pathByRef. |
| 436 | func (dh *DownloadHandler) checkFiles(ctx context.Context, parentPath string, fileRefs []blob.Ref) error { |
| 437 | // TODO(mpl): add some concurrency |
| 438 | for _, br := range fileRefs { |
| 439 | rc, _, err := dh.Fetcher.Fetch(ctx, br) |
| 440 | if err != nil { |
| 441 | return fmt.Errorf("could not fetch %v: %v", br, err) |
| 442 | } |
| 443 | b, err := schema.BlobFromReader(br, rc) |
| 444 | rc.Close() |
| 445 | if err != nil { |
| 446 | return fmt.Errorf("could not read %v as blob: %v", br, err) |
| 447 | } |
| 448 | tp := b.Type() |
| 449 | if _, ok := allowedFileTypes[tp]; !ok && tp != schema.TypeDirectory { |
| 450 | return fmt.Errorf("%v not a supported file or directory type: %q", br, tp) |
| 451 | } |
| 452 | if tp == schema.TypeDirectory { |
| 453 | dr, err := b.NewDirReader(ctx, dh.Fetcher) |
| 454 | if err != nil { |
| 455 | return fmt.Errorf("could not open %v as directory: %v", br, err) |
| 456 | } |
| 457 | children, err := dr.StaticSet(ctx) |
| 458 | if err != nil { |
| 459 | return fmt.Errorf("could not get dir entries of %v: %v", br, err) |
| 460 | } |
| 461 | if err := dh.checkFiles(ctx, filepath.Join(parentPath, b.FileName()), children); err != nil { |
| 462 | return err |
| 463 | } |
| 464 | continue |
| 465 | } |
| 466 | if tp != schema.TypeFile { |
| 467 | // We only bother checking regular files. symlinks, fifos, and sockets are |
| 468 | // assumed ok. |
| 469 | dh.pathByRef[br] = filepath.Join(parentPath, b.FileName()) |
| 470 | continue |
| 471 | } |
| 472 | fr, err := b.NewFileReader(dh.Fetcher) |
| 473 | if err != nil { |
| 474 | return fmt.Errorf("could not open %v: %v", br, err) |
| 475 | } |
| 476 | _, err = io.Copy(io.Discard, fr) |
| 477 | fr.Close() |
| 478 | if err != nil { |
| 479 | return fmt.Errorf("could not read %v: %v", br, err) |
| 480 | } |
| 481 | dh.pathByRef[br] = filepath.Join(parentPath, b.FileName()) |
| 482 | } |
| 483 | return nil |
| 484 | } |
| 485 | |
| 486 | // serveZip creates a zip archive from the files provided as |
| 487 | // ?files=sha1-foo,sha1-bar,... and serves it as the response. |
no test coverage detected