diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index dc992ebb5a..d0e0c0f651 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -146,7 +146,11 @@ func UploadPackageFile(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/alt/alt.go b/routers/api/packages/alt/alt.go index a118459ce3..98c5cdd552 100644 --- a/routers/api/packages/alt/alt.go +++ b/routers/api/packages/alt/alt.go @@ -78,7 +78,11 @@ func GetRepositoryFile(ctx *context.Context, arch string) { func UploadPackageFile(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/arch/arch.go b/routers/api/packages/arch/arch.go index a45f38dd08..f177412715 100644 --- a/routers/api/packages/arch/arch.go +++ b/routers/api/packages/arch/arch.go @@ -64,7 +64,11 @@ func PushPackage(ctx *context.Context) { defer releaser() upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index 927d131309..3a95a883c5 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -316,7 +316,11 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go index 52872d2543..57db8096d4 100644 --- a/routers/api/packages/conda/conda.go +++ b/routers/api/packages/conda/conda.go @@ -176,7 +176,11 @@ func EnumeratePackages(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/cran/cran.go b/routers/api/packages/cran/cran.go index f73111278f..65408146ee 100644 --- a/routers/api/packages/cran/cran.go +++ b/routers/api/packages/cran/cran.go @@ -153,7 +153,11 @@ func UploadBinaryPackageFile(ctx *context.Context) { func uploadPackageFile(ctx *context.Context, compositeKey string, properties map[string]string) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index 49b2153724..dbab9d9ee6 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -129,7 +129,11 @@ func UploadPackageFile(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index b84b902d2b..d61a9b4cbd 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -92,7 +92,11 @@ func UploadPackage(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/goproxy/goproxy.go b/routers/api/packages/goproxy/goproxy.go index 488850ecbf..b2a5bda177 100644 --- a/routers/api/packages/goproxy/goproxy.go +++ b/routers/api/packages/goproxy/goproxy.go @@ -156,7 +156,11 @@ func resolvePackage(ctx *context.Context, ownerID int64, name, version string) ( func UploadPackage(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index 0dfc1aeb93..b4dbc30e46 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -145,7 +145,11 @@ func DownloadPackageFile(ctx *context.Context) { func UploadPackage(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 254f4311c1..26b4efa2c8 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -606,7 +606,11 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return nil, nil, closables } diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index cdbf893183..59bb1c4057 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -119,7 +119,11 @@ func GetRepositoryFile(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index eed19467ff..e9fc58c27b 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -285,7 +285,11 @@ func DownloadPackageFile(ctx *context.Context) { func UploadPackageFile(ctx *context.Context) { upload, needToClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusBadRequest, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needToClose { diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go index 26131c2cf2..c43567fddd 100644 --- a/routers/api/packages/vagrant/vagrant.go +++ b/routers/api/packages/vagrant/vagrant.go @@ -151,7 +151,11 @@ func UploadPackageFile(ctx *context.Context) { upload, needsClose, err := ctx.UploadStream() if err != nil { - apiError(ctx, http.StatusInternalServerError, err) + if context.IsFormError(err) { + apiError(ctx, http.StatusBadRequest, err) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } return } if needsClose { diff --git a/services/context/context_request.go b/services/context/context_request.go index 984b9ac793..c04b7df19f 100644 --- a/services/context/context_request.go +++ b/services/context/context_request.go @@ -30,3 +30,7 @@ func (ctx *Context) UploadStream() (rd io.ReadCloser, needToClose bool, err erro } return ctx.Req.Body, false, nil } + +func IsFormError(err error) bool { + return err == http.ErrMissingFile || err == http.ErrMissingBoundary +} diff --git a/tests/integration/api_packages_alpine_test.go b/tests/integration/api_packages_alpine_test.go index d3cf56394c..9d4d2de126 100644 --- a/tests/integration/api_packages_alpine_test.go +++ b/tests/integration/api_packages_alpine_test.go @@ -91,6 +91,11 @@ Djfa/2q5bH4699v++uMAAAAAAAAAAAAAAAAAAAAAAHbgA/eXQh8AKAAA` AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_alt_test.go b/tests/integration/api_packages_alt_test.go index 1a0ba339c6..a15accdbbd 100644 --- a/tests/integration/api_packages_alt_test.go +++ b/tests/integration/api_packages_alt_test.go @@ -106,6 +106,11 @@ enabled=1`, req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_arch_test.go b/tests/integration/api_packages_arch_test.go index 2463fd1c8e..8b3662478b 100644 --- a/tests/integration/api_packages_arch_test.go +++ b/tests/integration/api_packages_arch_test.go @@ -142,6 +142,10 @@ HMhNSS1IzUsBcpJAPFAwwUXSM0u4BjoaR8EoGAWjgGQAAILFeyQADAAA req := NewRequestWithBody(t, "PUT", groupURL, bytes.NewReader(pkgs["any"])) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "PUT", groupURL, bytes.NewReader(pkgs["any"])). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) req = NewRequestWithBody(t, "PUT", groupURL, bytes.NewReader(pkgs["any"])). AddBasicAuth(user.Name) diff --git a/tests/integration/api_packages_conan_test.go b/tests/integration/api_packages_conan_test.go index 02a716b671..0e4e4a75e3 100644 --- a/tests/integration/api_packages_conan_test.go +++ b/tests/integration/api_packages_conan_test.go @@ -117,6 +117,11 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha uploadURL := uploadURLs[conanfileName] assert.NotEmpty(t, uploadURL) + req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConanfile)). + AddTokenAuth(token). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConanfile)). AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_conda_test.go b/tests/integration/api_packages_conda_test.go index 6924968d35..7a1d88f329 100644 --- a/tests/integration/api_packages_conda_test.go +++ b/tests/integration/api_packages_conda_test.go @@ -67,6 +67,11 @@ func TestPackageConda(t *testing.T) { req := NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) @@ -108,6 +113,11 @@ func TestPackageConda(t *testing.T) { req := NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_cran_test.go b/tests/integration/api_packages_cran_test.go index 2326d36171..29907bb74d 100644 --- a/tests/integration/api_packages_cran_test.go +++ b/tests/integration/api_packages_cran_test.go @@ -78,6 +78,12 @@ func TestPackageCran(t *testing.T) { )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( + "package/DESCRIPTION", + createDescription(packageName, packageVersion), + )).AddBasicAuth(user.Name).SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "package/DESCRIPTION", createDescription(packageName, packageVersion), diff --git a/tests/integration/api_packages_debian_test.go b/tests/integration/api_packages_debian_test.go index d5d093a435..40e20aa632 100644 --- a/tests/integration/api_packages_debian_test.go +++ b/tests/integration/api_packages_debian_test.go @@ -98,6 +98,11 @@ func TestPackageDebian(t *testing.T) { AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_generic_test.go b/tests/integration/api_packages_generic_test.go index 5a3727cae5..ab65b76f15 100644 --- a/tests/integration/api_packages_generic_test.go +++ b/tests/integration/api_packages_generic_test.go @@ -37,6 +37,11 @@ func TestPackageGeneric(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + + req = NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_goproxy_test.go b/tests/integration/api_packages_goproxy_test.go index 1b95da8650..2e3a10f239 100644 --- a/tests/integration/api_packages_goproxy_test.go +++ b/tests/integration/api_packages_goproxy_test.go @@ -61,6 +61,11 @@ func TestPackageGo(t *testing.T) { packageName + "@" + packageVersion + "/go.mod": []byte(goModContent), }) + req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_helm_test.go b/tests/integration/api_packages_helm_test.go index 922f4d1469..a4f1df892c 100644 --- a/tests/integration/api_packages_helm_test.go +++ b/tests/integration/api_packages_helm_test.go @@ -94,6 +94,11 @@ dependencies: require.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) + req = NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_nuget_test.go b/tests/integration/api_packages_nuget_test.go index 5596925d86..9db2aed60d 100644 --- a/tests/integration/api_packages_nuget_test.go +++ b/tests/integration/api_packages_nuget_test.go @@ -276,6 +276,11 @@ func TestPackageNuGet(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_rpm_test.go b/tests/integration/api_packages_rpm_test.go index 89faa7a67f..7bffd32e61 100644 --- a/tests/integration/api_packages_rpm_test.go +++ b/tests/integration/api_packages_rpm_test.go @@ -124,6 +124,11 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_packages_rubygems_test.go b/tests/integration/api_packages_rubygems_test.go index 97c2c8bb5f..30a58c33b7 100644 --- a/tests/integration/api_packages_rubygems_test.go +++ b/tests/integration/api_packages_rubygems_test.go @@ -369,6 +369,15 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==`) assert.Equal(t, "ruby", pd.Metadata.(*rubygems.Metadata).Platform) }) + t.Run("UploadBadRequest", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/api/v1/gems", root), bytes.NewReader(gemContent)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + }) + t.Run("UploadExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() diff --git a/tests/integration/api_packages_vagrant_test.go b/tests/integration/api_packages_vagrant_test.go index b9977d61c5..b780a12e62 100644 --- a/tests/integration/api_packages_vagrant_test.go +++ b/tests/integration/api_packages_vagrant_test.go @@ -83,6 +83,11 @@ func TestPackageVagrant(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) MakeRequest(t, req, http.StatusUnauthorized) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name). + SetHeader("content-type", "multipart/form-data") + MakeRequest(t, req, http.StatusBadRequest) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated)