package handlers import ( "errors" "fmt" "mime/multipart" "net/http" "strconv" "strings" "warpbox.dev/backend/libs/helpers" "warpbox.dev/backend/libs/jobs" "warpbox.dev/backend/libs/services" ) func (a *App) Upload(w http.ResponseWriter, r *http.Request) { r.Body = http.MaxBytesReader(w, r.Body, a.uploadService.MaxUploadSize()*8) if err := r.ParseMultipartForm(a.uploadService.MaxUploadSize() * 8); err != nil { helpers.WriteJSONError(w, http.StatusBadRequest, "upload form could not be read") return } files := uploadFiles(r) result, err := a.uploadService.CreateBox(files, services.UploadOptions{ MaxDays: parseInt(r.FormValue("max_days")), MaxDownloads: parseInt(r.FormValue("max_downloads")), Password: r.FormValue("password"), ObfuscateMetadata: r.FormValue("obfuscate_metadata") == "on", }) if err != nil { a.logger.Warn("upload failed", "source", "user-upload", "severity", "warn", "code", 4001, "error", err.Error()) helpers.WriteJSONError(w, http.StatusBadRequest, err.Error()) return } jobs.GenerateThumbnailsForBoxAsync(a.uploadService, a.logger, result.BoxID) if wantsJSON(r) { helpers.WriteJSON(w, http.StatusCreated, result) return } w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusCreated) _, _ = fmt.Fprintln(w, result.BoxURL) } func parseInt(value string) int { if value == "" { return 0 } parsed, err := strconv.Atoi(value) if err != nil { return 0 } return parsed } func statusForDownloadError(err error) int { if errors.Is(err, http.ErrMissingFile) { return http.StatusNotFound } return http.StatusForbidden } func uploadFiles(r *http.Request) []*multipart.FileHeader { if r.MultipartForm == nil { return nil } files := make([]*multipart.FileHeader, 0) files = append(files, r.MultipartForm.File["file"]...) files = append(files, r.MultipartForm.File["sharex"]...) return files } func wantsJSON(r *http.Request) bool { return strings.Contains(strings.ToLower(r.Header.Get("Accept")), "application/json") }