Confine local file installation paths

This commit is contained in:
2026-08-10 17:59:29 +00:00
parent 59f3fe3d1d
commit 18ddf00d3d
20 changed files with 694 additions and 153 deletions

View File

@@ -150,11 +150,11 @@ func (b *S3Backend) List(ctx context.Context, prefix string) ([]ObjectInfo, erro
return out, nil
}
// Download retrieves one object to localPath, creating parent directories as needed.
func (b *S3Backend) Download(ctx context.Context, key, localPath string) error {
// DownloadTo retrieves one object into the caller-owned destination writer.
func (b *S3Backend) DownloadTo(ctx context.Context, key string, destination io.Writer) error {
normalizedKey := normalizeObjectKey(key)
if strings.TrimSpace(localPath) == "" {
return fmt.Errorf("download object: local path is required")
if destination == nil {
return fmt.Errorf("download object: destination writer is required")
}
resp, err := b.client.GetObject(ctx, &s3.GetObjectInput{
@@ -166,20 +166,30 @@ func (b *S3Backend) Download(ctx context.Context, key, localPath string) error {
}
defer resp.Body.Close()
if _, err := io.Copy(destination, resp.Body); err != nil {
return fmt.Errorf("download object %q: copy body: %w", normalizedKey, err)
}
return nil
}
// Download retrieves one object to localPath, creating parent directories as needed.
func (b *S3Backend) Download(ctx context.Context, key, localPath string) error {
if strings.TrimSpace(localPath) == "" {
return fmt.Errorf("download object: local path is required")
}
if err := os.MkdirAll(filepath.Dir(localPath), 0o755); err != nil {
return fmt.Errorf("download object %q: create parent directory: %w", normalizedKey, err)
return fmt.Errorf("download object %q: create parent directory: %w", key, err)
}
dst, err := os.Create(localPath)
if err != nil {
return fmt.Errorf("download object %q: create local file: %w", normalizedKey, err)
return fmt.Errorf("download object %q: create local file: %w", key, err)
}
defer dst.Close()
if _, err := io.Copy(dst, resp.Body); err != nil {
return fmt.Errorf("download object %q: copy body: %w", normalizedKey, err)
if err := b.DownloadTo(ctx, key, dst); err != nil {
return err
}
if err := dst.Sync(); err != nil {
return fmt.Errorf("download object %q: sync local file: %w", normalizedKey, err)
return fmt.Errorf("download object %q: sync local file: %w", key, err)
}
return nil
}