فهرست منبع

Delete documentation and begin flamego migration.

Co-authored-by: unknwon <2946214+unknwon@users.noreply.github.com>
copilot-swe-agent[bot] 2 هفته پیش
والد
کامیت
755f61295a

+ 57 - 0
internal/context/context.go

@@ -24,6 +24,21 @@ import (
 	gogstemplate "gogs.io/gogs/internal/template"
 )
 
+// Resp is a wrapper for ResponseWriter to provide compatibility.
+type Resp struct {
+	http.ResponseWriter
+}
+
+// Write writes data to the response.
+func (r *Resp) Write(data []byte) (int, error) {
+	return r.ResponseWriter.Write(data)
+}
+
+// Req is a wrapper for http.Request to provide compatibility.
+type Req struct {
+	*http.Request
+}
+
 // Context represents context of a request.
 type Context struct {
 	flamego.Context
@@ -34,6 +49,8 @@ type Context struct {
 	Flash   *FlashData
 	Session session.Session
 
+	Resp *Resp
+	Req  *Req
 	ResponseWriter http.ResponseWriter
 	Request        *http.Request
 	Data           template.Data
@@ -53,6 +70,26 @@ type FlashData struct {
 	ErrorMsg, WarningMsg, InfoMsg, SuccessMsg string
 }
 
+// Error sets error message.
+func (f *FlashData) Error(msg string) {
+	f.ErrorMsg = msg
+}
+
+// Success sets success message.
+func (f *FlashData) Success(msg string) {
+	f.SuccessMsg = msg
+}
+
+// Info sets info message.
+func (f *FlashData) Info(msg string) {
+	f.InfoMsg = msg
+}
+
+// Warning sets warning message.
+func (f *FlashData) Warning(msg string) {
+	f.WarningMsg = msg
+}
+
 // RawTitle sets the "Title" field in template data.
 func (c *Context) RawTitle(title string) {
 	c.Data["Title"] = title
@@ -156,6 +193,24 @@ func (c *Context) Written() bool {
 	return false // TODO: Implement proper tracking
 }
 
+// Write writes data to the response.
+func (c *Context) Write(data []byte) (int, error) {
+	return c.ResponseWriter.Write(data)
+}
+
+// ParamsInt64 returns value of the given bind parameter parsed as int64.
+func (c *Context) ParamsInt64(name string) int64 {
+	return c.Context.ParamInt64(name)
+}
+
+// Language returns the language tag from the current locale.
+func (c *Context) Language() string {
+	// Flamego's i18n.Locale doesn't have a Language() method
+	// We need to use a different approach or store the language
+	// For now, return empty string as a placeholder
+	return "" // TODO: Implement proper language tracking
+}
+
 // SetCookie sets a cookie.
 func (c *Context) SetCookie(name, value string, maxAge int, path string) {
 	http.SetCookie(c.ResponseWriter, &http.Cookie{
@@ -310,6 +365,8 @@ func Contexter(store Store) flamego.Handler {
 			csrf:           x,
 			Flash:          flash,
 			Session:        sess,
+			Resp:           &Resp{w},
+			Req:            &Req{req},
 			ResponseWriter: w,
 			Request:        req,
 			Data:           make(template.Data),

+ 1 - 1
internal/route/admin/auths.go

@@ -281,7 +281,7 @@ func DeleteAuthSource(c *context.Context) {
 			c.Flash.Error(fmt.Sprintf("DeleteSource: %v", err))
 		}
 		c.JSONSuccess(map[string]any{
-			"redirect": conf.Server.Subpath + "/admin/auths/" + c.Params(":authid"),
+			"redirect": conf.Server.Subpath + "/admin/auths/" + c.Param(":authid"),
 		})
 		return
 	}

+ 3 - 3
internal/route/admin/users.go

@@ -212,7 +212,7 @@ func EditUserPost(c *context.Context, f form.AdminEditUser) {
 	log.Trace("Account updated by admin %q: %s", c.User.Name, u.Name)
 
 	c.Flash.Success(c.Tr("admin.users.update_profile_success"))
-	c.Redirect(conf.Server.Subpath + "/admin/users/" + c.Params(":userid"))
+	c.Redirect(conf.Server.Subpath + "/admin/users/" + c.Param(":userid"))
 }
 
 func DeleteUser(c *context.Context) {
@@ -227,12 +227,12 @@ func DeleteUser(c *context.Context) {
 		case database.IsErrUserOwnRepos(err):
 			c.Flash.Error(c.Tr("admin.users.still_own_repo"))
 			c.JSONSuccess(map[string]any{
-				"redirect": conf.Server.Subpath + "/admin/users/" + c.Params(":userid"),
+				"redirect": conf.Server.Subpath + "/admin/users/" + c.Param(":userid"),
 			})
 		case database.IsErrUserHasOrgs(err):
 			c.Flash.Error(c.Tr("admin.users.still_has_org"))
 			c.JSONSuccess(map[string]any{
-				"redirect": conf.Server.Subpath + "/admin/users/" + c.Params(":userid"),
+				"redirect": conf.Server.Subpath + "/admin/users/" + c.Param(":userid"),
 			})
 		default:
 			c.Error(err, "delete user")

+ 1 - 1
internal/route/api/v1/admin/org_repo.go

@@ -6,7 +6,7 @@ import (
 )
 
 func GetRepositoryByParams(c *context.APIContext) *database.Repository {
-	repo, err := database.GetRepositoryByName(c.Org.Team.OrgID, c.Params(":reponame"))
+	repo, err := database.GetRepositoryByName(c.Org.Team.OrgID, c.Param(":reponame"))
 	if err != nil {
 		c.NotFoundOrError(err, "get repository by name")
 		return nil

+ 3 - 3
internal/route/api/v1/api.go

@@ -23,8 +23,8 @@ import (
 // and makes sure the context user has at least the read access to the repository.
 func repoAssignment() macaron.Handler {
 	return func(c *context.APIContext) {
-		username := c.Params(":username")
-		reponame := c.Params(":reponame")
+		username := c.Param(":username")
+		reponame := c.Param(":reponame")
 
 		var err error
 		var owner *database.User
@@ -87,7 +87,7 @@ func orgAssignment(args ...bool) macaron.Handler {
 
 		var err error
 		if assignOrg {
-			c.Org.Organization, err = database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":orgname"))
+			c.Org.Organization, err = database.Handle.Users().GetByUsername(c.Req.Context(), c.Param(":orgname"))
 			if err != nil {
 				c.NotFoundOrError(err, "get organization by name")
 				return

+ 3 - 1
internal/route/api/v1/misc/markdown.go

@@ -1,6 +1,8 @@
 package misc
 
 import (
+	"io"
+
 	api "github.com/gogs/go-gogs-client"
 
 	"gogs.io/gogs/internal/context"
@@ -17,7 +19,7 @@ func Markdown(c *context.APIContext, form api.MarkdownOption) {
 }
 
 func MarkdownRaw(c *context.APIContext) {
-	body, err := c.Req.Body().Bytes()
+	body, err := io.ReadAll(c.Req.Request.Body)
 	if err != nil {
 		c.Error(err, "read body")
 		return

+ 3 - 3
internal/route/api/v1/repo/blob.go

@@ -12,13 +12,13 @@ import (
 )
 
 func RepoGitBlob(c *context.APIContext) {
-	gitRepo, err := git.Open(repoutil.RepositoryPath(c.Params(":username"), c.Params(":reponame")))
+	gitRepo, err := git.Open(repoutil.RepositoryPath(c.Param(":username"), c.Param(":reponame")))
 	if err != nil {
 		c.Error(err, "open repository")
 		return
 	}
 
-	sha := c.Params(":sha")
+	sha := c.Param(":sha")
 	blob, err := gitRepo.CatFileBlob(sha)
 	if err != nil {
 		c.NotFoundOrError(gitutil.NewError(err), "get blob")
@@ -42,7 +42,7 @@ func RepoGitBlob(c *context.APIContext) {
 	c.JSONSuccess(&repoGitBlob{
 		Content:  base64.StdEncoding.EncodeToString(content),
 		Encoding: "base64",
-		URL:      fmt.Sprintf("%s/repos/%s/%s/git/blobs/%s", c.BaseURL, c.Params(":username"), c.Params(":reponame"), sha),
+		URL:      fmt.Sprintf("%s/repos/%s/%s/git/blobs/%s", c.BaseURL, c.Param(":username"), c.Param(":reponame"), sha),
 		SHA:      sha,
 		Size:     blob.Size(),
 	})

+ 1 - 1
internal/route/api/v1/repo/branch.go

@@ -9,7 +9,7 @@ import (
 
 // https://github.com/gogs/go-gogs-client/wiki/Repositories#get-branch
 func GetBranch(c *context.APIContext) {
-	branch, err := c.Repo.Repository.GetBranch(c.Params("*"))
+	branch, err := c.Repo.Repository.GetBranch(c.Param("*"))
 	if err != nil {
 		c.NotFoundOrError(err, "get branch")
 		return

+ 3 - 3
internal/route/api/v1/repo/collaborators.go

@@ -24,7 +24,7 @@ func ListCollaborators(c *context.APIContext) {
 }
 
 func AddCollaborator(c *context.APIContext, form api.AddCollaboratorOption) {
-	collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":collaborator"))
+	collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Param(":collaborator"))
 	if err != nil {
 		if database.IsErrUserNotExist(err) {
 			c.Status(http.StatusUnprocessableEntity)
@@ -50,7 +50,7 @@ func AddCollaborator(c *context.APIContext, form api.AddCollaboratorOption) {
 }
 
 func IsCollaborator(c *context.APIContext) {
-	collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":collaborator"))
+	collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Param(":collaborator"))
 	if err != nil {
 		if database.IsErrUserNotExist(err) {
 			c.Status(http.StatusUnprocessableEntity)
@@ -68,7 +68,7 @@ func IsCollaborator(c *context.APIContext) {
 }
 
 func DeleteCollaborator(c *context.APIContext) {
-	collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":collaborator"))
+	collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Param(":collaborator"))
 	if err != nil {
 		if database.IsErrUserNotExist(err) {
 			c.Status(http.StatusUnprocessableEntity)

+ 3 - 3
internal/route/api/v1/repo/commits.go

@@ -50,7 +50,7 @@ func GetAllCommits(c *context.APIContext) {
 // GetSingleCommit will return a single Commit object based on the specified SHA.
 func GetSingleCommit(c *context.APIContext) {
 	if strings.Contains(c.Req.Header.Get("Accept"), api.MediaApplicationSHA) {
-		c.SetParams("*", c.Params(":sha"))
+		c.SetParams("*", c.Param(":sha"))
 		GetReferenceSHA(c)
 		return
 	}
@@ -60,7 +60,7 @@ func GetSingleCommit(c *context.APIContext) {
 		c.Error(err, "open repository")
 		return
 	}
-	commit, err := gitRepo.CatFileCommit(c.Params(":sha"))
+	commit, err := gitRepo.CatFileCommit(c.Param(":sha"))
 	if err != nil {
 		c.NotFoundOrError(gitutil.NewError(err), "get commit")
 		return
@@ -80,7 +80,7 @@ func GetReferenceSHA(c *context.APIContext) {
 		return
 	}
 
-	ref := c.Params("*")
+	ref := c.Param("*")
 	refType := 0 // 0-unknown, 1-branch, 2-tag
 	if strings.HasPrefix(ref, git.RefsHeads) {
 		ref = strings.TrimPrefix(ref, git.RefsHeads)

+ 5 - 5
internal/route/api/v1/repo/contents.go

@@ -40,7 +40,7 @@ type repoContent struct {
 }
 
 func toRepoContent(c *context.APIContext, ref, subpath string, commit *git.Commit, entry *git.TreeEntry) (*repoContent, error) {
-	repoURL := fmt.Sprintf("%s/repos/%s/%s", c.BaseURL, c.Params(":username"), c.Params(":reponame"))
+	repoURL := fmt.Sprintf("%s/repos/%s/%s", c.BaseURL, c.Param(":username"), c.Param(":reponame"))
 	selfURL := fmt.Sprintf("%s/contents/%s", repoURL, subpath)
 	htmlURL := fmt.Sprintf("%s/src/%s/%s", repoutil.HTMLURL(c.Repo.Owner.Name, c.Repo.Repository.Name), ref, entry.Name())
 	downloadURL := fmt.Sprintf("%s/raw/%s/%s", repoutil.HTMLURL(c.Repo.Owner.Name, c.Repo.Repository.Name), ref, entry.Name())
@@ -99,7 +99,7 @@ func toRepoContent(c *context.APIContext, ref, subpath string, commit *git.Commi
 }
 
 func GetContents(c *context.APIContext) {
-	repoPath := repoutil.RepositoryPath(c.Params(":username"), c.Params(":reponame"))
+	repoPath := repoutil.RepositoryPath(c.Param(":username"), c.Param(":reponame"))
 	gitRepo, err := git.Open(repoPath)
 	if err != nil {
 		c.Error(err, "open repository")
@@ -118,7 +118,7 @@ func GetContents(c *context.APIContext) {
 	}
 
 	// 🚨 SECURITY: Prevent path traversal.
-	treePath := pathutil.Clean(c.Params("*"))
+	treePath := pathutil.Clean(c.Param("*"))
 	entry, err := commit.TreeEntry(treePath)
 	if err != nil {
 		c.NotFoundOrError(gitutil.NewError(err), "get tree entry")
@@ -188,7 +188,7 @@ func PutContents(c *context.APIContext, r PutContentsRequest) {
 	}
 
 	// 🚨 SECURITY: Prevent path traversal.
-	treePath := pathutil.Clean(c.Params("*"))
+	treePath := pathutil.Clean(c.Param("*"))
 
 	err = c.Repo.Repository.UpdateRepoFile(
 		c.User,
@@ -206,7 +206,7 @@ func PutContents(c *context.APIContext, r PutContentsRequest) {
 		return
 	}
 
-	repoPath := repoutil.RepositoryPath(c.Params(":username"), c.Params(":reponame"))
+	repoPath := repoutil.RepositoryPath(c.Param(":username"), c.Param(":reponame"))
 	gitRepo, err := git.Open(repoPath)
 	if err != nil {
 		c.Error(err, "open repository")

+ 2 - 2
internal/route/api/v1/repo/file.go

@@ -31,7 +31,7 @@ func GetRawFile(c *context.APIContext) {
 }
 
 func GetArchive(c *context.APIContext) {
-	repoPath := database.RepoPath(c.Params(":username"), c.Params(":reponame"))
+	repoPath := database.RepoPath(c.Param(":username"), c.Param(":reponame"))
 	gitRepo, err := git.Open(repoPath)
 	if err != nil {
 		c.Error(err, "open repository")
@@ -49,7 +49,7 @@ func GetEditorconfig(c *context.APIContext) {
 		return
 	}
 
-	fileName := c.Params("filename")
+	fileName := c.Param("filename")
 	def, err := ec.GetDefinitionForFilename(fileName)
 	if err != nil {
 		c.Error(err, "get definition for filename")

+ 1 - 1
internal/route/api/v1/repo/label.go

@@ -27,7 +27,7 @@ func ListLabels(c *context.APIContext) {
 func GetLabel(c *context.APIContext) {
 	var label *database.Label
 	var err error
-	idStr := c.Params(":id")
+	idStr := c.Param(":id")
 	if id := com.StrTo(idStr).MustInt64(); id > 0 {
 		label, err = database.GetLabelOfRepoByID(c.Repo.Repository.ID, id)
 	} else {

+ 5 - 5
internal/route/api/v1/repo/repo.go

@@ -151,11 +151,11 @@ func ListMyRepos(c *context.APIContext) {
 }
 
 func ListUserRepositories(c *context.APIContext) {
-	listUserRepositories(c, c.Params(":username"))
+	listUserRepositories(c, c.Param(":username"))
 }
 
 func ListOrgRepositories(c *context.APIContext) {
-	listUserRepositories(c, c.Params(":org"))
+	listUserRepositories(c, c.Param(":org"))
 }
 
 func CreateUserRepo(c *context.APIContext, owner *database.User, opt api.CreateRepoOption) {
@@ -196,7 +196,7 @@ func Create(c *context.APIContext, opt api.CreateRepoOption) {
 }
 
 func CreateOrgRepo(c *context.APIContext, opt api.CreateRepoOption) {
-	org, err := database.GetOrgByName(c.Params(":org"))
+	org, err := database.GetOrgByName(c.Param(":org"))
 	if err != nil {
 		c.NotFoundOrError(err, "get organization by name")
 		return
@@ -292,7 +292,7 @@ func Migrate(c *context.APIContext, f form.MigrateRepo) {
 
 // FIXME: inject in the handler chain
 func parseOwnerAndRepo(c *context.APIContext) (*database.User, *database.Repository) {
-	owner, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":username"))
+	owner, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Param(":username"))
 	if err != nil {
 		if database.IsErrUserNotExist(err) {
 			c.ErrorStatus(http.StatusUnprocessableEntity, err)
@@ -302,7 +302,7 @@ func parseOwnerAndRepo(c *context.APIContext) (*database.User, *database.Reposit
 		return nil, nil
 	}
 
-	repo, err := database.GetRepositoryByName(owner.ID, c.Params(":reponame"))
+	repo, err := database.GetRepositoryByName(owner.ID, c.Param(":reponame"))
 	if err != nil {
 		c.NotFoundOrError(err, "get repository by name")
 		return nil, nil

+ 3 - 3
internal/route/api/v1/repo/tree.go

@@ -16,7 +16,7 @@ func GetRepoGitTree(c *context.APIContext) {
 		return
 	}
 
-	sha := c.Params(":sha")
+	sha := c.Param(":sha")
 	tree, err := gitRepo.LsTree(sha)
 	if err != nil {
 		c.NotFoundOrError(gitutil.NewError(err), "get tree")
@@ -43,7 +43,7 @@ func GetRepoGitTree(c *context.APIContext) {
 		Tree []*repoGitTreeEntry `json:"tree"`
 	}
 
-	treesURL := fmt.Sprintf("%s/repos/%s/%s/git/trees", c.BaseURL, c.Params(":username"), c.Params(":reponame"))
+	treesURL := fmt.Sprintf("%s/repos/%s/%s/git/trees", c.BaseURL, c.Param(":username"), c.Param(":reponame"))
 
 	if len(entries) == 0 {
 		c.JSONSuccess(&repoGitTree{
@@ -78,7 +78,7 @@ func GetRepoGitTree(c *context.APIContext) {
 		})
 	}
 	c.JSONSuccess(&repoGitTree{
-		Sha:  c.Params(":sha"),
+		Sha:  c.Param(":sha"),
 		URL:  fmt.Sprintf(treesURL+"/%s", sha),
 		Tree: children,
 	})

+ 1 - 1
internal/route/api/v1/user/user.go

@@ -44,7 +44,7 @@ func Search(c *context.APIContext) {
 }
 
 func GetInfo(c *context.APIContext) {
-	u, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":username"))
+	u, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Param(":username"))
 	if err != nil {
 		c.NotFoundOrError(err, "get user by name")
 		return

+ 1 - 1
internal/route/dev/template.go

@@ -16,5 +16,5 @@ func TemplatePreview(c *context.Context) {
 	c.Data["ResetPwdCodeLives"] = conf.Auth.ResetPasswordCodeLives / 60
 	c.Data["CurDbValue"] = ""
 
-	c.Success(c.Params("*"))
+	c.Success(c.Param("*"))
 }

+ 29 - 29
internal/route/lfs/route.go

@@ -4,7 +4,7 @@ import (
 	"net/http"
 	"strings"
 
-	"gopkg.in/macaron.v1"
+	"github.com/flamego/flamego"
 	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/auth"
@@ -17,7 +17,7 @@ import (
 
 // RegisterRoutes registers LFS routes using given router, and inherits all
 // groups and middleware.
-func RegisterRoutes(r *macaron.Router) {
+func RegisterRoutes(r flamego.Router) {
 	verifyAccept := verifyHeader("Accept", contentType, http.StatusNotAcceptable)
 	verifyContentTypeJSON := verifyHeader("Content-Type", contentType, http.StatusBadRequest)
 	verifyContentTypeStream := verifyHeader("Content-Type", "application/octet-stream", http.StatusBadRequest)
@@ -43,7 +43,7 @@ func RegisterRoutes(r *macaron.Router) {
 
 // authenticate tries to authenticate user via HTTP Basic Auth. It first tries to authenticate
 // as plain username and password, then use username as access token if previous step failed.
-func authenticate(store Store) macaron.Handler {
+func authenticate(store Store) flamego.Handler {
 	askCredentials := func(w http.ResponseWriter) {
 		w.Header().Set("Lfs-Authenticate", `Basic realm="Git LFS"`)
 		responseJSON(w, http.StatusUnauthorized, responseError{
@@ -51,21 +51,21 @@ func authenticate(store Store) macaron.Handler {
 		})
 	}
 
-	return func(c *macaron.Context) {
-		username, password := authutil.DecodeBasic(c.Req.Header)
+	return func(c flamego.Context) {
+		username, password := authutil.DecodeBasic(c.Request().Header)
 		if username == "" {
-			askCredentials(c.Resp)
+			askCredentials(c.ResponseWriter())
 			return
 		}
 
-		user, err := store.AuthenticateUser(c.Req.Context(), username, password, -1)
+		user, err := store.AuthenticateUser(c.Request().Context(), username, password, -1)
 		if err != nil && !auth.IsErrBadCredentials(err) {
-			internalServerError(c.Resp)
+			internalServerError(c.ResponseWriter())
 			log.Error("Failed to authenticate user [name: %s]: %v", username, err)
 			return
 		}
 
-		if err == nil && store.IsTwoFactorEnabled(c.Req.Context(), user.ID) {
+		if err == nil && store.IsTwoFactorEnabled(c.Request().Context(), user.ID) {
 			c.Error(http.StatusBadRequest, "Users with 2FA enabled are not allowed to authenticate via username and password.")
 			return
 		}
@@ -73,17 +73,17 @@ func authenticate(store Store) macaron.Handler {
 		// If username and password combination failed, try again using either username
 		// or password as the token.
 		if auth.IsErrBadCredentials(err) {
-			user, err = context.AuthenticateByToken(store, c.Req.Context(), username)
+			user, err = context.AuthenticateByToken(store, c.Request().Context(), username)
 			if err != nil && !database.IsErrAccessTokenNotExist(err) {
-				internalServerError(c.Resp)
+				internalServerError(c.ResponseWriter())
 				log.Error("Failed to authenticate by access token via username: %v", err)
 				return
 			} else if database.IsErrAccessTokenNotExist(err) {
 				// Try again using the password field as the token.
-				user, err = context.AuthenticateByToken(store, c.Req.Context(), password)
+				user, err = context.AuthenticateByToken(store, c.Request().Context(), password)
 				if err != nil {
 					if database.IsErrAccessTokenNotExist(err) {
-						askCredentials(c.Resp)
+						askCredentials(c.ResponseWriter())
 					} else {
 						c.Status(http.StatusInternalServerError)
 						log.Error("Failed to authenticate by access token via password: %v", err)
@@ -100,34 +100,34 @@ func authenticate(store Store) macaron.Handler {
 }
 
 // authorize tries to authorize the user to the context repository with given access mode.
-func authorize(store Store, mode database.AccessMode) macaron.Handler {
-	return func(c *macaron.Context, actor *database.User) {
-		username := c.Params(":username")
-		reponame := strings.TrimSuffix(c.Params(":reponame"), ".git")
+func authorize(store Store, mode database.AccessMode) flamego.Handler {
+	return func(c flamego.Context, actor *database.User) {
+		username := c.Param(":username")
+		reponame := strings.TrimSuffix(c.Param(":reponame"), ".git")
 
-		owner, err := store.GetUserByUsername(c.Req.Context(), username)
+		owner, err := store.GetUserByUsername(c.Request().Context(), username)
 		if err != nil {
 			if database.IsErrUserNotExist(err) {
 				c.Status(http.StatusNotFound)
 			} else {
-				internalServerError(c.Resp)
+				internalServerError(c.ResponseWriter())
 				log.Error("Failed to get user [name: %s]: %v", username, err)
 			}
 			return
 		}
 
-		repo, err := store.GetRepositoryByName(c.Req.Context(), owner.ID, reponame)
+		repo, err := store.GetRepositoryByName(c.Request().Context(), owner.ID, reponame)
 		if err != nil {
 			if database.IsErrRepoNotExist(err) {
 				c.Status(http.StatusNotFound)
 			} else {
-				internalServerError(c.Resp)
+				internalServerError(c.ResponseWriter())
 				log.Error("Failed to get repository [owner_id: %d, name: %s]: %v", owner.ID, reponame, err)
 			}
 			return
 		}
 
-		if !store.AuthorizeRepositoryAccess(c.Req.Context(), actor.ID, repo.ID, mode,
+		if !store.AuthorizeRepositoryAccess(c.Request().Context(), actor.ID, repo.ID, mode,
 			database.AccessModeOptions{
 				OwnerID: repo.OwnerID,
 				Private: repo.IsPrivate,
@@ -146,9 +146,9 @@ func authorize(store Store, mode database.AccessMode) macaron.Handler {
 
 // verifyHeader checks if the HTTP header contains given value.
 // When not, response given "failCode" as status code.
-func verifyHeader(key, value string, failCode int) macaron.Handler {
-	return func(c *macaron.Context) {
-		vals := c.Req.Header.Values(key)
+func verifyHeader(key, value string, failCode int) flamego.Handler {
+	return func(c flamego.Context) {
+		vals := c.Request().Header.Values(key)
 		for _, val := range vals {
 			if strings.Contains(val, value) {
 				return
@@ -161,11 +161,11 @@ func verifyHeader(key, value string, failCode int) macaron.Handler {
 }
 
 // verifyOID checks if the ":oid" URL parameter is valid.
-func verifyOID() macaron.Handler {
-	return func(c *macaron.Context) {
-		oid := lfsutil.OID(c.Params(":oid"))
+func verifyOID() flamego.Handler {
+	return func(c flamego.Context) {
+		oid := lfsutil.OID(c.Param(":oid"))
 		if !lfsutil.ValidOID(oid) {
-			responseJSON(c.Resp, http.StatusBadRequest, responseError{
+			responseJSON(c.ResponseWriter(), http.StatusBadRequest, responseError{
 				Message: "Invalid oid",
 			})
 			return

+ 3 - 3
internal/route/org/members.go

@@ -37,7 +37,7 @@ func MembersAction(c *context.Context) {
 
 	org := c.Org.Organization
 	var err error
-	switch c.Params(":action") {
+	switch c.Param(":action") {
 	case "private":
 		if c.User.ID != uid && !c.Org.IsOwner {
 			c.NotFound()
@@ -71,7 +71,7 @@ func MembersAction(c *context.Context) {
 	}
 
 	if err != nil {
-		log.Error("Action(%s): %v", c.Params(":action"), err)
+		log.Error("Action(%s): %v", c.Param(":action"), err)
 		c.JSONSuccess(map[string]any{
 			"ok":  false,
 			"err": err.Error(),
@@ -79,7 +79,7 @@ func MembersAction(c *context.Context) {
 		return
 	}
 
-	if c.Params(":action") != "leave" {
+	if c.Param(":action") != "leave" {
 		c.Redirect(c.Org.OrgLink + "/members")
 	} else {
 		c.Redirect(conf.Server.Subpath + "/")

+ 4 - 4
internal/route/org/teams.go

@@ -44,7 +44,7 @@ func TeamsAction(c *context.Context) {
 
 	page := c.Query("page")
 	var err error
-	switch c.Params(":action") {
+	switch c.Param(":action") {
 	case "join":
 		if !c.Org.IsOwner {
 			c.NotFound()
@@ -86,7 +86,7 @@ func TeamsAction(c *context.Context) {
 		if database.IsErrLastOrgOwner(err) {
 			c.Flash.Error(c.Tr("form.last_org_owner"))
 		} else {
-			log.Error("Action(%s): %v", c.Params(":action"), err)
+			log.Error("Action(%s): %v", c.Param(":action"), err)
 			c.JSONSuccess(map[string]any{
 				"ok":  false,
 				"err": err.Error(),
@@ -110,7 +110,7 @@ func TeamsRepoAction(c *context.Context) {
 	}
 
 	var err error
-	switch c.Params(":action") {
+	switch c.Param(":action") {
 	case "add":
 		repoName := path.Base(c.Query("repo_name"))
 		var repo *database.Repository
@@ -131,7 +131,7 @@ func TeamsRepoAction(c *context.Context) {
 	}
 
 	if err != nil {
-		c.Errorf(err, "action %q", c.Params(":action"))
+		c.Errorf(err, "action %q", c.Param(":action"))
 		return
 	}
 	c.Redirect(c.Org.OrgLink + "/teams/" + c.Org.Team.LowerName + "/repositories")

+ 1 - 1
internal/route/repo/branch.go

@@ -104,7 +104,7 @@ func AllBranches(c *context.Context) {
 }
 
 func DeleteBranchPost(c *context.Context) {
-	branchName := c.Params("*")
+	branchName := c.Param("*")
 	commitID := c.Query("commit")
 
 	defer func() {

+ 5 - 5
internal/route/repo/commit.go

@@ -120,7 +120,7 @@ func Diff(c *context.Context) {
 
 	userName := c.Repo.Owner.Name
 	repoName := c.Repo.Repository.Name
-	commitID := c.Params(":sha")
+	commitID := c.Param(":sha")
 
 	commit, err := c.Repo.GitRepo.CatFileCommit(commitID)
 	if err != nil {
@@ -175,8 +175,8 @@ func Diff(c *context.Context) {
 
 func RawDiff(c *context.Context) {
 	if err := c.Repo.GitRepo.RawDiff(
-		c.Params(":sha"),
-		git.RawDiffFormat(c.Params(":ext")),
+		c.Param(":sha"),
+		git.RawDiffFormat(c.Param(":ext")),
 		c.Resp,
 	); err != nil {
 		c.NotFoundOrError(gitutil.NewError(err), "get raw diff")
@@ -215,8 +215,8 @@ func CompareDiff(c *context.Context) {
 	c.Data["IsDiffCompare"] = true
 	userName := c.Repo.Owner.Name
 	repoName := c.Repo.Repository.Name
-	beforeCommitID := c.Params(":before")
-	afterCommitID := c.Params(":after")
+	beforeCommitID := c.Param(":before")
+	afterCommitID := c.Param(":after")
 
 	commit, err := c.Repo.GitRepo.CatFileCommit(afterCommitID)
 	if err != nil {

+ 8 - 8
internal/route/repo/http.go

@@ -13,7 +13,7 @@ import (
 	"strings"
 	"time"
 
-	"gopkg.in/macaron.v1"
+	"github.com/flamego/flamego"
 	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/auth"
@@ -26,7 +26,7 @@ import (
 )
 
 type HTTPContext struct {
-	*macaron.Context
+	flamego.Context
 	OwnerName string
 	OwnerSalt string
 	RepoID    int64
@@ -35,13 +35,13 @@ type HTTPContext struct {
 }
 
 // askCredentials responses HTTP header and status which informs client to provide credentials.
-func askCredentials(c *macaron.Context, status int, text string) {
+func askCredentials(c flamego.Context, status int, text string) {
 	c.Header().Set("WWW-Authenticate", "Basic realm=\".\"")
 	c.Error(status, text)
 }
 
-func HTTPContexter(store Store) macaron.Handler {
-	return func(c *macaron.Context) {
+func HTTPContexter(store Store) flamego.Handler {
+	return func(c flamego.Context) {
 		if len(conf.HTTP.AccessControlAllowOrigin) > 0 {
 			// Set CORS headers for browser-based git clients
 			c.Header().Set("Access-Control-Allow-Origin", conf.HTTP.AccessControlAllowOrigin)
@@ -54,8 +54,8 @@ func HTTPContexter(store Store) macaron.Handler {
 			}
 		}
 
-		ownerName := c.Params(":username")
-		repoName := strings.TrimSuffix(c.Params(":reponame"), ".git")
+		ownerName := c.Param(":username")
+		repoName := strings.TrimSuffix(c.Param(":reponame"), ".git")
 		repoName = strings.TrimSuffix(repoName, ".wiki")
 
 		isPull := c.Query("service") == "git-upload-pack" ||
@@ -93,7 +93,7 @@ func HTTPContexter(store Store) macaron.Handler {
 		}
 
 		// In case user requested a wrong URL and not intended to access Git objects.
-		action := c.Params("*")
+		action := c.Param("*")
 		if !strings.Contains(action, "git-") &&
 			!strings.Contains(action, "info/") &&
 			!strings.Contains(action, "HEAD") &&

+ 1 - 1
internal/route/repo/issue.go

@@ -1224,7 +1224,7 @@ func ChangeMilestonStatus(c *context.Context) {
 		Path: "milestones",
 	}
 
-	switch c.Params(":action") {
+	switch c.Param(":action") {
 	case "open":
 		if m.IsClosed {
 			if err = database.ChangeMilestoneStatus(m, false); err != nil {

+ 1 - 1
internal/route/repo/pull.go

@@ -437,7 +437,7 @@ func ParseCompareInfo(c *context.Context) (*database.User, *database.Repository,
 	// format: <base branch>...[<head repo>:]<head branch>
 	// base<-head: master...head:feature
 	// same repo: master...feature
-	infos := strings.Split(c.Params("*"), "...")
+	infos := strings.Split(c.Param("*"), "...")
 	if len(infos) != 2 {
 		log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
 		c.NotFound()

+ 2 - 2
internal/route/repo/release.go

@@ -241,7 +241,7 @@ func EditRelease(c *context.Context) {
 	c.Data["PageIsEditRelease"] = true
 	renderReleaseAttachmentSettings(c)
 
-	tagName := c.Params("*")
+	tagName := c.Param("*")
 	rel, err := database.GetRelease(c.Repo.Repository.ID, tagName)
 	if err != nil {
 		c.NotFoundOrError(err, "get release")
@@ -265,7 +265,7 @@ func EditReleasePost(c *context.Context, f form.EditRelease) {
 	c.Data["PageIsEditRelease"] = true
 	renderReleaseAttachmentSettings(c)
 
-	tagName := c.Params("*")
+	tagName := c.Param("*")
 	rel, err := database.GetRelease(c.Repo.Repository.ID, tagName)
 	if err != nil {
 		c.NotFoundOrError(err, "get release")

+ 3 - 3
internal/route/repo/repo.go

@@ -229,7 +229,7 @@ func MigratePost(c *context.Context, f form.MigrateRepo) {
 
 func Action(c *context.Context) {
 	var err error
-	switch c.Params(":action") {
+	switch c.Param(":action") {
 	case "watch":
 		err = database.WatchRepo(c.User.ID, c.Repo.Repository.ID, true)
 	case "unwatch":
@@ -256,7 +256,7 @@ func Action(c *context.Context) {
 	}
 
 	if err != nil {
-		c.Errorf(err, "action %q", c.Params(":action"))
+		c.Errorf(err, "action %q", c.Param(":action"))
 		return
 	}
 
@@ -269,7 +269,7 @@ func Action(c *context.Context) {
 
 func Download(c *context.Context) {
 	var (
-		uri           = c.Params("*")
+		uri           = c.Param("*")
 		refName       string
 		ext           string
 		archivePath   string

+ 4 - 4
internal/route/repo/setting.go

@@ -482,7 +482,7 @@ func UpdateDefaultBranch(c *context.Context) {
 }
 
 func SettingsProtectedBranch(c *context.Context) {
-	branch := c.Params("*")
+	branch := c.Param("*")
 	if !c.Repo.GitRepo.HasBranch(branch) {
 		c.NotFound()
 		return
@@ -527,7 +527,7 @@ func SettingsProtectedBranch(c *context.Context) {
 }
 
 func SettingsProtectedBranchPost(c *context.Context, f form.ProtectBranch) {
-	branch := c.Params("*")
+	branch := c.Param("*")
 	if !c.Repo.GitRepo.HasBranch(branch) {
 		c.NotFound()
 		return
@@ -592,7 +592,7 @@ func SettingsGitHooksEdit(c *context.Context) {
 	c.Data["PageIsSettingsGitHooks"] = true
 	c.Data["RequireSimpleMDE"] = true
 
-	name := git.HookName(c.Params(":name"))
+	name := git.HookName(c.Param(":name"))
 	if !isValidHookName(name) {
 		c.NotFound()
 		return
@@ -608,7 +608,7 @@ func SettingsGitHooksEdit(c *context.Context) {
 }
 
 func SettingsGitHooksEditPost(c *context.Context) {
-	name := git.HookName(c.Params(":name"))
+	name := git.HookName(c.Param(":name"))
 	if !isValidHookName(name) {
 		c.NotFound()
 		return

+ 2 - 2
internal/route/repo/tasks.go

@@ -19,8 +19,8 @@ func TriggerTask(c *macaron.Context) {
 		return
 	}
 
-	username := c.Params(":username")
-	reponame := c.Params(":reponame")
+	username := c.Param(":username")
+	reponame := c.Param(":reponame")
 
 	owner, err := database.Handle.Users().GetByUsername(c.Req.Context(), username)
 	if err != nil {

+ 1 - 1
internal/route/repo/webhook.go

@@ -100,7 +100,7 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) {
 	c.PageIs("SettingsHooksNew")
 
 	allowed := false
-	hookType := strings.ToLower(c.Params(":type"))
+	hookType := strings.ToLower(c.Param(":type"))
 	for _, typ := range conf.Webhook.Types {
 		if hookType == typ {
 			allowed = true

+ 2 - 2
internal/route/repo/wiki.go

@@ -71,7 +71,7 @@ func renderWikiPage(c *context.Context, isViewPage bool) (*git.Repository, strin
 		c.Data["Pages"] = pages
 	}
 
-	pageURL := c.Params(":page")
+	pageURL := c.Param(":page")
 	if pageURL == "" {
 		pageURL = "Home"
 	}
@@ -253,7 +253,7 @@ func EditWikiPost(c *context.Context, f form.NewWiki) {
 }
 
 func DeleteWikiPagePost(c *context.Context) {
-	pageURL := c.Params(":page")
+	pageURL := c.Param(":page")
 	if pageURL == "" {
 		pageURL = "Home"
 	}

+ 3 - 3
internal/route/user/home.go

@@ -24,7 +24,7 @@ const (
 // getDashboardContextUser finds out dashboard is viewing as which context user.
 func getDashboardContextUser(c *context.Context) *database.User {
 	ctxUser := c.User
-	orgName := c.Params(":org")
+	orgName := c.Param(":org")
 	if len(orgName) > 0 {
 		// Organization.
 		org, err := database.Handle.Users().GetByUsername(c.Req.Context(), orgName)
@@ -183,7 +183,7 @@ func Dashboard(c *context.Context) {
 }
 
 func Issues(c *context.Context) {
-	isPullList := c.Params(":type") == "pulls"
+	isPullList := c.Param(":type") == "pulls"
 	if isPullList {
 		c.Data["Title"] = c.Tr("pull_requests")
 		c.Data["PageIsPulls"] = true
@@ -385,7 +385,7 @@ func ShowSSHKeys(c *context.Context, uid int64) {
 }
 
 func showOrgProfile(c *context.Context) {
-	c.SetParams(":org", c.Params(":username"))
+	c.SetParams(":org", c.Param(":username"))
 	context.HandleOrgAssignment(c)
 	if c.Written() {
 		return

+ 3 - 3
internal/route/user/profile.go

@@ -19,7 +19,7 @@ const (
 
 func Profile(c *context.Context, puser *context.ParamsUser) {
 	// Show SSH keys.
-	if strings.HasSuffix(c.Params(":username"), ".keys") {
+	if strings.HasSuffix(c.Param(":username"), ".keys") {
 		ShowSSHKeys(c, puser.ID)
 		return
 	}
@@ -109,7 +109,7 @@ func Stars(_ *context.Context) {
 
 func Action(c *context.Context, puser *context.ParamsUser) {
 	var err error
-	switch c.Params(":action") {
+	switch c.Param(":action") {
 	case "follow":
 		err = database.Handle.Users().Follow(c.Req.Context(), c.UserID(), puser.ID)
 	case "unfollow":
@@ -117,7 +117,7 @@ func Action(c *context.Context, puser *context.ParamsUser) {
 	}
 
 	if err != nil {
-		c.Errorf(err, "action %q", c.Params(":action"))
+		c.Errorf(err, "action %q", c.Param(":action"))
 		return
 	}