aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2023-12-05 09:01:02 +0100
committerGitHub <noreply@github.com>2023-12-05 08:01:02 +0000
commita95d5b7702e37488e90c3e02016ab91f0c8b5153 (patch)
tree01deece90c6c48d681a94bec092e716803e40713
parent0aab2d38a7d91bc8caff332e452364468ce52d9a (diff)
downloadgitea-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.go5
-rw-r--r--routers/api/packages/rpm/rpm.go24
-rw-r--r--tests/integration/api_packages_rpm_test.go8
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)