--- name: s3_download kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func S3Download(cfg S3Config, key string, dst io.Writer) error" description: "STUB. Descarga el objeto key desde un bucket S3-compatible y escribe su contenido en dst. Permite streaming directo a disco o a un HTTP response. Requiere github.com/aws/aws-sdk-go-v2." tags: [s3, download, storage, cloud, stub, infra] uses_functions: [] uses_types: [S3Config_go_infra] returns: [] returns_optional: false error_type: "error_go_core" imports: [fmt, io] params: - name: cfg desc: "S3Config con endpoint, bucket, credenciales y region" - name: key desc: "key del objeto a descargar (ej: \"images/foto.png\")" - name: dst desc: "writer donde se escribe el contenido (ej: os.File, http.ResponseWriter, bytes.Buffer)" output: "nil si la descarga fue exitosa, error si fallo. STUB actual retorna siempre error \"not implemented\"" tested: false tests: [] test_file_path: "" file_path: "functions/infra/s3_download.go" --- ## Estado **Stub**. Para activar la implementacion real: 1. Añadir las mismas dependencias que `s3_upload`. 2. Reemplazar el cuerpo del stub por: ```go func S3Download(cfg S3Config, key string, dst io.Writer) error { ctx := context.Background() awsCfg, err := awscfg.LoadDefaultConfig(ctx, awscfg.WithRegion(cfg.Region), awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( cfg.AccessKey, cfg.SecretKey, "")), ) if err != nil { return fmt.Errorf("s3_download: aws config: %w", err) } client := s3.NewFromConfig(awsCfg, func(o *s3.Options) { o.UsePathStyle = true if cfg.Endpoint != "" { scheme := "http" if cfg.UseSSL { scheme = "https" } o.BaseEndpoint = aws.String(fmt.Sprintf("%s://%s", scheme, cfg.Endpoint)) } }) out, err := client.GetObject(ctx, &s3.GetObjectInput{ Bucket: aws.String(cfg.Bucket), Key: aws.String(key), }) if err != nil { return fmt.Errorf("s3_download: get object: %w", err) } defer out.Body.Close() _, err = io.Copy(dst, out.Body) return err } ``` ## Ejemplo (con implementacion real) ```go f, _ := os.Create("./local/photo.png") defer f.Close() err := S3Download(cfg, "images/photo.png", f) ``` ## Notas Soporta streaming — el `dst` puede ser un `os.File`, `http.ResponseWriter`, `bytes.Buffer`, o cualquier `io.Writer`. Para archivos grandes, escribir directamente al cliente HTTP evita cargarlo todo en memoria.