aboutsummaryrefslogtreecommitdiffstats
path: root/routers/install
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-05-04 14:36:34 +0800
committerGitHub <noreply@github.com>2023-05-04 14:36:34 +0800
commit5d77691d428d5302ee4df6c2a936b8e2ea9dca7e (patch)
tree4fa6b13f2ae81c5de94d84f2288ae1f5653c011f /routers/install
parent75ea0d5dba5dbf2f84cef2d12460fdd566d43e62 (diff)
downloadgitea-5d77691d428d5302ee4df6c2a936b8e2ea9dca7e.tar.gz
gitea-5d77691d428d5302ee4df6c2a936b8e2ea9dca7e.zip
Improve template system and panic recovery (#24461)
Partially for #24457 Major changes: 1. The old `signedUserNameStringPointerKey` is quite hacky, use `ctx.Data[SignedUser]` instead 2. Move duplicate code from `Contexter` to `CommonTemplateContextData` 3. Remove incorrect copying&pasting code `ctx.Data["Err_Password"] = true` in API handlers 4. Use one unique `RenderPanicErrorPage` for panic error page rendering 5. Move `stripSlashesMiddleware` to be the first middleware 6. Install global panic recovery handler, it works for both `install` and `web` 7. Make `500.tmpl` only depend minimal template functions/variables, avoid triggering new panics Screenshot: <details> ![image](https://user-images.githubusercontent.com/2114189/235444895-cecbabb8-e7dc-4360-a31c-b982d11946a7.png) </details>
Diffstat (limited to 'routers/install')
-rw-r--r--routers/install/install.go30
-rw-r--r--routers/install/routes.go66
2 files changed, 15 insertions, 81 deletions
diff --git a/routers/install/install.go b/routers/install/install.go
index c838db6582..714ddd5548 100644
--- a/routers/install/install.go
+++ b/routers/install/install.go
@@ -5,7 +5,6 @@
package install
import (
- goctx "context"
"fmt"
"net/http"
"os"
@@ -53,33 +52,32 @@ func getSupportedDbTypeNames() (dbTypeNames []map[string]string) {
return dbTypeNames
}
-// Init prepare for rendering installation page
-func Init(ctx goctx.Context) func(next http.Handler) http.Handler {
+// Contexter prepare for rendering installation page
+func Contexter() func(next http.Handler) http.Handler {
rnd := templates.HTMLRenderer()
dbTypeNames := getSupportedDbTypeNames()
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
- locale := middleware.Locale(resp, req)
- startTime := time.Now()
ctx := context.Context{
Resp: context.NewResponse(resp),
Flash: &middleware.Flash{},
- Locale: locale,
+ Locale: middleware.Locale(resp, req),
Render: rnd,
+ Data: middleware.GetContextData(req.Context()),
Session: session.GetSession(req),
- Data: map[string]interface{}{
- "locale": locale,
- "Title": locale.Tr("install.install"),
- "PageIsInstall": true,
- "DbTypeNames": dbTypeNames,
- "AllLangs": translation.AllLangs(),
- "PageStartTime": startTime,
-
- "PasswordHashAlgorithms": hash.RecommendedHashAlgorithms,
- },
}
defer ctx.Close()
+ ctx.Data.MergeFrom(middleware.CommonTemplateContextData())
+ ctx.Data.MergeFrom(middleware.ContextData{
+ "locale": ctx.Locale,
+ "Title": ctx.Locale.Tr("install.install"),
+ "PageIsInstall": true,
+ "DbTypeNames": dbTypeNames,
+ "AllLangs": translation.AllLangs(),
+
+ "PasswordHashAlgorithms": hash.RecommendedHashAlgorithms,
+ })
ctx.Req = context.WithContext(req, &ctx)
next.ServeHTTP(resp, ctx.Req)
})
diff --git a/routers/install/routes.go b/routers/install/routes.go
index 88c7e99695..52c07cfa26 100644
--- a/routers/install/routes.go
+++ b/routers/install/routes.go
@@ -9,76 +9,14 @@ import (
"html"
"net/http"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/public"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/routers/common"
"code.gitea.io/gitea/routers/web/healthcheck"
"code.gitea.io/gitea/services/forms"
)
-type dataStore map[string]interface{}
-
-func (d *dataStore) GetData() map[string]interface{} {
- return *d
-}
-
-func installRecovery(ctx goctx.Context) func(next http.Handler) http.Handler {
- return func(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- defer func() {
- // Why we need this? The first recover will try to render a beautiful
- // error page for user, but the process can still panic again, then
- // we have to just recover twice and send a simple error page that
- // should not panic anymore.
- defer func() {
- if err := recover(); err != nil {
- combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, log.Stack(2))
- log.Error("%s", combinedErr)
- if setting.IsProd {
- http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
- } else {
- http.Error(w, combinedErr, http.StatusInternalServerError)
- }
- }
- }()
-
- if err := recover(); err != nil {
- combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, log.Stack(2))
- log.Error("%s", combinedErr)
-
- lc := middleware.Locale(w, req)
- store := dataStore{
- "Language": lc.Language(),
- "CurrentURL": setting.AppSubURL + req.URL.RequestURI(),
- "locale": lc,
- "SignedUserID": int64(0),
- "SignedUserName": "",
- }
-
- httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform")
- w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
-
- if !setting.IsProd {
- store["ErrorMsg"] = combinedErr
- }
- rnd := templates.HTMLRenderer()
- err = rnd.HTML(w, http.StatusInternalServerError, "status/500", templates.BaseVars().Merge(store))
- if err != nil {
- log.Error("%v", err)
- }
- }
- }()
-
- next.ServeHTTP(w, req)
- })
- }
-}
-
// Routes registers the installation routes
func Routes(ctx goctx.Context) *web.Route {
base := web.NewRoute()
@@ -86,9 +24,7 @@ func Routes(ctx goctx.Context) *web.Route {
base.RouteMethods("/assets/*", "GET, HEAD", public.AssetsHandlerFunc("/assets/"))
r := web.NewRoute()
- r.Use(common.Sessioner())
- r.Use(installRecovery(ctx))
- r.Use(Init(ctx))
+ r.Use(common.Sessioner(), Contexter())
r.Get("/", Install) // it must be on the root, because the "install.js" use the window.location to replace the "localhost" AppURL
r.Post("/", web.Bind(forms.InstallForm{}), SubmitInstall)
r.Get("/post-install", InstallDone)