package handlers import ( "messenger/internal/api/middleware" "messenger/internal/api/responses" "messenger/internal/service" "net/http" "strconv" "time" "github.com/go-chi/chi/v5" ) type FileHandler struct { fileService *service.FileService } func NewFileHandler(fileService *service.FileService) *FileHandler { return &FileHandler{ fileService: fileService, } } func (h *FileHandler) UploadFile(w http.ResponseWriter, r *http.Request) { user := middleware.GetUserFromContext(r.Context()) if user == nil { responses.Unauthorized(w, "user not found") return } chatID, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64) if err != nil { responses.BadRequest(w, "invalid chat id") return } // Parse multipart form (20 MB max) if err := r.ParseMultipartForm(20 << 20); err != nil { responses.BadRequest(w, "failed to parse form") return } file, header, err := r.FormFile("file") if err != nil { responses.BadRequest(w, "file is required") return } defer file.Close() attachment, err := h.fileService.UploadFile(r.Context(), chatID, user.ID, header) if err != nil { responses.BadRequest(w, err.Error()) return } responses.Success(w, http.StatusOK, attachment) } func (h *FileHandler) DownloadFile(w http.ResponseWriter, r *http.Request) { user := middleware.GetUserFromContext(r.Context()) if user == nil { responses.Unauthorized(w, "user not found") return } attachmentID, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64) if err != nil { responses.BadRequest(w, "invalid attachment id") return } fileName, file, mimeType, err := h.fileService.DownloadFile(r.Context(), attachmentID, user.ID) if err != nil { responses.NotFound(w, err.Error()) return } defer file.Close() w.Header().Set("Content-Type", mimeType) w.Header().Set("Content-Disposition", "attachment; filename="+strconv.Quote(fileName)) http.ServeContent(w, r, fileName, time.Now(), file) }