From 4da1d9781025aa4a85899b1ddeb25aabbaa82703 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 15 Dec 2021 14:59:57 +0800 Subject: [PATCH] Refactor HTTP request context (#17979) --- modules/context/api.go | 10 +- modules/context/context.go | 159 +++++++++++----------------- modules/context/repo.go | 9 +- modules/templates/base.go | 3 - routers/api/v1/repo/commits.go | 10 +- routers/api/v1/repo/pull.go | 8 +- routers/api/v1/user/gpg_key.go | 2 +- routers/install/install.go | 6 +- routers/private/default_branch.go | 2 +- routers/private/hook_pre_receive.go | 2 +- routers/private/key.go | 6 +- routers/private/mail.go | 2 +- routers/private/manager.go | 12 +-- routers/private/manager_unix.go | 4 +- routers/private/manager_windows.go | 2 +- routers/web/goget.go | 2 +- routers/web/repo/branch.go | 2 +- routers/web/repo/editor.go | 10 +- routers/web/repo/http.go | 30 +++--- routers/web/repo/issue.go | 6 +- routers/web/repo/pull.go | 12 +-- routers/web/user/auth.go | 2 +- routers/web/user/home.go | 4 +- routers/web/user/oauth.go | 4 +- services/externalaccount/link.go | 1 + templates/status/500.tmpl | 6 +- 26 files changed, 139 insertions(+), 177 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index b6fcdd2a1..574d7c424 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -181,24 +181,24 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) { links := genAPILinks(ctx.Req.URL, total, pageSize, ctx.FormInt("page")) if len(links) > 0 { - ctx.Header().Set("Link", strings.Join(links, ",")) + ctx.RespHeader().Set("Link", strings.Join(links, ",")) ctx.AppendAccessControlExposeHeaders("Link") } } // SetTotalCountHeader set "X-Total-Count" header func (ctx *APIContext) SetTotalCountHeader(total int64) { - ctx.Header().Set("X-Total-Count", fmt.Sprint(total)) + ctx.RespHeader().Set("X-Total-Count", fmt.Sprint(total)) ctx.AppendAccessControlExposeHeaders("X-Total-Count") } // AppendAccessControlExposeHeaders append headers by name to "Access-Control-Expose-Headers" header func (ctx *APIContext) AppendAccessControlExposeHeaders(names ...string) { - val := ctx.Header().Get("Access-Control-Expose-Headers") + val := ctx.RespHeader().Get("Access-Control-Expose-Headers") if len(val) != 0 { - ctx.Header().Set("Access-Control-Expose-Headers", fmt.Sprintf("%s, %s", val, strings.Join(names, ", "))) + ctx.RespHeader().Set("Access-Control-Expose-Headers", fmt.Sprintf("%s, %s", val, strings.Join(names, ", "))) } else { - ctx.Header().Set("Access-Control-Expose-Headers", strings.Join(names, ", ")) + ctx.RespHeader().Set("Access-Control-Expose-Headers", strings.Join(names, ", ")) } } diff --git a/modules/context/context.go b/modules/context/context.go index 5a37f8b0b..88cf498f8 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -9,7 +9,6 @@ import ( "context" "crypto/sha256" "encoding/hex" - "fmt" "html" "html/template" "io" @@ -156,6 +155,7 @@ func (ctx *Context) GetErrMsg() string { } // HasError returns true if error occurs in form validation. +// Attention: this function changes ctx.Data and ctx.Flash func (ctx *Context) HasError() bool { hasErr, ok := ctx.Data["HasError"] if !ok { @@ -191,29 +191,25 @@ func (ctx *Context) RedirectToFirst(location ...string) { ctx.Redirect(setting.AppSubURL + "/") } -// HTML calls Context.HTML and converts template name to string. +// HTML calls Context.HTML and renders the template to HTTP response func (ctx *Context) HTML(status int, name base.TplName) { log.Debug("Template: %s", name) - var startTime = time.Now() + tmplStartTime := time.Now() ctx.Data["TmplLoadTimes"] = func() string { - return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" + return strconv.FormatInt(time.Since(tmplStartTime).Nanoseconds()/1e6, 10) + "ms" } if err := ctx.Render.HTML(ctx.Resp, status, string(name), ctx.Data); err != nil { if status == http.StatusInternalServerError && name == base.TplName("status/500") { - ctx.PlainText(http.StatusInternalServerError, []byte("Unable to find status/500 template")) + ctx.PlainText(http.StatusInternalServerError, "Unable to find status/500 template") return } ctx.ServerError("Render failed", err) } } -// HTMLString render content to a string but not http.ResponseWriter -func (ctx *Context) HTMLString(name string, data interface{}) (string, error) { +// RenderToString renders the template content to a string +func (ctx *Context) RenderToString(name base.TplName, data map[string]interface{}) (string, error) { var buf strings.Builder - var startTime = time.Now() - ctx.Data["TmplLoadTimes"] = func() string { - return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" - } err := ctx.Render.HTML(&buf, 200, string(name), data) return buf.String(), err } @@ -229,33 +225,30 @@ func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form interface{} } // NotFound displays a 404 (Not Found) page and prints the given error, if any. -func (ctx *Context) NotFound(title string, err error) { - ctx.notFoundInternal(title, err) +func (ctx *Context) NotFound(logMsg string, logErr error) { + ctx.notFoundInternal(logMsg, logErr) } -func (ctx *Context) notFoundInternal(title string, err error) { - if err != nil { - log.ErrorWithSkip(2, "%s: %v", title, err) +func (ctx *Context) notFoundInternal(logMsg string, logErr error) { + if logErr != nil { + log.ErrorWithSkip(2, "%s: %v", logMsg, logErr) if !setting.IsProd { - ctx.Data["ErrorMsg"] = err + ctx.Data["ErrorMsg"] = logErr } } - // response simple meesage if Accept isn't text/html - reqTypes, has := ctx.Req.Header["Accept"] - if has && len(reqTypes) > 0 { - notHTML := true - for _, part := range reqTypes { - if strings.Contains(part, "text/html") { - notHTML = false - break - } + // response simple message if Accept isn't text/html + showHTML := false + for _, part := range ctx.Req.Header["Accept"] { + if strings.Contains(part, "text/html") { + showHTML = true + break } + } - if notHTML { - ctx.PlainText(404, []byte("Not found.\n")) - return - } + if !showHTML { + ctx.PlainText(http.StatusNotFound, "Not found.\n") + return } ctx.Data["IsRepo"] = ctx.Repo.Repository != nil @@ -263,17 +256,16 @@ func (ctx *Context) notFoundInternal(title string, err error) { ctx.HTML(http.StatusNotFound, base.TplName("status/404")) } -// ServerError displays a 500 (Internal Server Error) page and prints the given -// error, if any. -func (ctx *Context) ServerError(title string, err error) { - ctx.serverErrorInternal(title, err) +// ServerError displays a 500 (Internal Server Error) page and prints the given error, if any. +func (ctx *Context) ServerError(logMsg string, logErr error) { + ctx.serverErrorInternal(logMsg, logErr) } -func (ctx *Context) serverErrorInternal(title string, err error) { - if err != nil { - log.ErrorWithSkip(2, "%s: %v", title, err) +func (ctx *Context) serverErrorInternal(logMsg string, logErr error) { + if logErr != nil { + log.ErrorWithSkip(2, "%s: %v", logMsg, logErr) if !setting.IsProd { - ctx.Data["ErrorMsg"] = err + ctx.Data["ErrorMsg"] = logErr } } @@ -282,37 +274,45 @@ func (ctx *Context) serverErrorInternal(title string, err error) { } // NotFoundOrServerError use error check function to determine if the error -// is about not found. It responses with 404 status code for not found error, +// is about not found. It responds with 404 status code for not found error, // or error context description for logging purpose of 500 server error. -func (ctx *Context) NotFoundOrServerError(title string, errck func(error) bool, err error) { - if errck(err) { - ctx.notFoundInternal(title, err) +func (ctx *Context) NotFoundOrServerError(logMsg string, errCheck func(error) bool, err error) { + if errCheck(err) { + ctx.notFoundInternal(logMsg, err) return } - - ctx.serverErrorInternal(title, err) + ctx.serverErrorInternal(logMsg, err) } -// Header returns a header -func (ctx *Context) Header() http.Header { - return ctx.Resp.Header() -} - -// HandleText handles HTTP status code -func (ctx *Context) HandleText(status int, title string) { +// PlainTextBytes renders bytes as plain text +func (ctx *Context) PlainTextBytes(status int, bs []byte) { if (status/100 == 4) || (status/100 == 5) { - log.Error("%s", title) + log.Error("PlainTextBytes: %s", string(bs)) } - ctx.PlainText(status, []byte(title)) + ctx.Resp.WriteHeader(status) + ctx.Resp.Header().Set("Content-Type", "text/plain;charset=utf-8") + if _, err := ctx.Resp.Write(bs); err != nil { + log.Error("Write bytes failed: %v", err) + } +} + +// PlainText renders content as plain text +func (ctx *Context) PlainText(status int, text string) { + ctx.PlainTextBytes(status, []byte(text)) +} + +// RespHeader returns the response header +func (ctx *Context) RespHeader() http.Header { + return ctx.Resp.Header() } // ServeContent serves content to http request func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) { - modtime := time.Now() + modTime := time.Now() for _, p := range params { switch v := p.(type) { case time.Time: - modtime = v + modTime = v } } ctx.Resp.Header().Set("Content-Description", "File Transfer") @@ -323,16 +323,7 @@ func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interfa ctx.Resp.Header().Set("Cache-Control", "must-revalidate") ctx.Resp.Header().Set("Pragma", "public") ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") - http.ServeContent(ctx.Resp, ctx.Req, name, modtime, r) -} - -// PlainText render content as plain text -func (ctx *Context) PlainText(status int, bs []byte) { - ctx.Resp.WriteHeader(status) - ctx.Resp.Header().Set("Content-Type", "text/plain;charset=utf-8") - if _, err := ctx.Resp.Write(bs); err != nil { - ctx.ServerError("Write bytes failed", err) - } + http.ServeContent(ctx.Resp, ctx.Req, name, modTime, r) } // ServeFile serves given file to response. @@ -386,7 +377,7 @@ func (ctx *Context) JSON(status int, content interface{}) { } } -// Redirect redirect the request +// Redirect redirects the request func (ctx *Context) Redirect(location string, status ...int) { code := http.StatusFound if len(status) == 1 { @@ -506,7 +497,7 @@ func (ctx *Context) SetParams(k, v string) { chiCtx.URLParams.Add(strings.TrimPrefix(k, ":"), url.PathEscape(v)) } -// Write writes data to webbrowser +// Write writes data to web browser func (ctx *Context) Write(bs []byte) (int, error) { return ctx.Resp.Write(bs) } @@ -544,10 +535,9 @@ func (ctx *Context) Value(key interface{}) interface{} { // Handler represents a custom handler type Handler func(*Context) -// enumerate all content -var ( - contextKey interface{} = "default_context" -) +type contextKeyType struct{} + +var contextKey interface{} = contextKeyType{} // WithContext set up install context in request func WithContext(req *http.Request, ctx *Context) *http.Request { @@ -570,31 +560,6 @@ func GetContextUser(req *http.Request) *user_model.User { return nil } -// SignedUserName returns signed user's name via context -func SignedUserName(req *http.Request) string { - if middleware.IsInternalPath(req) { - return "" - } - if middleware.IsAPIPath(req) { - ctx, ok := req.Context().Value(apiContextKey).(*APIContext) - if ok { - v := ctx.Data["SignedUserName"] - if res, ok := v.(string); ok { - return res - } - } - } else { - ctx, ok := req.Context().Value(contextKey).(*Context) - if ok { - v := ctx.Data["SignedUserName"] - if res, ok := v.(string); ok { - return res - } - } - } - return "" -} - func getCsrfOpts() CsrfOptions { return CsrfOptions{ Secret: setting.SecretKey, @@ -727,8 +692,6 @@ func Contexter() func(next http.Handler) http.Handler { ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken()) ctx.Data["CsrfTokenHtml"] = template.HTML(``) - log.Debug("Session ID: %s", ctx.Session.ID()) - log.Debug("CSRF Token: %v", ctx.Data["CsrfToken"]) // FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these ctx.Data["IsLandingPageHome"] = setting.LandingPageURL == setting.LandingPageHome diff --git a/modules/context/repo.go b/modules/context/repo.go index 010d3b7f8..139dfaf0f 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -9,6 +9,7 @@ import ( "context" "fmt" "io" + "net/http" "net/url" "path" "strings" @@ -305,14 +306,14 @@ func EarlyResponseForGoGetMeta(ctx *Context) { username := ctx.Params(":username") reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git") if username == "" || reponame == "" { - ctx.PlainText(400, []byte("invalid repository path")) + ctx.PlainText(http.StatusBadRequest, "invalid repository path") return } - ctx.PlainText(200, []byte(com.Expand(``, + ctx.PlainText(http.StatusOK, com.Expand(``, map[string]string{ "GoGetImport": ComposeGoGetImport(username, reponame), "CloneLink": repo_model.ComposeHTTPSCloneURL(username, reponame), - }))) + })) } // RedirectToRepo redirect to a differently-named repository @@ -897,7 +898,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context } // If short commit ID add canonical link header if len(refName) < 40 { - ctx.Header().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", + ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1)))) } } else { diff --git a/modules/templates/base.go b/modules/templates/base.go index f753bfbe4..f3052770e 100644 --- a/modules/templates/base.go +++ b/modules/templates/base.go @@ -43,9 +43,6 @@ func BaseVars() Vars { "EnableSwagger": setting.API.EnableSwagger, "EnableOpenIDSignIn": setting.Service.EnableOpenIDSignIn, "PageStartTime": startTime, - "TmplLoadTimes": func() string { - return time.Since(startTime).String() - }, } } diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 117fef08d..6845ccb36 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -205,11 +205,11 @@ func GetAllCommits(ctx *context.APIContext) { ctx.SetTotalCountHeader(commitsCountTotal) // kept for backwards compatibility - ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page)) - ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) - ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10)) - ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount)) - ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount)) + ctx.RespHeader().Set("X-Page", strconv.Itoa(listOptions.Page)) + ctx.RespHeader().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) + ctx.RespHeader().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10)) + ctx.RespHeader().Set("X-PageCount", strconv.Itoa(pageCount)) + ctx.RespHeader().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount)) ctx.AppendAccessControlExposeHeaders("X-Page", "X-PerPage", "X-Total", "X-PageCount", "X-HasMore") ctx.JSON(http.StatusOK, &apiCommits) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 0683fe454..4c774e8af 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1233,10 +1233,10 @@ func GetPullRequestCommits(ctx *context.APIContext) { ctx.SetLinkHeader(totalNumberOfCommits, listOptions.PageSize) ctx.SetTotalCountHeader(int64(totalNumberOfCommits)) - ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page)) - ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) - ctx.Header().Set("X-PageCount", strconv.Itoa(totalNumberOfPages)) - ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < totalNumberOfPages)) + ctx.RespHeader().Set("X-Page", strconv.Itoa(listOptions.Page)) + ctx.RespHeader().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) + ctx.RespHeader().Set("X-PageCount", strconv.Itoa(totalNumberOfPages)) + ctx.RespHeader().Set("X-HasMore", strconv.FormatBool(listOptions.Page < totalNumberOfPages)) ctx.AppendAccessControlExposeHeaders("X-Page", "X-PerPage", "X-PageCount", "X-HasMore") ctx.JSON(http.StatusOK, &apiCommits) diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index b0f9f1feb..a90e8c30f 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -157,7 +157,7 @@ func GetVerificationToken(ctx *context.APIContext) { // "$ref": "#/responses/notFound" token := asymkey_model.VerificationToken(ctx.User, 1) - ctx.PlainText(http.StatusOK, []byte(token)) + ctx.PlainText(http.StatusOK, token) } // VerifyUserGPGKey creates new GPG key to given user by ID. diff --git a/routers/install/install.go b/routers/install/install.go index 45804acf3..7c3d43bbd 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -80,9 +80,7 @@ func Init(next http.Handler) http.Handler { "AllLangs": translation.AllLangs(), "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), "PageStartTime": startTime, - "TmplLoadTimes": func() string { - return time.Since(startTime).String() - }, + "PasswordHashAlgorithms": user_model.AvailableHashAlgorithms, }, } @@ -554,7 +552,7 @@ func SubmitInstall(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("install.install_success")) - ctx.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") + ctx.RespHeader().Add("Refresh", "1; url="+setting.AppURL+"user/login") ctx.HTML(http.StatusOK, tplPostInstall) // Now get the http.Server from this request and shut it down diff --git a/routers/private/default_branch.go b/routers/private/default_branch.go index 974534c21..5fdd0df73 100644 --- a/routers/private/default_branch.go +++ b/routers/private/default_branch.go @@ -71,5 +71,5 @@ func SetDefaultBranch(ctx *gitea_context.PrivateContext) { }) return } - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 17ccf010a..7ad719155 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -134,7 +134,7 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { } } - ctx.PlainText(http.StatusOK, []byte("ok")) + ctx.PlainText(http.StatusOK, "ok") } func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName string) { diff --git a/routers/private/key.go b/routers/private/key.go index 30fde73c8..3366b764e 100644 --- a/routers/private/key.go +++ b/routers/private/key.go @@ -28,7 +28,7 @@ func UpdatePublicKeyInRepo(ctx *context.PrivateContext) { deployKey, err := asymkey_model.GetDeployKeyByRepo(keyID, repoID) if err != nil { if asymkey_model.IsErrDeployKeyNotExist(err) { - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") return } ctx.JSON(http.StatusInternalServerError, private.Response{ @@ -44,7 +44,7 @@ func UpdatePublicKeyInRepo(ctx *context.PrivateContext) { return } - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } // AuthorizedPublicKeyByContent searches content as prefix (leak e-mail part) @@ -59,5 +59,5 @@ func AuthorizedPublicKeyByContent(ctx *context.PrivateContext) { }) return } - ctx.PlainText(http.StatusOK, []byte(publicKey.AuthorizedString())) + ctx.PlainText(http.StatusOK, publicKey.AuthorizedString()) } diff --git a/routers/private/mail.go b/routers/private/mail.go index 5218cd34a..8b69c3809 100644 --- a/routers/private/mail.go +++ b/routers/private/mail.go @@ -86,5 +86,5 @@ func sendEmail(ctx *context.PrivateContext, subject, message string, to []string wasSent := strconv.Itoa(len(to)) - ctx.PlainText(http.StatusOK, []byte(wasSent)) + ctx.PlainText(http.StatusOK, wasSent) } diff --git a/routers/private/manager.go b/routers/private/manager.go index 2b4cfb8ef..a3b9a16f7 100644 --- a/routers/private/manager.go +++ b/routers/private/manager.go @@ -41,19 +41,19 @@ func FlushQueues(ctx *context.PrivateContext) { Err: fmt.Sprintf("%v", err), }) } - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } // PauseLogging pauses logging func PauseLogging(ctx *context.PrivateContext) { log.Pause() - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } // ResumeLogging resumes logging func ResumeLogging(ctx *context.PrivateContext) { log.Resume() - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } // ReleaseReopenLogging releases and reopens logging files @@ -64,7 +64,7 @@ func ReleaseReopenLogging(ctx *context.PrivateContext) { }) return } - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } // RemoveLogger removes a logger @@ -81,7 +81,7 @@ func RemoveLogger(ctx *context.PrivateContext) { if ok { setting.RemoveSubLogDescription(group, name) } - ctx.PlainText(http.StatusOK, []byte(fmt.Sprintf("Removed %s %s", group, name))) + ctx.PlainText(http.StatusOK, fmt.Sprintf("Removed %s %s", group, name)) } // AddLogger adds a logger @@ -154,5 +154,5 @@ func AddLogger(ctx *context.PrivateContext) { Config: config, }) - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } diff --git a/routers/private/manager_unix.go b/routers/private/manager_unix.go index 1738c06a0..f00f20220 100644 --- a/routers/private/manager_unix.go +++ b/routers/private/manager_unix.go @@ -17,12 +17,12 @@ import ( // Restart causes the server to perform a graceful restart func Restart(ctx *context.PrivateContext) { graceful.GetManager().DoGracefulRestart() - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } // Shutdown causes the server to perform a graceful shutdown func Shutdown(ctx *context.PrivateContext) { graceful.GetManager().DoGracefulShutdown() - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } diff --git a/routers/private/manager_windows.go b/routers/private/manager_windows.go index a8a477313..014018a53 100644 --- a/routers/private/manager_windows.go +++ b/routers/private/manager_windows.go @@ -25,5 +25,5 @@ func Restart(ctx *context.PrivateContext) { // Shutdown causes the server to perform a graceful shutdown func Shutdown(ctx *context.PrivateContext) { graceful.GetManager().DoGracefulShutdown() - ctx.PlainText(http.StatusOK, []byte("success")) + ctx.PlainText(http.StatusOK, "success") } diff --git a/routers/web/goget.go b/routers/web/goget.go index 6898f0f43..2843a96c3 100644 --- a/routers/web/goget.go +++ b/routers/web/goget.go @@ -65,7 +65,7 @@ func goGet(ctx *context.Context) { if appURL.Scheme == string(setting.HTTP) { insecure = "--insecure " } - ctx.Header().Set("Content-Type", "text/html") + ctx.RespHeader().Set("Content-Type", "text/html") ctx.Status(http.StatusOK) _, _ = ctx.Write([]byte(com.Expand(` diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index d8f7b7ef2..924720208 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -379,7 +379,7 @@ func CreateBranch(ctx *context.Context) { if len(e.Message) == 0 { ctx.Flash.Error(ctx.Tr("repo.editor.push_rejected_no_message")) } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(e.Message), diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 97f097783..ef2166d85 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -307,7 +307,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b if len(errPushRej.Message) == 0 { ctx.RenderWithErr(ctx.Tr("repo.editor.push_rejected_no_message"), tplEditFile, &form) } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(errPushRej.Message), @@ -319,7 +319,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b ctx.RenderWithErr(flashError, tplEditFile, &form) } } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.editor.fail_to_update_file", form.TreePath), "Summary": ctx.Tr("repo.editor.fail_to_update_file_summary"), "Details": utils.SanitizeFlashErrorString(err.Error()), @@ -376,7 +376,7 @@ func DiffPreviewPost(ctx *context.Context) { } if diff.NumFiles == 0 { - ctx.PlainText(200, []byte(ctx.Tr("repo.editor.no_changes_to_show"))) + ctx.PlainText(http.StatusOK, ctx.Tr("repo.editor.no_changes_to_show")) return } ctx.Data["File"] = diff.Files[0] @@ -501,7 +501,7 @@ func DeleteFilePost(ctx *context.Context) { if len(errPushRej.Message) == 0 { ctx.RenderWithErr(ctx.Tr("repo.editor.push_rejected_no_message"), tplDeleteFile, &form) } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(errPushRej.Message), @@ -704,7 +704,7 @@ func UploadFilePost(ctx *context.Context) { if len(errPushRej.Message) == 0 { ctx.RenderWithErr(ctx.Tr("repo.editor.push_rejected_no_message"), tplUploadFile, &form) } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(errPushRej.Message), diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go index 107f1d960..64e617dc4 100644 --- a/routers/web/repo/http.go +++ b/routers/web/repo/http.go @@ -126,7 +126,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { return } if !owner.IsOrganization() && !owner.IsActive { - ctx.HandleText(http.StatusForbidden, "Repository cannot be accessed. You cannot push or open issues/pull-requests.") + ctx.PlainText(http.StatusForbidden, "Repository cannot be accessed. You cannot push or open issues/pull-requests.") return } @@ -147,7 +147,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { // Don't allow pushing if the repo is archived if repoExist && repo.IsArchived && !isPull { - ctx.HandleText(http.StatusForbidden, "This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.") + ctx.PlainText(http.StatusForbidden, "This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.") return } @@ -182,7 +182,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { _, err = login.GetTwoFactorByUID(ctx.User.ID) if err == nil { // TODO: This response should be changed to "invalid credentials" for security reasons once the expectation behind it (creating an app token to authenticate) is properly documented - ctx.HandleText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page") + ctx.PlainText(http.StatusUnauthorized, "Users with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password. Please create and use a personal access token on the user settings page") return } else if !login.IsErrTwoFactorNotEnrolled(err) { ctx.ServerError("IsErrTwoFactorNotEnrolled", err) @@ -191,7 +191,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { } if !ctx.User.IsActive || ctx.User.ProhibitLogin { - ctx.HandleText(http.StatusForbidden, "Your account is disabled.") + ctx.PlainText(http.StatusForbidden, "Your account is disabled.") return } @@ -208,12 +208,12 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { } if !p.CanAccess(accessMode, unitType) { - ctx.HandleText(http.StatusForbidden, "User permission denied") + ctx.PlainText(http.StatusForbidden, "User permission denied") return } if !isPull && repo.IsMirror { - ctx.HandleText(http.StatusForbidden, "mirror repository is read-only") + ctx.PlainText(http.StatusForbidden, "mirror repository is read-only") return } } @@ -240,21 +240,21 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { if !repoExist { if !receivePack { - ctx.HandleText(http.StatusNotFound, "Repository not found") + ctx.PlainText(http.StatusNotFound, "Repository not found") return } if isWiki { // you cannot send wiki operation before create the repository - ctx.HandleText(http.StatusNotFound, "Repository not found") + ctx.PlainText(http.StatusNotFound, "Repository not found") return } if owner.IsOrganization() && !setting.Repository.EnablePushCreateOrg { - ctx.HandleText(http.StatusForbidden, "Push to create is not enabled for organizations.") + ctx.PlainText(http.StatusForbidden, "Push to create is not enabled for organizations.") return } if !owner.IsOrganization() && !setting.Repository.EnablePushCreateUser { - ctx.HandleText(http.StatusForbidden, "Push to create is not enabled for users.") + ctx.PlainText(http.StatusForbidden, "Push to create is not enabled for users.") return } @@ -276,7 +276,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { // Ensure the wiki is enabled before we allow access to it if _, err := repo.GetUnit(unit.TypeWiki); err != nil { if repo_model.IsErrUnitTypeNotExist(err) { - ctx.HandleText(http.StatusForbidden, "repository wiki is disabled") + ctx.PlainText(http.StatusForbidden, "repository wiki is disabled") return } log.Error("Failed to get the wiki unit in %-v Error: %v", repo, err) @@ -338,10 +338,10 @@ func dummyInfoRefs(ctx *context.Context) { infoRefsCache = refs }) - ctx.Header().Set("Expires", "Fri, 01 Jan 1980 00:00:00 GMT") - ctx.Header().Set("Pragma", "no-cache") - ctx.Header().Set("Cache-Control", "no-cache, max-age=0, must-revalidate") - ctx.Header().Set("Content-Type", "application/x-git-receive-pack-advertisement") + ctx.RespHeader().Set("Expires", "Fri, 01 Jan 1980 00:00:00 GMT") + ctx.RespHeader().Set("Pragma", "no-cache") + ctx.RespHeader().Set("Cache-Control", "no-cache, max-age=0, must-revalidate") + ctx.RespHeader().Set("Content-Type", "application/x-git-receive-pack-advertisement") _, _ = ctx.Write(packetWrite("# service=git-receive-pack\n")) _, _ = ctx.Write([]byte("0000")) _, _ = ctx.Write(infoRefsCache) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 464646a86..fe015145b 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -2343,7 +2343,7 @@ func ChangeIssueReaction(ctx *context.Context) { return } - html, err := ctx.HTMLString(string(tplReactions), map[string]interface{}{ + html, err := ctx.RenderToString(tplReactions, map[string]interface{}{ "ctx": ctx.Data, "ActionURL": fmt.Sprintf("%s/issues/%d/reactions", ctx.Repo.RepoLink, issue.Index), "Reactions": issue.Reactions.GroupByType(), @@ -2443,7 +2443,7 @@ func ChangeCommentReaction(ctx *context.Context) { return } - html, err := ctx.HTMLString(string(tplReactions), map[string]interface{}{ + html, err := ctx.RenderToString(tplReactions, map[string]interface{}{ "ctx": ctx.Data, "ActionURL": fmt.Sprintf("%s/comments/%d/reactions", ctx.Repo.RepoLink, comment.ID), "Reactions": comment.Reactions.GroupByType(), @@ -2565,7 +2565,7 @@ func updateAttachments(item interface{}, files []string) error { } func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment, content string) string { - attachHTML, err := ctx.HTMLString(string(tplAttachment), map[string]interface{}{ + attachHTML, err := ctx.RenderToString(tplAttachment, map[string]interface{}{ "ctx": ctx.Data, "Attachments": attachments, "Content": content, diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index f94424870..9445c1a48 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -771,7 +771,7 @@ func UpdatePullRequest(ctx *context.Context) { if err = pull_service.Update(issue.PullRequest, ctx.User, message, rebase); err != nil { if models.IsErrMergeConflicts(err) { conflictError := err.(models.ErrMergeConflicts) - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.pulls.merge_conflict"), "Summary": ctx.Tr("repo.pulls.merge_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -785,7 +785,7 @@ func UpdatePullRequest(ctx *context.Context) { return } else if models.IsErrRebaseConflicts(err) { conflictError := err.(models.ErrRebaseConflicts) - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.pulls.rebase_conflict", utils.SanitizeFlashErrorString(conflictError.CommitSHA)), "Summary": ctx.Tr("repo.pulls.rebase_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -940,7 +940,7 @@ func MergePullRequest(ctx *context.Context) { return } else if models.IsErrMergeConflicts(err) { conflictError := err.(models.ErrMergeConflicts) - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.editor.merge_conflict"), "Summary": ctx.Tr("repo.editor.merge_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -954,7 +954,7 @@ func MergePullRequest(ctx *context.Context) { return } else if models.IsErrRebaseConflicts(err) { conflictError := err.(models.ErrRebaseConflicts) - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.pulls.rebase_conflict", utils.SanitizeFlashErrorString(conflictError.CommitSHA)), "Summary": ctx.Tr("repo.pulls.rebase_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -983,7 +983,7 @@ func MergePullRequest(ctx *context.Context) { if len(message) == 0 { ctx.Flash.Error(ctx.Tr("repo.pulls.push_rejected_no_message")) } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.pulls.push_rejected"), "Summary": ctx.Tr("repo.pulls.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(pushrejErr.Message), @@ -1143,7 +1143,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { if len(message) == 0 { ctx.Flash.Error(ctx.Tr("repo.pulls.push_rejected_no_message")) } else { - flashError, err := ctx.HTMLString(string(tplAlertDetails), map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ "Message": ctx.Tr("repo.pulls.push_rejected"), "Summary": ctx.Tr("repo.pulls.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(pushrejErr.Message), diff --git a/routers/web/user/auth.go b/routers/web/user/auth.go index 55a4b1100..178852d3f 100644 --- a/routers/web/user/auth.go +++ b/routers/web/user/auth.go @@ -506,7 +506,7 @@ func U2FSign(ctx *context.Context) { if redirect == "" { redirect = setting.AppSubURL + "/" } - ctx.PlainText(200, []byte(redirect)) + ctx.PlainText(http.StatusOK, redirect) return } } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index bad621f91..975262cf9 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -839,7 +839,7 @@ func ShowSSHKeys(ctx *context.Context, uid int64) { buf.WriteString(keys[i].OmitEmail()) buf.WriteString("\n") } - ctx.PlainText(200, buf.Bytes()) + ctx.PlainTextBytes(http.StatusOK, buf.Bytes()) } // ShowGPGKeys output all the public GPG keys of user by uid @@ -878,7 +878,7 @@ func ShowGPGKeys(ctx *context.Context, uid int64) { } } writer.Close() - ctx.PlainText(200, buf.Bytes()) + ctx.PlainTextBytes(http.StatusOK, buf.Bytes()) } // Email2User show user page via email diff --git a/routers/web/user/oauth.go b/routers/web/user/oauth.go index d3baeaedc..3795d4e5b 100644 --- a/routers/web/user/oauth.go +++ b/routers/web/user/oauth.go @@ -251,7 +251,7 @@ type userInfoResponse struct { func InfoOAuth(ctx *context.Context) { if ctx.User == nil || ctx.Data["AuthedMethod"] != (&auth.OAuth2{}).Name() { ctx.Resp.Header().Set("WWW-Authenticate", `Bearer realm=""`) - ctx.HandleText(http.StatusUnauthorized, "no valid authorization") + ctx.PlainText(http.StatusUnauthorized, "no valid authorization") return } @@ -301,7 +301,7 @@ func getOAuthGroupsForUser(user *user_model.User) ([]string, error) { func IntrospectOAuth(ctx *context.Context) { if ctx.User == nil { ctx.Resp.Header().Set("WWW-Authenticate", `Bearer realm=""`) - ctx.HandleText(http.StatusUnauthorized, "no valid authorization") + ctx.PlainText(http.StatusUnauthorized, "no valid authorization") return } diff --git a/services/externalaccount/link.go b/services/externalaccount/link.go index e71a37090..95ada2254 100644 --- a/services/externalaccount/link.go +++ b/services/externalaccount/link.go @@ -8,6 +8,7 @@ import ( "fmt" user_model "code.gitea.io/gitea/models/user" + "github.com/markbates/goth" ) diff --git a/templates/status/500.tmpl b/templates/status/500.tmpl index e2eeb407b..43ff2c12e 100644 --- a/templates/status/500.tmpl +++ b/templates/status/500.tmpl @@ -3,8 +3,10 @@

500


- {{if .ErrorMsg}}

{{.i18n.Tr "error.occurred"}}:

-
{{.ErrorMsg}}
{{end}} + {{if .ErrorMsg}} +

{{.i18n.Tr "error.occurred"}}:

+
{{.ErrorMsg}}
+ {{end}} {{if .ShowFooterVersion}}

{{.i18n.Tr "admin.config.app_ver"}}: {{AppVer}}

{{end}} {{if .IsAdmin}}

{{.i18n.Tr "error.report_message" | Safe}}

{{end}}