Files

58 lines
1.6 KiB
Go

package infra
import (
"net/http"
)
// UploadHandler retorna un http.HandlerFunc completo para multipart upload. Compone
// internamente UploadParse + FileValidateType + FileSaveDisk segun cfg.
//
// Comportamiento:
// - Parsea el multipart con maxSize = cfg.MaxFileSize.
// - Para cada archivo: valida tipo por magic bytes contra cfg.AllowedTypes,
// guarda en cfg.BaseDir con FileSaveDisk, sobreescribe ContentType con el
// MIME real detectado.
// - Responde 200 con JSON `{"files": [UploadedFile, ...]}`.
// - Errores: 400 si el parse falla, 415 si algun archivo es de tipo no permitido,
// 500 si falla el guardado.
func UploadHandler(cfg StorageConfig) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
files, err := UploadParse(r, cfg.MaxFileSize)
if err != nil {
HTTPErrorResponse(w, HTTPError{
Status: http.StatusBadRequest,
Code: "parse_error",
Message: err.Error(),
})
return
}
var saved []UploadedFile
for _, pf := range files {
mime, ok := FileValidateType(pf.Header, cfg.AllowedTypes)
if !ok {
HTTPErrorResponse(w, HTTPError{
Status: http.StatusUnsupportedMediaType,
Code: "invalid_type",
Message: "tipo no permitido: " + mime,
})
return
}
uploaded, err := FileSaveDisk(cfg.BaseDir, pf.Filename, pf.Content)
if err != nil {
HTTPErrorResponse(w, HTTPError{
Status: http.StatusInternalServerError,
Code: "save_error",
Message: err.Error(),
})
return
}
uploaded.ContentType = mime
saved = append(saved, uploaded)
}
HTTPJSONResponse(w, http.StatusOK, map[string]any{"files": saved})
}
}