mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-21 16:40:52 +00:00
Make URL scheme unambiguous (#2408)
* Make URL scheme unambiguous Redirect old routes to new routes * Fix redirects to new URL scheme, and update template * Fix branches/_new endpoints, and update integration test
This commit is contained in:
parent
6e98812ecf
commit
513375c429
20 changed files with 279 additions and 144 deletions
|
@ -14,6 +14,7 @@ import (
|
|||
"code.gitea.io/git"
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
@ -117,6 +118,20 @@ func (r *Repository) GetCommitsCount() (int64, error) {
|
|||
})
|
||||
}
|
||||
|
||||
// BranchNameSubURL sub-URL for the BranchName field
|
||||
func (r *Repository) BranchNameSubURL() string {
|
||||
switch {
|
||||
case r.IsViewBranch:
|
||||
return "branch/" + r.BranchName
|
||||
case r.IsViewTag:
|
||||
return "tag/" + r.BranchName
|
||||
case r.IsViewCommit:
|
||||
return "commit/" + r.BranchName
|
||||
}
|
||||
log.Error(4, "Unknown view type for repo: %v", r)
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetEditorconfig returns the .editorconfig definition if found in the
|
||||
// HEAD of the default repo branch.
|
||||
func (r *Repository) GetEditorconfig() (*editorconfig.Editorconfig, error) {
|
||||
|
@ -444,8 +459,81 @@ func RepoAssignment() macaron.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
// RepoRef handles repository reference name including those contain `/`.
|
||||
// RepoRefType type of repo reference
|
||||
type RepoRefType int
|
||||
|
||||
const (
|
||||
// RepoRefLegacy unknown type, make educated guess and redirect.
|
||||
// for backward compatibility with previous URL scheme
|
||||
RepoRefLegacy RepoRefType = iota
|
||||
// RepoRefBranch branch
|
||||
RepoRefBranch
|
||||
// RepoRefTag tag
|
||||
RepoRefTag
|
||||
// RepoRefCommit commit
|
||||
RepoRefCommit
|
||||
)
|
||||
|
||||
// RepoRef handles repository reference names when the ref name is not
|
||||
// explicitly given
|
||||
func RepoRef() macaron.Handler {
|
||||
// since no ref name is explicitly specified, ok to just use branch
|
||||
return RepoRefByType(RepoRefBranch)
|
||||
}
|
||||
|
||||
func getRefNameFromPath(ctx *Context, path string, isExist func(string) bool) string {
|
||||
refName := ""
|
||||
parts := strings.Split(path, "/")
|
||||
for i, part := range parts {
|
||||
refName = strings.TrimPrefix(refName+"/"+part, "/")
|
||||
if isExist(refName) {
|
||||
ctx.Repo.TreePath = strings.Join(parts[i+1:], "/")
|
||||
return refName
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getRefName(ctx *Context, pathType RepoRefType) string {
|
||||
path := ctx.Params("*")
|
||||
switch pathType {
|
||||
case RepoRefLegacy:
|
||||
if refName := getRefName(ctx, RepoRefBranch); len(refName) > 0 {
|
||||
return refName
|
||||
}
|
||||
if refName := getRefName(ctx, RepoRefTag); len(refName) > 0 {
|
||||
return refName
|
||||
}
|
||||
return getRefName(ctx, RepoRefCommit)
|
||||
case RepoRefBranch:
|
||||
return getRefNameFromPath(ctx, path, ctx.Repo.GitRepo.IsBranchExist)
|
||||
case RepoRefTag:
|
||||
return getRefNameFromPath(ctx, path, ctx.Repo.GitRepo.IsTagExist)
|
||||
case RepoRefCommit:
|
||||
parts := strings.Split(path, "/")
|
||||
if len(parts) > 0 && len(parts[0]) == 40 {
|
||||
ctx.Repo.TreePath = strings.Join(parts[1:], "/")
|
||||
return parts[0]
|
||||
}
|
||||
default:
|
||||
log.Error(4, "Unrecognized path type: %v", path)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// URL to redirect to for deprecated URL scheme
|
||||
func repoRefRedirect(ctx *Context) string {
|
||||
urlPath := ctx.Req.URL.String()
|
||||
idx := strings.LastIndex(urlPath, ctx.Params("*"))
|
||||
if idx < 0 {
|
||||
idx = len(urlPath)
|
||||
}
|
||||
return path.Join(urlPath[:idx], ctx.Repo.BranchNameSubURL())
|
||||
}
|
||||
|
||||
// RepoRefByType handles repository reference name for a specific type
|
||||
// of repository reference
|
||||
func RepoRefByType(refType RepoRefType) macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
// Empty repository does not have reference information.
|
||||
if ctx.Repo.Repository.IsBare {
|
||||
|
@ -470,6 +558,7 @@ func RepoRef() macaron.Handler {
|
|||
// Get default branch.
|
||||
if len(ctx.Params("*")) == 0 {
|
||||
refName = ctx.Repo.Repository.DefaultBranch
|
||||
ctx.Repo.BranchName = refName
|
||||
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
brs, err := ctx.Repo.GitRepo.GetBranches()
|
||||
if err != nil {
|
||||
|
@ -492,25 +581,8 @@ func RepoRef() macaron.Handler {
|
|||
ctx.Repo.IsViewBranch = true
|
||||
|
||||
} else {
|
||||
hasMatched := false
|
||||
parts := strings.Split(ctx.Params("*"), "/")
|
||||
for i, part := range parts {
|
||||
refName = strings.TrimPrefix(refName+"/"+part, "/")
|
||||
|
||||
if ctx.Repo.GitRepo.IsBranchExist(refName) ||
|
||||
ctx.Repo.GitRepo.IsTagExist(refName) {
|
||||
if i < len(parts)-1 {
|
||||
ctx.Repo.TreePath = strings.Join(parts[i+1:], "/")
|
||||
}
|
||||
hasMatched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasMatched && len(parts[0]) == 40 {
|
||||
refName = parts[0]
|
||||
ctx.Repo.TreePath = strings.Join(parts[1:], "/")
|
||||
}
|
||||
|
||||
refName = getRefName(ctx, refType)
|
||||
ctx.Repo.BranchName = refName
|
||||
if ctx.Repo.GitRepo.IsBranchExist(refName) {
|
||||
ctx.Repo.IsViewBranch = true
|
||||
|
||||
|
@ -542,10 +614,16 @@ func RepoRef() macaron.Handler {
|
|||
ctx.Handle(404, "RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
|
||||
return
|
||||
}
|
||||
|
||||
if refType == RepoRefLegacy {
|
||||
// redirect from old URL scheme to new URL scheme
|
||||
ctx.Redirect(repoRefRedirect(ctx))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Repo.BranchName = refName
|
||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue