diff options
Diffstat (limited to 'internal/api')
| -rw-r--r-- | internal/api/handlers.go | 26 | ||||
| -rw-r--r-- | internal/api/handlers_more_test.go | 23 |
2 files changed, 43 insertions, 6 deletions
diff --git a/internal/api/handlers.go b/internal/api/handlers.go index 3ee4445..e964b92 100644 --- a/internal/api/handlers.go +++ b/internal/api/handlers.go @@ -290,7 +290,19 @@ func (s *Server) handleUpload(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid set id"}) return } - _ = r.ParseMultipartForm(int64(s.cfg.MaxUploadSizeMB) << 20) + + maxBytes := int64(s.cfg.MaxUploadSizeMB) << 20 + r.Body = http.MaxBytesReader(w, r.Body, maxBytes) + if err := r.ParseMultipartForm(maxBytes); err != nil { + var mbe *http.MaxBytesError + if errors.As(err, &mbe) { + writeJSON(w, http.StatusRequestEntityTooLarge, map[string]string{"error": "file too large"}) + return + } + writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid multipart form"}) + return + } + file, fh, err := r.FormFile("file") if err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "missing file"}) @@ -300,6 +312,18 @@ func (s *Server) handleUpload(w http.ResponseWriter, r *http.Request) { media, err := s.mediaSvc.UploadMedia(r.Context(), setID, userIDFromContext(r), fh.Filename, file, fh.Size) if err != nil { + if errors.Is(err, service.ErrNotFound) { + writeJSON(w, http.StatusNotFound, map[string]string{"error": "not found"}) + return + } + if errors.Is(err, service.ErrForbidden) { + writeJSON(w, http.StatusForbidden, map[string]string{"error": "forbidden"}) + return + } + if errors.Is(err, service.ErrUnsupportedExtension) { + writeJSON(w, http.StatusBadRequest, map[string]string{"error": err.Error()}) + return + } writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } diff --git a/internal/api/handlers_more_test.go b/internal/api/handlers_more_test.go index 263041c..1939349 100644 --- a/internal/api/handlers_more_test.go +++ b/internal/api/handlers_more_test.go @@ -410,13 +410,18 @@ func TestServer_Upload(t *testing.T) { svcNil bool svcErr error noFile bool + large bool wantCode int }{ - {"nil service", "1", true, nil, false, http.StatusNotImplemented}, - {"invalid id", "abc", false, nil, false, http.StatusBadRequest}, - {"missing file", "1", false, nil, true, http.StatusBadRequest}, - {"service error", "1", false, errors.New("boom"), false, http.StatusInternalServerError}, - {"ok", "1", false, nil, false, http.StatusOK}, + {"nil service", "1", true, nil, false, false, http.StatusNotImplemented}, + {"invalid id", "abc", false, nil, false, false, http.StatusBadRequest}, + {"missing file", "1", false, nil, true, false, http.StatusBadRequest}, + {"file too large", "1", false, nil, false, true, http.StatusRequestEntityTooLarge}, + {"forbidden", "1", false, service.ErrForbidden, false, false, http.StatusForbidden}, + {"not found", "1", false, service.ErrNotFound, false, false, http.StatusNotFound}, + {"unsupported ext", "1", false, service.ErrUnsupportedExtension, false, false, http.StatusBadRequest}, + {"service error", "1", false, errors.New("boom"), false, false, http.StatusInternalServerError}, + {"ok", "1", false, nil, false, false, http.StatusOK}, } for _, tt := range tests { @@ -437,6 +442,14 @@ func TestServer_Upload(t *testing.T) { _ = w.Close() req = httptest.NewRequest(http.MethodPost, "/api/sets/"+tt.id+"/upload", &buf) req.Header.Set("Content-Type", w.FormDataContentType()) + } else if tt.large { + var buf bytes.Buffer + w := multipart.NewWriter(&buf) + part, _ := w.CreateFormFile("file", "big.bin") + part.Write(make([]byte, 11*1024*1024)) + _ = w.Close() + req = httptest.NewRequest(http.MethodPost, fmt.Sprintf("/api/sets/%s/upload", tt.id), &buf) + req.Header.Set("Content-Type", w.FormDataContentType()) } else { req = newUploadRequest(t, tt.id, "test.mp4", "data") } |
