aboutsummaryrefslogtreecommitdiffstats
path: root/modules/context/repo.go
diff options
context:
space:
mode:
authorEthan Koenig <ethantkoenig@gmail.com>2017-10-29 19:04:25 -0700
committerLunny Xiao <xiaolunwen@gmail.com>2017-10-30 10:04:25 +0800
commit513375c429435ba60a667b219bdfb00e5b760b38 (patch)
tree9f516c8d0ebbdc66808c9017df7db2ff9aa34b57 /modules/context/repo.go
parent6e98812ecf4efb6f53d72414ca8f67b14fac6595 (diff)
downloadgitea-513375c429435ba60a667b219bdfb00e5b760b38.tar.gz
gitea-513375c429435ba60a667b219bdfb00e5b760b38.zip
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
Diffstat (limited to 'modules/context/repo.go')
-rw-r--r--modules/context/repo.go120
1 files changed, 99 insertions, 21 deletions
diff --git a/modules/context/repo.go b/modules/context/repo.go
index 704dc59f93..b2b58c4f26 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -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