为 filter 添加全局配置支持

This commit is contained in:
ExplodingDragon
2025-11-18 23:56:59 +08:00
parent f4ca1377ca
commit 268f21c2af
15 changed files with 340 additions and 285 deletions

View File

@@ -56,7 +56,7 @@ func main() {
if err != nil {
zap.L().Fatal("failed to init memory provider", zap.Error(err))
}
server := pkg.NewPageServer(http.DefaultClient,
server, err := pkg.NewPageServer(http.DefaultClient,
provider, domain, "gh-pages", memory, memory, 0, &nopCache{},
func(w http.ResponseWriter, r *http.Request, err error) {
if errors.Is(err, os.ErrNotExist) {
@@ -64,7 +64,10 @@ func main() {
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
}, make(map[string]map[string]any))
if err != nil {
zap.L().Fatal("failed to init page", zap.Error(err))
}
err = http.ListenAndServe(port, server)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
zap.L().Fatal("failed to start server", zap.Error(err))

View File

@@ -29,11 +29,10 @@ type Config struct {
Page ConfigPage `yaml:"page"` // 页面配置
Render ConfigRender `yaml:"render"` // 渲染配置
Proxy ConfigProxy `yaml:"proxy"` // 反向代理配置
StaticDir string `yaml:"static"` // 静态资源提供路径
Filters map[string]map[string]any `yaml:"filters"` // 渲染器配置
pageErrNotFound, pageErrUnknown *template.Template
}

View File

@@ -64,7 +64,7 @@ func main() {
if !ok {
log.Fatalln(errors.New("database not support cursor"))
}
pageServer := pkg.NewPageServer(
pageServer, err := pkg.NewPageServer(
http.DefaultClient,
backend,
config.Domain,
@@ -74,7 +74,11 @@ func main() {
config.Cache.MetaTTL,
cacheBlob.Child("filter"),
config.ErrorHandler,
config.Filters,
)
if err != nil {
log.Fatalln(err)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
defer stop()

View File

@@ -22,14 +22,14 @@ type FilterContext struct {
RepoDB kv.CursorPagedKV
}
type FilterParams map[string]any
type Params map[string]any
func (f FilterParams) String() string {
func (f Params) String() string {
marshal, _ := json.Marshal(f)
return strings.ReplaceAll(string(marshal), "\"", "'")
}
func (f FilterParams) Unmarshal(target any) error {
func (f Params) Unmarshal(target any) error {
marshal, err := json.Marshal(f)
if err != nil {
return err
@@ -40,7 +40,7 @@ func (f FilterParams) Unmarshal(target any) error {
type Filter struct {
Path string `json:"path"`
Type string `json:"type"`
Params FilterParams `json:"params"`
Params Params `json:"params"`
}
func NextCallWrapper(call FilterCall, parentCall NextCall, stack Filter) NextCall {
@@ -69,4 +69,7 @@ type FilterCall func(
next NextCall,
) error
type FilterInstance func(config FilterParams) (FilterCall, error)
type (
GlobalFilter func(config Params) (FilterInstance, error)
FilterInstance func(route Params) (FilterCall, error)
)

View File

@@ -6,7 +6,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/core"
)
var FilterInstBlock core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstBlock(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Code int `json:"code"`
Message string `json:"message"`
@@ -27,4 +28,5 @@ var FilterInstBlock core.FilterInstance = func(config core.FilterParams) (core.F
}
return nil
}, nil
}, nil
}

View File

@@ -1,12 +1,19 @@
package filters
import (
"errors"
"go.uber.org/zap"
"gopkg.d7z.net/gitea-pages/pkg/core"
"gopkg.d7z.net/gitea-pages/pkg/filters/goja"
)
func DefaultFilters() map[string]core.FilterInstance {
return map[string]core.FilterInstance{
func DefaultFilters(config map[string]map[string]any) (map[string]core.FilterInstance, error) {
if config == nil {
return nil, errors.New("config is nil")
}
result := make(map[string]core.FilterInstance)
for key, instance := range map[string]core.GlobalFilter{
"block": FilterInstBlock,
"redirect": FilterInstRedirect,
"direct": FilterInstDirect,
@@ -15,5 +22,20 @@ func DefaultFilters() map[string]core.FilterInstance {
"failback": FilterInstFailback,
"template": FilterInstTemplate,
"js": goja.FilterInstGoJa,
} {
item, ok := config[key]
if !ok {
item = make(map[string]any)
}
if item["_disable"] == true {
zap.L().Debug("skip filter", zap.String("key", key))
continue
}
inst, err := instance(item)
if err != nil {
return nil, err
}
result[key] = inst
}
return result, nil
}

View File

@@ -9,7 +9,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/core"
)
var FilterInstDefaultNotFound core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstDefaultNotFound(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
return func(ctx core.FilterContext, writer http.ResponseWriter, request *http.Request, next core.NextCall) error {
err := next(ctx, writer, request)
if err != nil && errors.Is(err, os.ErrNotExist) {
@@ -30,4 +31,5 @@ var FilterInstDefaultNotFound core.FilterInstance = func(config core.FilterParam
}
return err
}, nil
}, nil
}

View File

@@ -14,7 +14,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/core"
)
var FilterInstDirect core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstDirect(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Prefix string `json:"prefix"`
}
@@ -69,4 +70,5 @@ var FilterInstDirect core.FilterInstance = func(config core.FilterParams) (core.
_, err = io.Copy(writer, resp.Body)
return err
}, nil
}, nil
}

View File

@@ -12,7 +12,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/core"
)
var FilterInstFailback core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstFailback(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Path string `json:"path"`
}
@@ -45,4 +46,5 @@ var FilterInstFailback core.FilterInstance = func(config core.FilterParams) (cor
_, err = io.Copy(writer, resp.Body)
return err
}, nil
}, nil
}

View File

@@ -15,7 +15,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/core"
)
var FilterInstGoJa core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstGoJa(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Exec string `json:"exec"`
Debug bool `json:"debug"`
@@ -76,6 +77,7 @@ var FilterInstGoJa core.FilterInstance = func(config core.FilterParams) (core.Fi
}
return debug.Flush(err)
}, nil
}, nil
}
func newRegistry(ctx core.FilterContext) *require.Registry {

View File

@@ -13,7 +13,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/utils"
)
var FilterInstProxy core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstProxy(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Prefix string `json:"prefix"`
Target string `json:"target"`
@@ -45,4 +46,5 @@ var FilterInstProxy core.FilterInstance = func(config core.FilterParams) (core.F
proxy.ServeHTTP(writer, request)
return nil
}, nil
}, nil
}

View File

@@ -15,7 +15,8 @@ import (
var portExp = regexp.MustCompile(`:\d+$`)
var FilterInstRedirect core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstRedirect(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Targets []string `json:"targets"`
Code int `json:"code"`
@@ -52,4 +53,5 @@ var FilterInstRedirect core.FilterInstance = func(config core.FilterParams) (cor
}
return next(ctx, writer, request)
}, nil
}, nil
}

View File

@@ -9,7 +9,8 @@ import (
"gopkg.d7z.net/gitea-pages/pkg/utils"
)
var FilterInstTemplate core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) {
func FilterInstTemplate(_ core.Params) (core.FilterInstance, error) {
return func(config core.Params) (core.FilterCall, error) {
var param struct {
Prefix string `json:"prefix"`
}
@@ -41,4 +42,5 @@ var FilterInstTemplate core.FilterInstance = func(config core.FilterParams) (cor
_, _ = out.WriteTo(writer)
return nil
}, nil
}, nil
}

View File

@@ -44,22 +44,27 @@ func NewPageServer(
cacheTTL time.Duration,
cacheBlob cache.Cache,
errorHandler func(w http.ResponseWriter, r *http.Request, err error),
) *Server {
filterConfig map[string]map[string]any,
) (*Server, error) {
svcMeta := core.NewServerMeta(client, backend, domain, cacheMeta, cacheTTL)
pageMeta := core.NewPageDomain(svcMeta, core.NewDomainAlias(db.Child("config").Child("alias")), domain, defaultBranch)
globCache, err := lru.New[string, glob.Glob](256)
if err != nil {
panic(err)
return nil, err
}
defaultFilters, err := filters.DefaultFilters(filterConfig)
if err != nil {
return nil, err
}
return &Server{
backend: backend,
meta: pageMeta,
db: db,
globCache: globCache,
filterMgr: filters.DefaultFilters(),
filterMgr: defaultFilters,
errorHandler: errorHandler,
cacheBlob: cacheBlob,
}
}, nil
}
func (s *Server) ServeHTTP(w http.ResponseWriter, request *http.Request) {

View File

@@ -46,7 +46,7 @@ func NewTestServer(domain string) *TestServer {
CleanupInt: time.Minute,
})
memoryKV, _ := kv.NewMemory("")
server := pkg.NewPageServer(
server, err := pkg.NewPageServer(
http.DefaultClient,
dummy,
domain,
@@ -62,8 +62,11 @@ func NewTestServer(domain string) *TestServer {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
},
make(map[string]map[string]any),
)
if err != nil {
panic(err)
}
return &TestServer{
dummy: dummy,
server: server,