重构部分 block 逻辑,调整 js 执行器的 kv 流程
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport"
|
<meta name="viewport"
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>js 验证</title>
|
<title>Hello World</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Hello World</p>
|
<p>Hello World</p>
|
||||||
|
|||||||
8
global-types/globals.d.ts
vendored
8
global-types/globals.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
// goja.d.ts
|
// global.d.ts
|
||||||
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@@ -25,6 +25,7 @@ declare global {
|
|||||||
put(key: string, value: string): Promise<void>;
|
put(key: string, value: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
const event: EventSystem;
|
const event: EventSystem;
|
||||||
|
|
||||||
// Request 相关类型
|
// Request 相关类型
|
||||||
@@ -103,8 +104,8 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface KVSystem {
|
interface KVSystem {
|
||||||
repo(group: string): KVOps;
|
repo(...group: string[]): KVOps;
|
||||||
org(group: string): KVOps;
|
org(...group: string[]): KVOps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const kv: KVSystem;
|
const kv: KVSystem;
|
||||||
@@ -118,6 +119,7 @@ declare global {
|
|||||||
debug(...args: any[]): void;
|
debug(...args: any[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
const console: Console;
|
const console: Console;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,17 +12,15 @@ import (
|
|||||||
type PageDomain struct {
|
type PageDomain struct {
|
||||||
*ServerMeta
|
*ServerMeta
|
||||||
|
|
||||||
alias *DomainAlias
|
|
||||||
baseDomain string
|
baseDomain string
|
||||||
defaultBranch string
|
defaultBranch string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPageDomain(meta *ServerMeta, alias *DomainAlias, baseDomain, defaultBranch string) *PageDomain {
|
func NewPageDomain(meta *ServerMeta, baseDomain, defaultBranch string) *PageDomain {
|
||||||
return &PageDomain{
|
return &PageDomain{
|
||||||
baseDomain: baseDomain,
|
baseDomain: baseDomain,
|
||||||
defaultBranch: defaultBranch,
|
defaultBranch: defaultBranch,
|
||||||
ServerMeta: meta,
|
ServerMeta: meta,
|
||||||
alias: alias,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +38,7 @@ func (p *PageDomain) ParseDomainMeta(ctx context.Context, domain, path, branch s
|
|||||||
}
|
}
|
||||||
pathArr := strings.Split(strings.TrimPrefix(path, "/"), "/")
|
pathArr := strings.Split(strings.TrimPrefix(path, "/"), "/")
|
||||||
if !strings.HasSuffix(domain, "."+p.baseDomain) {
|
if !strings.HasSuffix(domain, "."+p.baseDomain) {
|
||||||
alias, err := p.alias.Query(ctx, domain) // 确定 alias 是否存在内容
|
alias, err := p.Alias.Query(ctx, domain) // 确定 alias 是否存在内容
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.L().Warn("unknown domain", zap.String("base", p.baseDomain), zap.String("domain", domain), zap.Error(err))
|
zap.L().Warn("unknown domain", zap.String("base", p.baseDomain), zap.String("domain", domain), zap.Error(err))
|
||||||
return nil, os.ErrNotExist
|
return nil, os.ErrNotExist
|
||||||
@@ -83,10 +81,6 @@ func (p *PageDomain) returnMeta(ctx context.Context, owner, repo, branch string,
|
|||||||
result.Owner = owner
|
result.Owner = owner
|
||||||
result.Repo = repo
|
result.Repo = repo
|
||||||
result.Path = strings.Join(path, "/")
|
result.Path = strings.Join(path, "/")
|
||||||
// todo: 优化保存逻辑 ,减少写入
|
|
||||||
if err = p.alias.Bind(ctx, meta.Alias, result.Owner, result.Repo, branch); err != nil {
|
|
||||||
zap.L().Warn("alias binding error.", zap.Error(err))
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
type ServerMeta struct {
|
type ServerMeta struct {
|
||||||
Backend
|
Backend
|
||||||
Domain string
|
Domain string
|
||||||
|
Alias *DomainAlias
|
||||||
|
|
||||||
client *http.Client
|
client *http.Client
|
||||||
cache *tools.KVCache[PageMetaContent]
|
cache *tools.KVCache[PageMetaContent]
|
||||||
@@ -70,10 +71,11 @@ func (m *PageMetaContent) String() string {
|
|||||||
return string(marshal)
|
return string(marshal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerMeta(client *http.Client, backend Backend, domain string, cache kv.KV, ttl time.Duration) *ServerMeta {
|
func NewServerMeta(client *http.Client, backend Backend, domain string, alias *DomainAlias, cache kv.KV, ttl time.Duration) *ServerMeta {
|
||||||
return &ServerMeta{
|
return &ServerMeta{
|
||||||
Backend: backend,
|
Backend: backend,
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
|
Alias: alias,
|
||||||
client: client,
|
client: client,
|
||||||
cache: tools.NewCache[PageMetaContent](cache, "meta", ttl),
|
cache: tools.NewCache[PageMetaContent](cache, "meta", ttl),
|
||||||
locker: utils.NewLocker(),
|
locker: utils.NewLocker(),
|
||||||
@@ -144,7 +146,11 @@ func (s *ServerMeta) GetMeta(ctx context.Context, owner, repo, branch string) (*
|
|||||||
_ = s.cache.Store(ctx, key, *rel)
|
_ = s.cache.Store(ctx, key, *rel)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// todo: 优化保存逻辑 ,减少写入
|
||||||
|
if err = s.Alias.Bind(ctx, rel.Alias, owner, repo, branch); err != nil {
|
||||||
|
zap.L().Warn("alias binding error.", zap.Error(err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
_ = s.cache.Store(ctx, key, *rel)
|
_ = s.cache.Store(ctx, key, *rel)
|
||||||
return rel, nil
|
return rel, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package filters
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
"gopkg.d7z.net/gitea-pages/pkg/core"
|
"gopkg.d7z.net/gitea-pages/pkg/core"
|
||||||
)
|
)
|
||||||
@@ -16,7 +17,7 @@ func FilterInstBlock(_ core.Params) (core.FilterInstance, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if param.Code == 0 {
|
if param.Code == 0 {
|
||||||
param.Code = http.StatusForbidden
|
return nil, os.ErrNotExist
|
||||||
}
|
}
|
||||||
if param.Message == "" {
|
if param.Message == "" {
|
||||||
param.Message = http.StatusText(param.Code)
|
param.Message = http.StatusText(param.Code)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// todo: 新增超时配置
|
// todo: 新增超时配置
|
||||||
|
|
||||||
func FilterInstGoJa(gl core.Params) (core.FilterInstance, error) {
|
func FilterInstGoJa(gl core.Params) (core.FilterInstance, error) {
|
||||||
var global struct {
|
var global struct {
|
||||||
Timeout time.Duration `json:"timeout"`
|
Timeout time.Duration `json:"timeout"`
|
||||||
@@ -50,7 +51,7 @@ func FilterInstGoJa(gl core.Params) (core.FilterInstance, error) {
|
|||||||
|
|
||||||
debug := NewDebug(global.EnableDebug && param.Debug && request.URL.Query().
|
debug := NewDebug(global.EnableDebug && param.Debug && request.URL.Query().
|
||||||
Get("debug") == "true", request, w)
|
Get("debug") == "true", request, w)
|
||||||
program, err := goja.Compile("main.js", js, false)
|
program, err := goja.Compile(param.Exec, js, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return debug.Flush(err)
|
return debug.Flush(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package goja
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -12,22 +11,21 @@ import (
|
|||||||
|
|
||||||
func KVInject(ctx core.FilterContext, jsCtx *goja.Runtime) error {
|
func KVInject(ctx core.FilterContext, jsCtx *goja.Runtime) error {
|
||||||
return jsCtx.GlobalObject().Set("kv", map[string]interface{}{
|
return jsCtx.GlobalObject().Set("kv", map[string]interface{}{
|
||||||
"repo": func(group string) (goja.Value, error) {
|
"repo": func(group ...string) (goja.Value, error) {
|
||||||
return kvResult(ctx.RepoDB)(ctx, jsCtx, group)
|
return kvResult(ctx.RepoDB)(ctx, jsCtx, group...)
|
||||||
},
|
},
|
||||||
"org": func(group string) (goja.Value, error) {
|
"org": func(group ...string) (goja.Value, error) {
|
||||||
return kvResult(ctx.OrgDB)(ctx, jsCtx, group)
|
return kvResult(ctx.OrgDB)(ctx, jsCtx, group...)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func kvResult(db kv.CursorPagedKV) func(ctx core.FilterContext, jsCtx *goja.Runtime, group string) (goja.Value, error) {
|
func kvResult(db kv.CursorPagedKV) func(ctx core.FilterContext, jsCtx *goja.Runtime, group ...string) (goja.Value, error) {
|
||||||
return func(ctx core.FilterContext, jsCtx *goja.Runtime, group string) (goja.Value, error) {
|
return func(ctx core.FilterContext, jsCtx *goja.Runtime, group ...string) (goja.Value, error) {
|
||||||
group = strings.TrimSpace(group)
|
if len(group) == 0 {
|
||||||
if group == "" {
|
|
||||||
return goja.Undefined(), errors.New("invalid group")
|
return goja.Undefined(), errors.New("invalid group")
|
||||||
}
|
}
|
||||||
db := db.Child(group).(kv.CursorPagedKV)
|
db := db.Child(group...).(kv.CursorPagedKV)
|
||||||
return jsCtx.ToValue(map[string]interface{}{
|
return jsCtx.ToValue(map[string]interface{}{
|
||||||
"get": func(key string) (goja.Value, error) {
|
"get": func(key string) (goja.Value, error) {
|
||||||
get, err := db.Get(ctx, key)
|
get, err := db.Get(ctx, key)
|
||||||
|
|||||||
@@ -54,8 +54,9 @@ func NewPageServer(
|
|||||||
errorHandler func(w http.ResponseWriter, r *http.Request, err error),
|
errorHandler func(w http.ResponseWriter, r *http.Request, err error),
|
||||||
filterConfig map[string]map[string]any,
|
filterConfig map[string]map[string]any,
|
||||||
) (*Server, error) {
|
) (*Server, error) {
|
||||||
svcMeta := core.NewServerMeta(client, backend, domain, cacheMeta, cacheMetaTTL)
|
alias := core.NewDomainAlias(db.Child("config", "alias"))
|
||||||
pageMeta := core.NewPageDomain(svcMeta, core.NewDomainAlias(db.Child("config", "alias")), domain, defaultBranch)
|
svcMeta := core.NewServerMeta(client, backend, domain, alias, cacheMeta, cacheMetaTTL)
|
||||||
|
pageMeta := core.NewPageDomain(svcMeta, domain, defaultBranch)
|
||||||
globCache, err := lru.New[string, glob.Glob](512)
|
globCache, err := lru.New[string, glob.Glob](512)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func Test_filter_block(t *testing.T) {
|
|||||||
routes:
|
routes:
|
||||||
- path: "bad.html"
|
- path: "bad.html"
|
||||||
block:
|
block:
|
||||||
code:
|
code: 403
|
||||||
`)
|
`)
|
||||||
data, _, err = server.OpenFile("https://org1.example.com/repo1/")
|
data, _, err = server.OpenFile("https://org1.example.com/repo1/")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -32,5 +32,5 @@ routes:
|
|||||||
assert.Equal(t, 403, resp.StatusCode)
|
assert.Equal(t, 403, resp.StatusCode)
|
||||||
// 默认排除的内容
|
// 默认排除的内容
|
||||||
_, resp, _ = server.OpenFile("https://org1.example.com/repo1/.pages.yaml")
|
_, resp, _ = server.OpenFile("https://org1.example.com/repo1/.pages.yaml")
|
||||||
assert.Equal(t, 403, resp.StatusCode)
|
assert.Equal(t, 404, resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user