mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-05 14:48:07 +00:00
Fix RPM Registry 404 when package name contains 'package' (#37087)
Fixes #37086, fix the bug in MatchPath, and swap the order of overlapping routes in api.go to make it look better. --------- Signed-off-by: Rohan Guliani <rohansguliani@google.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -55,6 +55,7 @@ func (g *RouterPathGroup) MatchPattern(methods string, pattern *RouterPathGroupP
|
||||
|
||||
type routerPathParam struct {
|
||||
name string
|
||||
pathSepEnd bool
|
||||
captureGroup int
|
||||
}
|
||||
|
||||
@@ -93,7 +94,15 @@ func (p *routerPathMatcher) matchPath(chiCtx *chi.Context, path string) bool {
|
||||
}
|
||||
for i, pm := range paramMatches {
|
||||
groupIdx := p.params[i].captureGroup * 2
|
||||
chiCtx.URLParams.Add(p.params[i].name, path[pm[groupIdx]:pm[groupIdx+1]])
|
||||
if pm[groupIdx] == -1 || pm[groupIdx+1] == -1 {
|
||||
chiCtx.URLParams.Add(p.params[i].name, "")
|
||||
continue
|
||||
}
|
||||
val := path[pm[groupIdx]:pm[groupIdx+1]]
|
||||
if p.params[i].pathSepEnd {
|
||||
val = strings.TrimSuffix(val, "/")
|
||||
}
|
||||
chiCtx.URLParams.Add(p.params[i].name, val)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -145,11 +154,19 @@ func patternRegexp(pattern string, h ...any) *RouterPathGroupPattern {
|
||||
// it is not used so no need to implement it now
|
||||
param := routerPathParam{}
|
||||
if partExp == "*" {
|
||||
re = append(re, "(.*?)/?"...)
|
||||
// "<part:*>" is a shorthand for optionally matching any string (but not greedy)
|
||||
partExp = ".*?"
|
||||
if lastEnd < len(pattern) && pattern[lastEnd] == '/' {
|
||||
lastEnd++ // the "*" pattern is able to handle the last slash, so skip it
|
||||
// if this param part ends with path separator "/", then consider it together: "(.*?/)"
|
||||
partExp += "/"
|
||||
param.pathSepEnd = true
|
||||
lastEnd++
|
||||
}
|
||||
re = append(re, '(')
|
||||
re = append(re, partExp...)
|
||||
re = append(re, ')', '?') // the wildcard matching is optional
|
||||
} else {
|
||||
// the pattern is user-provided regexp, defaults to a path part (separated by "/")
|
||||
partExp = util.IfZero(partExp, "[^/]+")
|
||||
re = append(re, '(')
|
||||
re = append(re, partExp...)
|
||||
|
||||
@@ -100,7 +100,8 @@ func TestPathProcessor(t *testing.T) {
|
||||
chiCtx := chi.NewRouteContext()
|
||||
chiCtx.RouteMethod = "GET"
|
||||
p := newRouterPathMatcher("GET", patternRegexp(pattern), http.NotFound)
|
||||
assert.True(t, p.matchPath(chiCtx, uri), "use pattern %s to process uri %s", pattern, uri)
|
||||
shouldProcess := expectedPathParams != nil
|
||||
assert.Equal(t, shouldProcess, p.matchPath(chiCtx, uri), "use pattern %s to process uri %s", pattern, uri)
|
||||
assert.Equal(t, expectedPathParams, chiURLParamsToMap(chiCtx), "use pattern %s to process uri %s", pattern, uri)
|
||||
}
|
||||
|
||||
@@ -113,6 +114,10 @@ func TestPathProcessor(t *testing.T) {
|
||||
testProcess("/<p1:*>/<p2>", "/a", map[string]string{"p1": "", "p2": "a"})
|
||||
testProcess("/<p1:*>/<p2>", "/a/b", map[string]string{"p1": "a", "p2": "b"})
|
||||
testProcess("/<p1:*>/<p2>", "/a/b/c", map[string]string{"p1": "a/b", "p2": "c"})
|
||||
testProcess("/<p1:*>/part/<p2>", "/a/part/c", map[string]string{"p1": "a", "p2": "c"})
|
||||
testProcess("/<p1:*>/part/<p2>", "/part/c", map[string]string{"p1": "", "p2": "c"})
|
||||
testProcess("/<p1:*>/part/<p2>", "/a/other-part/c", nil)
|
||||
testProcess("/<p1:*>-part/<p2>", "/a-other-part/c", map[string]string{"p1": "a-other", "p2": "c"})
|
||||
}
|
||||
|
||||
func TestRouter(t *testing.T) {
|
||||
|
||||
@@ -473,8 +473,8 @@ func CommonRoutes() *web.Router {
|
||||
g.MatchPath("GET", "/<group:*>/repodata/<filename>", rpm.GetRepositoryFile)
|
||||
g.MatchPath("PUT", "/<group:*>/upload", reqPackageAccess(perm.AccessModeWrite), rpm.UploadPackageFile)
|
||||
// this URL pattern is only used internally in the RPM index, it is generated by us, the filename part is not really used (can be anything)
|
||||
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>", rpm.DownloadPackageFile)
|
||||
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>/<filename>", rpm.DownloadPackageFile)
|
||||
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>", rpm.DownloadPackageFile)
|
||||
g.MatchPath("DELETE", "/<group:*>/package/<name>/<version>/<architecture>", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user