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
This commit is contained in:
parent
0aab2d38a7
commit
a95d5b7702
3 changed files with 35 additions and 2 deletions
|
@ -520,7 +520,10 @@ func CommonRoutes() *web.Route {
|
||||||
r.Get("", rpm.DownloadPackageFile)
|
r.Get("", rpm.DownloadPackageFile)
|
||||||
r.Delete("", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
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))
|
}, reqPackageAccess(perm.AccessModeRead))
|
||||||
r.Group("/rubygems", func() {
|
r.Group("/rubygems", func() {
|
||||||
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
|
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
|
||||||
|
|
|
@ -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
|
// Gets a pre-generated repository metadata file
|
||||||
func GetRepositoryFile(ctx *context.Context) {
|
func GetRepositoryFile(ctx *context.Context) {
|
||||||
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
|
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
|
||||||
|
|
|
@ -149,12 +149,18 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, user.Name, user.Name, setting.AppN
|
||||||
|
|
||||||
url := rootURL + "/repodata"
|
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)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
t.Run("repomd.xml", func(t *testing.T) {
|
t.Run("repomd.xml", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
req = NewRequest(t, "HEAD", url+"/repomd.xml")
|
||||||
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", url+"/repomd.xml")
|
req = NewRequest(t, "GET", url+"/repomd.xml")
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue