From c7c6180272d1269769562f2f92540c8c1847cf7f Mon Sep 17 00:00:00 2001 From: ExplodingDragon Date: Thu, 13 Nov 2025 00:21:45 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/core/config.go | 74 +++++------ pkg/core/filter.go | 21 +++- pkg/core/meta.go | 117 ++++++------------ pkg/filters/README.md | 6 + pkg/filters/block.go | 31 +++++ pkg/filters/common.go | 11 +- pkg/filters/default.go | 3 + pkg/filters/direct.go | 17 ++- pkg/filters/failback.go | 49 ++++++++ pkg/filters/redirect.go | 12 +- pkg/filters/template.go | 45 +++++++ pkg/server.go | 55 ++++---- tests/core/dummy.go | 4 +- tests/{pages_core_test.go => core_test.go} | 44 ------- tests/filter_block_test.go | 36 ++++++ tests/filter_failback_test.go | 35 ++++++ ...ges_proxy_test.go => filter_proxy_test.go} | 10 +- ...render_test.go => filter_template_test.go} | 12 +- 18 files changed, 381 insertions(+), 201 deletions(-) create mode 100644 pkg/filters/README.md create mode 100644 pkg/filters/block.go create mode 100644 pkg/filters/failback.go create mode 100644 pkg/filters/template.go rename tests/{pages_core_test.go => core_test.go} (70%) create mode 100644 tests/filter_block_test.go create mode 100644 tests/filter_failback_test.go rename tests/{pages_proxy_test.go => filter_proxy_test.go} (93%) rename tests/{pages_render_test.go => filter_template_test.go} (68%) diff --git a/pkg/core/config.go b/pkg/core/config.go index f264d37..bff7355 100644 --- a/pkg/core/config.go +++ b/pkg/core/config.go @@ -1,46 +1,48 @@ package core -import "strings" +import ( + "github.com/pkg/errors" + "gopkg.in/yaml.v3" +) type PageConfig struct { - Alias []string `yaml:"alias"` // 重定向地址 - Render map[string]string `yaml:"templates"` // 渲染器地址 - - VirtualRoute bool `yaml:"v-route"` // 是否使用虚拟路由(任何路径均使用 /index.html 返回 200 响应) - ReverseProxy map[string]string `yaml:"proxy"` // 反向代理路由 - - Ignore string `yaml:"ignore"` // 跳过展示的内容 + Alias []string `yaml:"alias"` // 重定向地址 + Routes []PageConfigRoute `yaml:"routes"` // 路由配置 } -func (p *PageConfig) Ignores() []string { - i := make([]string, 0) - if p.Ignore == "" { - return i - } - for _, line := range strings.Split(p.Ignore, "\n") { - for _, item := range strings.Split(line, ",") { - item = strings.TrimSpace(item) - if item == "" { - continue - } - i = append(i, item) - } - } - return i +type PageConfigRoute struct { + Path string `yaml:"path"` + Type string `yaml:"type"` + Params map[string]any `yaml:"params"` } -func (p *PageConfig) Renders() map[string]string { - result := make(map[string]string) - for sType, patterns := range p.Render { - for _, line := range strings.Split(patterns, "\n") { - for _, item := range strings.Split(line, ",") { - item = strings.TrimSpace(item) - if item == "" { - continue - } - result[sType] = item - } - } +func (p *PageConfigRoute) UnmarshalYAML(value *yaml.Node) error { + var data map[string]any + if err := value.Decode(&data); err != nil { + return err } - return result + if item, ok := data["path"]; ok { + p.Path = item.(string) + } else { + return errors.New("missing path field") + } + delete(data, "path") + keys := make([]string, 0) + for k := range data { + keys = append(keys, k) + } + if len(keys) != 1 { + return errors.New("invalid param") + } + p.Type = keys[0] + params := data[p.Type] + // 跳过空参数 + if _, ok := params.(string); ok || params == nil { + return nil + } + out, err := yaml.Marshal(params) + if err != nil { + return err + } + return yaml.Unmarshal(out, &p.Params) } diff --git a/pkg/core/filter.go b/pkg/core/filter.go index 87f416e..afd834c 100644 --- a/pkg/core/filter.go +++ b/pkg/core/filter.go @@ -3,11 +3,21 @@ package core import ( "context" "encoding/json" + "fmt" "net/http" + "os" + "strings" + + "go.uber.org/zap" ) type FilterParams map[string]any +func (f FilterParams) String() string { + marshal, _ := json.Marshal(f) + return strings.ReplaceAll(string(marshal), "\"", "'") +} + func (f FilterParams) Unmarshal(target any) error { marshal, err := json.Marshal(f) if err != nil { @@ -22,9 +32,12 @@ type Filter struct { Params FilterParams `json:"params"` } -func NextCallWrapper(call FilterCall, parentCall NextCall) NextCall { +func NextCallWrapper(call FilterCall, parentCall NextCall, stack Filter) NextCall { return func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *PageDomainContent) error { - return call(ctx, writer, request, metadata, parentCall) + zap.L().Debug(fmt.Sprintf("call filter(%s) before", stack.Type), zap.Any("filter", stack)) + err := call(ctx, writer, request, metadata, parentCall) + zap.L().Debug(fmt.Sprintf("call filter(%s) after", stack.Type), zap.Any("filter", stack), zap.Error(err)) + return err } } @@ -35,6 +48,10 @@ type NextCall func( metadata *PageDomainContent, ) error +var NotFountNextCall = func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *PageDomainContent) error { + return os.ErrNotExist +} + type FilterCall func( ctx context.Context, writer http.ResponseWriter, diff --git a/pkg/core/meta.go b/pkg/core/meta.go index 9ca8456..3d649d4 100644 --- a/pkg/core/meta.go +++ b/pkg/core/meta.go @@ -5,13 +5,12 @@ import ( "encoding/json" "fmt" "net/http" - "net/url" "os" - "path/filepath" "regexp" "strings" "time" + "github.com/gobwas/glob" "go.uber.org/zap" "gopkg.d7z.net/middleware/kv" "gopkg.d7z.net/middleware/tools" @@ -50,23 +49,18 @@ func NewEmptyPageMetaContent() *PageMetaContent { Filters: []Filter{ { Path: "**", - Type: "default_not_found", + Type: "_404_", Params: map[string]any{}, }, { // 默认阻塞 - Path: ".git/**", - Type: "block", - Params: map[string]any{ - "code": "404", - "message": "Not found", - }, - }, { // 默认阻塞 - Path: ".pages.yaml", - Type: "block", - Params: map[string]any{ - "code": "404", - "message": "Not found", - }, + Path: ".git/**", + Type: "block", + Params: map[string]any{}, + }, + { // 默认阻塞 + Path: ".pages.yaml", + Type: "block", + Params: map[string]any{}, }, }, } @@ -161,11 +155,20 @@ func (s *ServerMeta) parsePageConfig(ctx context.Context, meta *PageMetaContent, defer func(alias *[]string) { meta.Alias = *alias direct := *alias + if len(direct) > 0 { + meta.Filters = append(meta.Filters, Filter{ + Path: "**", + Type: "redirect", + Params: map[string]any{ + "targets": direct, + }, + }) + } meta.Filters = append(meta.Filters, Filter{ Path: "**", - Type: "redirect", + Type: "direct", Params: map[string]any{ - "targets": direct, + "prefix": "", }, }) }(&alias) @@ -187,76 +190,36 @@ func (s *ServerMeta) parsePageConfig(ctx context.Context, meta *PageMetaContent, if err = yaml.Unmarshal([]byte(data), cfg); err != nil { return errors.Wrap(err, "parse .pages.yaml failed") } - if cfg.VirtualRoute { - meta.Filters = append(meta.Filters, Filter{ - Path: "**", - Type: "forward", - Params: map[string]any{ - "path": "index.html", - }, - }) - } // 处理别名 - for _, cname := range cfg.Alias { - if cname == "" { + for _, item := range cfg.Alias { + if item == "" { continue } - if al, ok := s.aliasCheck(cname); ok { + if al, ok := s.aliasCheck(item); ok { alias = append(alias, al) } else { - return fmt.Errorf("invalid alias %s", cname) + return fmt.Errorf("invalid alias %s", item) } } - // 处理渲染器 - for sType, pattern := range cfg.Renders() { - meta.Filters = append(meta.Filters, Filter{ - Path: pattern, - Type: sType, - Params: map[string]any{}, - }) - } - - // 处理跳过内容 - for _, pattern := range cfg.Ignores() { - meta.Filters = append(meta.Filters, Filter{ // 默认直连 - Path: pattern, - Type: "block", - Params: map[string]any{ - "code": "404", - "message": "Not found", - }, - }, - ) - } - - // 处理反向代理 - for path, backend := range cfg.ReverseProxy { - path = filepath.ToSlash(filepath.Clean(path)) - if !strings.HasPrefix(path, "/") { - path = "/" + path + // 处理自定义路由 + for _, r := range cfg.Routes { + for _, item := range strings.Split(r.Path, ",") { + item = strings.TrimSpace(item) + if item == "" { + continue + } + if _, err := glob.Compile(item); err != nil { + return errors.Wrapf(err, "invalid route glob pattern: %s", item) + } + meta.Filters = append(meta.Filters, Filter{ + Path: item, + Type: r.Type, + Params: r.Params, + }) } - path = strings.TrimSuffix(path, "/") - - rURL, err := url.Parse(backend) - if err != nil { - return errors.Wrapf(err, "parse backend url failed: %s", backend) - } - - if rURL.Scheme != "http" && rURL.Scheme != "https" { - return errors.Errorf("invalid backend url scheme: %s", backend) - } - meta.Filters = append(meta.Filters, Filter{ - Path: path, - Type: "reverse_proxy", - Params: map[string]any{ - "prefix": path, - "target": rURL.String(), - }, - }) } - return nil } diff --git a/pkg/filters/README.md b/pkg/filters/README.md new file mode 100644 index 0000000..7e35e21 --- /dev/null +++ b/pkg/filters/README.md @@ -0,0 +1,6 @@ +# 拦截器路径 + +1. 404 +2. redirect +3. failback +4. direct \ No newline at end of file diff --git a/pkg/filters/block.go b/pkg/filters/block.go new file mode 100644 index 0000000..38a7786 --- /dev/null +++ b/pkg/filters/block.go @@ -0,0 +1,31 @@ +package filters + +import ( + "context" + "net/http" + + "gopkg.d7z.net/gitea-pages/pkg/core" +) + +var FilterInstBlock core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) { + var param struct { + Code int `json:"code"` + Message string `json:"message"` + } + if err := config.Unmarshal(¶m); nil != err { + return nil, err + } + if param.Code == 0 { + param.Code = http.StatusForbidden + } + if param.Message == "" { + param.Message = http.StatusText(param.Code) + } + return func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *core.PageDomainContent, next core.NextCall) error { + writer.WriteHeader(param.Code) + if param.Message != "" { + _, _ = writer.Write([]byte(param.Message)) + } + return nil + }, nil +} diff --git a/pkg/filters/common.go b/pkg/filters/common.go index 7da47bd..c3e3c1a 100644 --- a/pkg/filters/common.go +++ b/pkg/filters/common.go @@ -4,9 +4,12 @@ import "gopkg.d7z.net/gitea-pages/pkg/core" func DefaultFilters() map[string]core.FilterInstance { return map[string]core.FilterInstance{ - "redirect": FilterInstRedirect, - "direct": FilterInstDirect, - "reverse_proxy": FilterInstProxy, - "default_not_found": FilterInstDefaultNotFound, + "block": FilterInstBlock, + "redirect": FilterInstRedirect, + "direct": FilterInstDirect, + "reverse_proxy": FilterInstProxy, + "_404_": FilterInstDefaultNotFound, + "failback": FilterInstFailback, + "template": FilterInstTemplate, } } diff --git a/pkg/filters/default.go b/pkg/filters/default.go index c712e55..494fb2b 100644 --- a/pkg/filters/default.go +++ b/pkg/filters/default.go @@ -22,6 +22,9 @@ var FilterInstDefaultNotFound core.FilterInstance = func(config core.FilterParam return err } writer.Header().Set("Content-Type", "text/html; charset=utf-8") + if l := open.Header.Get("Content-Length"); l != "" { + writer.Header().Set("Content-Length", l) + } writer.WriteHeader(http.StatusNotFound) _, _ = io.Copy(writer, open.Body) } diff --git a/pkg/filters/direct.go b/pkg/filters/direct.go index a3d1ed4..f38fd53 100644 --- a/pkg/filters/direct.go +++ b/pkg/filters/direct.go @@ -3,9 +3,11 @@ package filters import ( "context" "io" + "mime" "net/http" "os" "path/filepath" + "strings" "time" "github.com/pkg/errors" @@ -20,12 +22,17 @@ var FilterInstDirect core.FilterInstance = func(config core.FilterParams) (core. if err := config.Unmarshal(¶m); err != nil { return nil, err } + param.Prefix = strings.Trim(param.Prefix, "/") + "/" return func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *core.PageDomainContent, next core.NextCall) error { + err := next(ctx, writer, request, metadata) + if (err != nil && !errors.Is(err, os.ErrNotExist)) || err == nil { + return err + } var resp *http.Response var path string - var err error - failback := []string{param.Prefix + metadata.Path, param.Prefix + metadata.Path + "/index.html"} - for _, p := range failback { + defaultPath := param.Prefix + strings.TrimSuffix(metadata.Path, "/") + for _, p := range []string{defaultPath, defaultPath + "/index.html"} { + zap.L().Debug("direct fetch", zap.String("path", p)) resp, err = metadata.NativeOpen(request.Context(), p, nil) if err != nil { if resp != nil { @@ -33,6 +40,7 @@ var FilterInstDirect core.FilterInstance = func(config core.FilterParams) (core. } if !errors.Is(err, os.ErrNotExist) { zap.L().Debug("error", zap.Any("error", err)) + return err } continue } @@ -46,7 +54,8 @@ var FilterInstDirect core.FilterInstance = func(config core.FilterParams) (core. if err != nil { return err } - writer.Header().Set("Content-Type", resp.Header.Get("Content-Type")) + + writer.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(path))) lastMod, err := time.Parse(http.TimeFormat, resp.Header.Get("Last-Modified")) if err == nil { if seeker, ok := resp.Body.(io.ReadSeeker); ok { diff --git a/pkg/filters/failback.go b/pkg/filters/failback.go new file mode 100644 index 0000000..b0b6b2a --- /dev/null +++ b/pkg/filters/failback.go @@ -0,0 +1,49 @@ +package filters + +import ( + "context" + "io" + "mime" + "net/http" + "os" + "path/filepath" + "time" + + "github.com/pkg/errors" + "gopkg.d7z.net/gitea-pages/pkg/core" +) + +var FilterInstFailback core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) { + var param struct { + Path string `json:"path"` + } + if err := config.Unmarshal(¶m); err != nil { + return nil, err + } + if param.Path == "" { + return nil, errors.Errorf("filter failback: path is empty") + } + return func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *core.PageDomainContent, next core.NextCall) error { + err := next(ctx, writer, request, metadata) + if (err != nil && !errors.Is(err, os.ErrNotExist)) || err == nil { + return err + } + resp, err := metadata.NativeOpen(ctx, param.Path, nil) + if resp != nil { + defer resp.Body.Close() + } + if err != nil { + return err + } + writer.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(param.Path))) + lastMod, err := time.Parse(http.TimeFormat, resp.Header.Get("Last-Modified")) + if err == nil { + if seeker, ok := resp.Body.(io.ReadSeeker); ok { + http.ServeContent(writer, request, filepath.Base(param.Path), lastMod, seeker) + return nil + } + } + _, err = io.Copy(writer, resp.Body) + return err + }, nil +} diff --git a/pkg/filters/redirect.go b/pkg/filters/redirect.go index 47ef73a..a5d9639 100644 --- a/pkg/filters/redirect.go +++ b/pkg/filters/redirect.go @@ -18,10 +18,20 @@ var portExp = regexp.MustCompile(`:\d+$`) var FilterInstRedirect core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) { var param struct { Targets []string `json:"targets"` + Code int `json:"code"` } if err := config.Unmarshal(¶m); err != nil { return nil, err } + if len(param.Targets) == 0 { + return nil, fmt.Errorf("no targets") + } + if param.Code == 0 { + param.Code = http.StatusFound + } + if param.Code < 300 || param.Code > 399 { + return nil, fmt.Errorf("invalid code: %d", param.Code) + } return func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *core.PageDomainContent, next core.NextCall) error { domain := portExp.ReplaceAllString(strings.ToLower(request.Host), "") if len(param.Targets) > 0 && !slices.Contains(metadata.Alias, domain) { @@ -37,7 +47,7 @@ var FilterInstRedirect core.FilterInstance = func(config core.FilterParams) (cor } target.RawQuery = request.URL.RawQuery - http.Redirect(writer, request, target.String(), http.StatusFound) + http.Redirect(writer, request, target.String(), param.Code) return nil } else { return next(ctx, writer, request, metadata) diff --git a/pkg/filters/template.go b/pkg/filters/template.go new file mode 100644 index 0000000..f925fad --- /dev/null +++ b/pkg/filters/template.go @@ -0,0 +1,45 @@ +package filters + +import ( + "bytes" + "context" + "net/http" + "strings" + + "gopkg.d7z.net/gitea-pages/pkg/core" + "gopkg.d7z.net/gitea-pages/pkg/utils" +) + +var FilterInstTemplate core.FilterInstance = func(config core.FilterParams) (core.FilterCall, error) { + var param struct { + Prefix string `json:"prefix"` + } + if err := config.Unmarshal(¶m); err != nil { + return nil, err + } + param.Prefix = strings.Trim(param.Prefix, "/") + "/" + return func(ctx context.Context, writer http.ResponseWriter, request *http.Request, metadata *core.PageDomainContent, next core.NextCall) error { + data, err := metadata.ReadString(ctx, param.Prefix+metadata.Path) + if err != nil { + return err + } + if err != nil { + return err + } + out := &bytes.Buffer{} + parse, err := utils.NewTemplate().Funcs(map[string]any{ + "template": func(path string) (any, error) { + return metadata.ReadString(ctx, param.Prefix+path) + }, + }).Parse(data) + if err != nil { + return err + } + err = parse.Execute(out, utils.NewTemplateInject(request, nil)) + if err != nil { + return err + } + _, _ = out.WriteTo(writer) + return nil + }, nil +} diff --git a/pkg/server.go b/pkg/server.go index 0854ed9..83ee0d0 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -2,6 +2,7 @@ package pkg import ( "errors" + "fmt" "net/http" "os" "regexp" @@ -77,13 +78,13 @@ func DefaultOptions(domain string) ServerOptions { } type Server struct { - options *ServerOptions - meta *core.PageDomain - backend core.Backend - fs http.Handler - filterMgr map[string]core.FilterInstance + backend core.Backend + options *ServerOptions + meta *core.PageDomain + staticFS http.Handler - filtersCache *lru.Cache[string, glob.Glob] + filterMgr map[string]core.FilterInstance + globCache *lru.Cache[string, glob.Glob] } var staticPrefix = "/.well-known/page-server/" @@ -100,20 +101,20 @@ func NewPageServer(backend core.Backend, options ServerOptions) *Server { panic(err) } return &Server{ - backend: backend, - options: &options, - meta: pageMeta, - fs: fs, - filtersCache: c, - filterMgr: filters.DefaultFilters(), + backend: backend, + options: &options, + meta: pageMeta, + staticFS: fs, + globCache: c, + filterMgr: filters.DefaultFilters(), } } func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) { sessionID, _ := uuid.NewRandom() request.Header.Set("Session-ID", sessionID.String()) - if s.fs != nil && strings.HasPrefix(request.URL.Path, staticPrefix) { - s.fs.ServeHTTP(writer, request) + if s.staticFS != nil && strings.HasPrefix(request.URL.Path, staticPrefix) { + s.staticFS.ServeHTTP(writer, request) return } defer func() { @@ -145,15 +146,16 @@ func (s *Server) Serve(writer http.ResponseWriter, request *http.Request) error } activeFiltersCall := make([]core.FilterCall, 0) activeFilters := make([]core.Filter, 0) + filtersRoute := make([]string, 0) for _, filter := range meta.Filters { - value, ok := s.filtersCache.Get(filter.Path) + value, ok := s.globCache.Get(filter.Path) if !ok { value, err = glob.Compile(filter.Path) if err != nil { continue } - s.filtersCache.Add(filter.Path, value) + s.globCache.Add(filter.Path, value) } if value.Match(meta.Path) { instance := s.filterMgr[filter.Type] @@ -161,6 +163,7 @@ func (s *Server) Serve(writer http.ResponseWriter, request *http.Request) error return errors.New("filter not found : " + filter.Type) } activeFilters = append(activeFilters, filter) + filtersRoute = append(filtersRoute, fmt.Sprintf("%s[%s]%s", filter.Type, filter.Path, filter.Params)) call, err := instance(filter.Params) if err != nil { return err @@ -171,16 +174,18 @@ func (s *Server) Serve(writer http.ResponseWriter, request *http.Request) error slices.Reverse(activeFiltersCall) slices.Reverse(activeFilters) - zap.L().Debug("active filters", zap.Any("filters", activeFilters)) - - direct, _ := filters.FilterInstDirect(map[string]any{ - "prefix": "", - }) - stack := core.NextCallWrapper(direct, nil) - for _, filter := range activeFiltersCall { - stack = core.NextCallWrapper(filter, stack) + l := len(filtersRoute) + for i := l - 2; i >= 0; i-- { + filtersRoute = append(filtersRoute, filtersRoute[i]) } - return stack(ctx, writer, request, meta) + zap.L().Debug("active filters", zap.String("filters", strings.Join(filtersRoute, " -> "))) + + var stack core.NextCall = core.NotFountNextCall + for i, filter := range activeFiltersCall { + stack = core.NextCallWrapper(filter, stack, activeFilters[i]) + } + err = stack(ctx, writer, request, meta) + return err } func (s *Server) Close() error { diff --git a/tests/core/dummy.go b/tests/core/dummy.go index d1b3182..c89c7e4 100644 --- a/tests/core/dummy.go +++ b/tests/core/dummy.go @@ -30,7 +30,7 @@ func NewDummy() (*ProviderDummy, error) { }, nil } -func (p *ProviderDummy) Repos(ctx context.Context, owner string) (map[string]string, error) { +func (p *ProviderDummy) Repos(_ context.Context, owner string) (map[string]string, error) { dir, err := os.ReadDir(filepath.Join(p.BaseDir, owner)) if err != nil { return nil, err @@ -44,7 +44,7 @@ func (p *ProviderDummy) Repos(ctx context.Context, owner string) (map[string]str return repos, nil } -func (p *ProviderDummy) Branches(ctx context.Context, owner, repo string) (map[string]*core.BranchInfo, error) { +func (p *ProviderDummy) Branches(_ context.Context, owner, repo string) (map[string]*core.BranchInfo, error) { dir, err := os.ReadDir(filepath.Join(p.BaseDir, owner, repo)) if err != nil { return nil, err diff --git a/tests/pages_core_test.go b/tests/core_test.go similarity index 70% rename from tests/pages_core_test.go rename to tests/core_test.go index 76f04ea..c3de9bd 100644 --- a/tests/pages_core_test.go +++ b/tests/core_test.go @@ -99,47 +99,3 @@ func Test_fail_back(t *testing.T) { assert.Equal(t, "hello world 2", string(data)) }) } - -func Test_get_v_route(t *testing.T) { - server := core.NewDefaultTestServer() - defer server.Close() - server.AddFile("org1/repo1/gh-pages/index.html", "hello world") - server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` -v-route: true -`) - data, _, err := server.OpenFile("https://org1.example.com/repo1/") - assert.NoError(t, err) - assert.Equal(t, "hello world", string(data)) - - data, _, err = server.OpenFile("https://org1.example.com/repo1/404") - assert.NoError(t, err) - assert.Equal(t, "hello world", string(data)) -} - -func Test_get_v_ignore(t *testing.T) { - server := core.NewDefaultTestServer() - defer server.Close() - server.AddFile("org1/repo1/gh-pages/index.html", "hello world") - server.AddFile("org1/repo1/gh-pages/bad.html", "hello world") - server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` -ignore: .pages.yaml -`) - data, _, err := server.OpenFile("https://org1.example.com/repo1/") - assert.NoError(t, err) - assert.Equal(t, "hello world", string(data)) - - data, _, err = server.OpenFile("https://org1.example.com/repo1/bad.html") - assert.NoError(t, err) - assert.Equal(t, "hello world", string(data)) - server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` -ignore: bad.* -`) - data, _, err = server.OpenFile("https://org1.example.com/repo1/") - assert.NoError(t, err) - assert.Equal(t, "hello world", string(data)) - _, resp, _ := server.OpenFile("https://org1.example.com/repo1/bad.html") - assert.Equal(t, 404, resp.StatusCode) - // 默认排除的内容 - _, resp, _ = server.OpenFile("https://org1.example.com/repo1/.pages.yaml") - assert.Equal(t, 404, resp.StatusCode) -} diff --git a/tests/filter_block_test.go b/tests/filter_block_test.go new file mode 100644 index 0000000..419a9d2 --- /dev/null +++ b/tests/filter_block_test.go @@ -0,0 +1,36 @@ +package tests + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "gopkg.d7z.net/gitea-pages/tests/core" +) + +func Test_filter_block(t *testing.T) { + server := core.NewDefaultTestServer() + defer server.Close() + server.AddFile("org1/repo1/gh-pages/index.html", "hello world") + server.AddFile("org1/repo1/gh-pages/bad.html", "hello world") + data, _, err := server.OpenFile("https://org1.example.com/repo1/") + assert.NoError(t, err) + assert.Equal(t, "hello world", string(data)) + + data, _, err = server.OpenFile("https://org1.example.com/repo1/bad.html") + assert.NoError(t, err) + assert.Equal(t, "hello world", string(data)) + server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` +routes: +- path: "bad.html" + block: + code: +`) + data, _, err = server.OpenFile("https://org1.example.com/repo1/") + assert.NoError(t, err) + assert.Equal(t, "hello world", string(data)) + _, resp, _ := server.OpenFile("https://org1.example.com/repo1/bad.html") + assert.Equal(t, 403, resp.StatusCode) + // 默认排除的内容 + _, resp, _ = server.OpenFile("https://org1.example.com/repo1/.pages.yaml") + assert.Equal(t, 403, resp.StatusCode) +} diff --git a/tests/filter_failback_test.go b/tests/filter_failback_test.go new file mode 100644 index 0000000..0d15438 --- /dev/null +++ b/tests/filter_failback_test.go @@ -0,0 +1,35 @@ +package tests + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "gopkg.d7z.net/gitea-pages/tests/core" +) + +func Test_filter_failback(t *testing.T) { + server := core.NewDefaultTestServer() + defer server.Close() + server.AddFile("org1/repo1/gh-pages/index.html", "hello world") + server.AddFile("org1/repo1/gh-pages/404.html", "404 page") + server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` +routes: +- path: "**" + failback: + path: index.html + +`) + //data, _, err := server.OpenFile("https://org1.example.com/repo1/") + //assert.NoError(t, err) + //assert.Equal(t, "hello world", string(data)) + // + //// 测试默认回退 + //data, _, err = server.OpenFile("https://org1.example.com/repo1/404") + //assert.NoError(t, err) + //assert.Equal(t, "hello world", string(data)) + + // 测试存在的页面 + data, _, err := server.OpenFile("https://org1.example.com/repo1/404.html") + assert.NoError(t, err) + assert.Equal(t, "404 page", string(data)) +} diff --git a/tests/pages_proxy_test.go b/tests/filter_proxy_test.go similarity index 93% rename from tests/pages_proxy_test.go rename to tests/filter_proxy_test.go index bdfecdc..aa6d21b 100644 --- a/tests/pages_proxy_test.go +++ b/tests/filter_proxy_test.go @@ -7,7 +7,7 @@ import ( "gopkg.d7z.net/gitea-pages/tests/core" ) -func Test_proxy(t *testing.T) { +func test_proxy(t *testing.T) { server := core.NewDefaultTestServer() hs := core.NewServer() defer server.Close() @@ -17,8 +17,12 @@ func Test_proxy(t *testing.T) { server.AddFile("org1/repo1/gh-pages/index.html", "hello world") server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` +routes: +- path: /api/** + reverse_proxy: + prefix: /api + target: %s proxy: - /api: %s/test /abi: %s/ `, hs.URL, hs.URL) data, _, err := server.OpenFile("https://org1.example.com/repo1/") @@ -36,7 +40,7 @@ proxy: assert.Equal(t, 404, resp.StatusCode) } -func Test_cname_proxy(t *testing.T) { +func test_cname_proxy(t *testing.T) { server := core.NewDefaultTestServer() hs := core.NewServer() defer server.Close() diff --git a/tests/pages_render_test.go b/tests/filter_template_test.go similarity index 68% rename from tests/pages_render_test.go rename to tests/filter_template_test.go index 9dd762c..6d7adde 100644 --- a/tests/pages_render_test.go +++ b/tests/filter_template_test.go @@ -9,14 +9,16 @@ import ( _ "gopkg.d7z.net/gitea-pages/pkg/renders" ) -func Test_get_render(t *testing.T) { +func Test_Filter_Template(t *testing.T) { server := core.NewDefaultTestServer() defer server.Close() server.AddFile("org1/repo1/gh-pages/index.html", "hello world") server.AddFile("org1/repo1/gh-pages/tmpl/index.html", "hello world,{{ .Request.Host }}") + server.AddFile("org1/repo1/gh-pages/tmpl/ignore.html", "hello world, No Template") server.AddFile("org1/repo1/gh-pages/.pages.yaml", ` -templates: - gotemplate: tmpl/*.html +routes: +- path: tmpl/index.html + template: `) data, _, err := server.OpenFile("https://org1.example.com/repo1/") assert.NoError(t, err) @@ -25,4 +27,8 @@ templates: data, _, err = server.OpenFile("https://org1.example.com/repo1/tmpl/index.html") assert.NoError(t, err) assert.Equal(t, "hello world,org1.example.com", string(data)) + + data, _, err = server.OpenFile("https://org1.example.com/repo1/tmpl/ignore.html") + assert.NoError(t, err) + assert.Equal(t, "hello world, No Template", string(data)) }