forked from Shiloh/githaven
d32648b204
Refactor route path normalization and decouple it from the chi router. Fix the TODO, fix the legacy strange path behavior.
218 lines
6.9 KiB
Go
218 lines
6.9 KiB
Go
// Copyright 2016 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package routers
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"reflect"
|
|
"runtime"
|
|
|
|
"code.gitea.io/gitea/models"
|
|
authmodel "code.gitea.io/gitea/models/auth"
|
|
"code.gitea.io/gitea/modules/cache"
|
|
"code.gitea.io/gitea/modules/eventsource"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/highlight"
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/markup"
|
|
"code.gitea.io/gitea/modules/markup/external"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/ssh"
|
|
"code.gitea.io/gitea/modules/storage"
|
|
"code.gitea.io/gitea/modules/svg"
|
|
"code.gitea.io/gitea/modules/system"
|
|
"code.gitea.io/gitea/modules/templates"
|
|
"code.gitea.io/gitea/modules/translation"
|
|
"code.gitea.io/gitea/modules/util"
|
|
"code.gitea.io/gitea/modules/web"
|
|
"code.gitea.io/gitea/modules/web/routing"
|
|
actions_router "code.gitea.io/gitea/routers/api/actions"
|
|
packages_router "code.gitea.io/gitea/routers/api/packages"
|
|
apiv1 "code.gitea.io/gitea/routers/api/v1"
|
|
"code.gitea.io/gitea/routers/common"
|
|
"code.gitea.io/gitea/routers/private"
|
|
web_routers "code.gitea.io/gitea/routers/web"
|
|
actions_service "code.gitea.io/gitea/services/actions"
|
|
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
|
"code.gitea.io/gitea/services/auth"
|
|
"code.gitea.io/gitea/services/auth/source/oauth2"
|
|
"code.gitea.io/gitea/services/automerge"
|
|
"code.gitea.io/gitea/services/cron"
|
|
feed_service "code.gitea.io/gitea/services/feed"
|
|
indexer_service "code.gitea.io/gitea/services/indexer"
|
|
"code.gitea.io/gitea/services/mailer"
|
|
mailer_incoming "code.gitea.io/gitea/services/mailer/incoming"
|
|
markup_service "code.gitea.io/gitea/services/markup"
|
|
repo_migrations "code.gitea.io/gitea/services/migrations"
|
|
mirror_service "code.gitea.io/gitea/services/mirror"
|
|
pull_service "code.gitea.io/gitea/services/pull"
|
|
release_service "code.gitea.io/gitea/services/release"
|
|
repo_service "code.gitea.io/gitea/services/repository"
|
|
"code.gitea.io/gitea/services/repository/archiver"
|
|
"code.gitea.io/gitea/services/task"
|
|
"code.gitea.io/gitea/services/uinotification"
|
|
"code.gitea.io/gitea/services/webhook"
|
|
)
|
|
|
|
func mustInit(fn func() error) {
|
|
err := fn()
|
|
if err != nil {
|
|
ptr := reflect.ValueOf(fn).Pointer()
|
|
fi := runtime.FuncForPC(ptr)
|
|
log.Fatal("%s failed: %v", fi.Name(), err)
|
|
}
|
|
}
|
|
|
|
func mustInitCtx(ctx context.Context, fn func(ctx context.Context) error) {
|
|
err := fn(ctx)
|
|
if err != nil {
|
|
ptr := reflect.ValueOf(fn).Pointer()
|
|
fi := runtime.FuncForPC(ptr)
|
|
log.Fatal("%s(ctx) failed: %v", fi.Name(), err)
|
|
}
|
|
}
|
|
|
|
func syncAppConfForGit(ctx context.Context) error {
|
|
runtimeState := new(system.RuntimeState)
|
|
if err := system.AppState.Get(ctx, runtimeState); err != nil {
|
|
return err
|
|
}
|
|
|
|
updated := false
|
|
if runtimeState.LastAppPath != setting.AppPath {
|
|
log.Info("AppPath changed from '%s' to '%s'", runtimeState.LastAppPath, setting.AppPath)
|
|
runtimeState.LastAppPath = setting.AppPath
|
|
updated = true
|
|
}
|
|
if runtimeState.LastCustomConf != setting.CustomConf {
|
|
log.Info("CustomConf changed from '%s' to '%s'", runtimeState.LastCustomConf, setting.CustomConf)
|
|
runtimeState.LastCustomConf = setting.CustomConf
|
|
updated = true
|
|
}
|
|
|
|
if updated {
|
|
log.Info("re-sync repository hooks ...")
|
|
mustInitCtx(ctx, repo_service.SyncRepositoryHooks)
|
|
|
|
log.Info("re-write ssh public keys ...")
|
|
mustInitCtx(ctx, asymkey_service.RewriteAllPublicKeys)
|
|
|
|
return system.AppState.Set(ctx, runtimeState)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func InitWebInstallPage(ctx context.Context) {
|
|
translation.InitLocales(ctx)
|
|
setting.LoadSettingsForInstall()
|
|
mustInit(svg.Init)
|
|
}
|
|
|
|
// InitWebInstalled is for global installed configuration.
|
|
func InitWebInstalled(ctx context.Context) {
|
|
mustInitCtx(ctx, git.InitFull)
|
|
log.Info("Git version: %s (home: %s)", git.DefaultFeatures().VersionInfo(), git.HomeDir())
|
|
if !git.DefaultFeatures().SupportHashSha256 {
|
|
log.Warn("sha256 hash support is disabled - requires Git >= 2.42." + util.Iif(git.DefaultFeatures().UsingGogit, " Gogit is currently unsupported.", ""))
|
|
}
|
|
|
|
// Setup i18n
|
|
translation.InitLocales(ctx)
|
|
|
|
setting.LoadSettings()
|
|
mustInit(storage.Init)
|
|
|
|
mailer.NewContext(ctx)
|
|
mustInit(cache.Init)
|
|
mustInit(feed_service.Init)
|
|
mustInit(uinotification.Init)
|
|
mustInitCtx(ctx, archiver.Init)
|
|
|
|
highlight.NewContext()
|
|
external.RegisterRenderers()
|
|
markup.Init(markup_service.ProcessorHelper())
|
|
|
|
if setting.EnableSQLite3 {
|
|
log.Info("SQLite3 support is enabled")
|
|
} else if setting.Database.Type.IsSQLite3() {
|
|
log.Fatal("SQLite3 support is disabled, but it is used for database setting. Please get or build a Gitea release with SQLite3 support.")
|
|
}
|
|
|
|
mustInitCtx(ctx, common.InitDBEngine)
|
|
log.Info("ORM engine initialization successful!")
|
|
mustInit(system.Init)
|
|
mustInitCtx(ctx, oauth2.Init)
|
|
|
|
mustInit(release_service.Init)
|
|
|
|
mustInitCtx(ctx, models.Init)
|
|
mustInitCtx(ctx, authmodel.Init)
|
|
mustInitCtx(ctx, repo_service.Init)
|
|
|
|
// Booting long running goroutines.
|
|
mustInit(indexer_service.Init)
|
|
|
|
mirror_service.InitSyncMirrors()
|
|
mustInit(webhook.Init)
|
|
mustInit(pull_service.Init)
|
|
mustInit(automerge.Init)
|
|
mustInit(task.Init)
|
|
mustInit(repo_migrations.Init)
|
|
eventsource.GetManager().Init()
|
|
mustInitCtx(ctx, mailer_incoming.Init)
|
|
|
|
mustInitCtx(ctx, syncAppConfForGit)
|
|
|
|
mustInit(ssh.Init)
|
|
|
|
auth.Init()
|
|
mustInit(svg.Init)
|
|
|
|
actions_service.Init()
|
|
|
|
// Finally start up the cron
|
|
cron.NewContext(ctx)
|
|
}
|
|
|
|
// NormalRoutes represents non install routes
|
|
func NormalRoutes() *web.Route {
|
|
_ = templates.HTMLRenderer()
|
|
r := web.NewRoute()
|
|
r.Use(common.ProtocolMiddlewares()...)
|
|
|
|
r.Mount("/", web_routers.Routes())
|
|
r.Mount("/api/v1", apiv1.Routes())
|
|
r.Mount("/api/internal", private.Routes())
|
|
|
|
r.Post("/-/fetch-redirect", common.FetchRedirectDelegate)
|
|
|
|
if setting.Packages.Enabled {
|
|
// This implements package support for most package managers
|
|
r.Mount("/api/packages", packages_router.CommonRoutes())
|
|
// This implements the OCI API, this container registry "/v2" endpoint must be in the root of the site.
|
|
// If site admin deploys Gitea in a sub-path, they must configure their reverse proxy to map the "https://host/v2" endpoint to Gitea.
|
|
r.Mount("/v2", packages_router.ContainerRoutes())
|
|
}
|
|
|
|
if setting.Actions.Enabled {
|
|
prefix := "/api/actions"
|
|
r.Mount(prefix, actions_router.Routes(prefix))
|
|
|
|
// TODO: Pipeline api used for runner internal communication with gitea server. but only artifact is used for now.
|
|
// In Github, it uses ACTIONS_RUNTIME_URL=https://pipelines.actions.githubusercontent.com/fLgcSHkPGySXeIFrg8W8OBSfeg3b5Fls1A1CwX566g8PayEGlg/
|
|
// TODO: this prefix should be generated with a token string with runner ?
|
|
prefix = "/api/actions_pipeline"
|
|
r.Mount(prefix, actions_router.ArtifactsRoutes(prefix))
|
|
prefix = actions_router.ArtifactV4RouteBase
|
|
r.Mount(prefix, actions_router.ArtifactsV4Routes(prefix))
|
|
}
|
|
|
|
r.NotFound(func(w http.ResponseWriter, req *http.Request) {
|
|
routing.UpdateFuncInfo(req.Context(), routing.GetFuncInfo(http.NotFound, "GlobalNotFound"))
|
|
http.NotFound(w, req)
|
|
})
|
|
return r
|
|
}
|