diff options
author | KN4CK3R <admin@oldschoolhack.me> | 2023-12-05 09:01:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-05 08:01:02 +0000 |
commit | a95d5b7702e37488e90c3e02016ab91f0c8b5153 (patch) | |
tree | 01deece90c6c48d681a94bec092e716803e40713 | |
parent | 0aab2d38a7d91bc8caff332e452364468ce52d9a (diff) | |
download | gitea-a95d5b7702e37488e90c3e02016ab91f0c8b5153.tar.gz gitea-a95d5b7702e37488e90c3e02016ab91f0c8b5153.zip |
Add `HEAD` support for rpm repo files (#28309)
Fixes https://codeberg.org/forgejo/forgejo/issues/1810
zypper uses HEAD requests to check file existence.
https://github.com/openSUSE/libzypp/blob/HEAD/zypp/RepoManager.cc#L2549
https://github.com/openSUSE/libzypp/blob/HEAD/zypp-curl/ng/network/private/downloaderstates/basicdownloader_p.cc#L116
@ExplodingDragon fyi
-rw-r--r-- | routers/api/packages/api.go | 5 | ||||
-rw-r--r-- | routers/api/packages/rpm/rpm.go | 24 | ||||
-rw-r--r-- | tests/integration/api_packages_rpm_test.go | 8 |
3 files changed, 35 insertions, 2 deletions
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 2ba35e2138..722ee3f87b 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -520,7 +520,10 @@ func CommonRoutes() *web.Route { r.Get("", rpm.DownloadPackageFile) r.Delete("", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile) }) - r.Get("/repodata/{filename}", rpm.GetRepositoryFile) + r.Group("/repodata/{filename}", func() { + r.Head("", rpm.CheckRepositoryFileExistence) + r.Get("", rpm.GetRepositoryFile) + }) }, reqPackageAccess(perm.AccessModeRead)) r.Group("/rubygems", func() { r.Get("/specs.4.8.gz", rubygems.EnumeratePackages) diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index f5d8b67e16..2e161940b8 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -57,6 +57,30 @@ func GetRepositoryKey(ctx *context.Context) { }) } +func CheckRepositoryFileExistence(ctx *context.Context) { + pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), packages_model.EmptyFileKey) + if err != nil { + if errors.Is(err, util.ErrNotExist) { + ctx.Status(http.StatusNotFound) + } else { + apiError(ctx, http.StatusInternalServerError, err) + } + return + } + + ctx.SetServeHeaders(&context.ServeHeaderOptions{ + Filename: pf.Name, + LastModified: pf.CreatedUnix.AsLocalTime(), + }) + ctx.Status(http.StatusOK) +} + // Gets a pre-generated repository metadata file func GetRepositoryFile(ctx *context.Context) { pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID) diff --git a/tests/integration/api_packages_rpm_test.go b/tests/integration/api_packages_rpm_test.go index fc4c4d1c4b..6d3b0688f2 100644 --- a/tests/integration/api_packages_rpm_test.go +++ b/tests/integration/api_packages_rpm_test.go @@ -149,12 +149,18 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, user.Name, user.Name, setting.AppN url := rootURL + "/repodata" - req := NewRequest(t, "GET", url+"/dummy.xml") + req := NewRequest(t, "HEAD", url+"/dummy.xml") + MakeRequest(t, req, http.StatusNotFound) + + req = NewRequest(t, "GET", url+"/dummy.xml") MakeRequest(t, req, http.StatusNotFound) t.Run("repomd.xml", func(t *testing.T) { defer tests.PrintCurrentTest(t)() + req = NewRequest(t, "HEAD", url+"/repomd.xml") + MakeRequest(t, req, http.StatusOK) + req = NewRequest(t, "GET", url+"/repomd.xml") resp := MakeRequest(t, req, http.StatusOK) |