From e829c2baff44e927919a42161b4570aab3a22c53 Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Thu, 5 Jun 2025 00:24:21 +0800 Subject: [PATCH 1/2] 25w43a --- CHANGELOG.md | 7 +++ DEV-VERSION | 2 +- go.mod | 5 +- go.sum | 10 ++-- main.go | 149 +++++++++++++++++++++++++++++---------------------- 5 files changed, 101 insertions(+), 72 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2820fb..49187fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # 更新日志 +25w43a - 2025-06-05 +--- +- PRE-RELEASE: 此版本是v3.4.3预发布版本,请勿在生产环境中使用; +- CHANGE: 弃用`adaptor.GetCompatRequest`, 切换到`adaptor.HertzHandler` +- CHANGE: 为`embedFS`使用包装器, 使其支持`Last-Modified` +- CHANGE: 为静态资源增加`Cache-Control: public, max-age=3600, must-revalidate` + 3.4.2 - 2025-06-03 --- - DEP: 回滚 github.com/nyaruka/phonenumbers 版本到 v1.6.1, v1.6.3观测到了一些反射造成的内存占用异常 diff --git a/DEV-VERSION b/DEV-VERSION index 0b20fcc..e303d5b 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -25w42a \ No newline at end of file +25w43a \ No newline at end of file diff --git a/go.mod b/go.mod index 437f381..90b925e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.3 require ( github.com/BurntSushi/toml v1.5.0 github.com/WJQSERVER-STUDIO/httpc v0.5.1 - github.com/WJQSERVER-STUDIO/logger v1.7.2 + github.com/WJQSERVER-STUDIO/logger v1.7.3 github.com/cloudwego/hertz v0.10.0 github.com/hertz-contrib/http2 v0.1.8 golang.org/x/net v0.40.0 @@ -14,8 +14,9 @@ require ( require ( github.com/WJQSERVER-STUDIO/go-utils/limitreader v0.0.2 - github.com/bytedance/sonic v1.13.2 + github.com/bytedance/sonic v1.13.3 github.com/hashicorp/golang-lru/v2 v2.0.7 + github.com/wjqserver/modembed v0.0.1 ) require ( diff --git a/go.sum b/go.sum index 5e3a90e..834e6c7 100644 --- a/go.sum +++ b/go.sum @@ -8,15 +8,15 @@ github.com/WJQSERVER-STUDIO/go-utils/log v0.0.3 h1:t6nyLhmo9pSfVHm1Wu1WyLsTpXFSj github.com/WJQSERVER-STUDIO/go-utils/log v0.0.3/go.mod h1:j9Q+xnwpOfve7/uJnZ2izRQw6NNoXjvJHz7vUQAaLZE= github.com/WJQSERVER-STUDIO/httpc v0.5.1 h1:+TKCPYBuj7PAHuiduGCGAqsHAa4QtsUfoVwRN777q64= github.com/WJQSERVER-STUDIO/httpc v0.5.1/go.mod h1:M7KNUZjjhCkzzcg9lBPs9YfkImI+7vqjAyjdA19+joE= -github.com/WJQSERVER-STUDIO/logger v1.7.2 h1:Tu9WICwlrY+BMQmY7k4llDB1ziFtZ9VmK7/85VIPN+M= -github.com/WJQSERVER-STUDIO/logger v1.7.2/go.mod h1:yzXPtot0OvR1gzx4+rlFrv/sccUpz0gIXVBwUx3H7fM= +github.com/WJQSERVER-STUDIO/logger v1.7.3 h1:XoFJ1nBcZKyMvP4v0MZv5jL2q7IkAF7yfXgwyB3MLP4= +github.com/WJQSERVER-STUDIO/logger v1.7.3/go.mod h1:yzXPtot0OvR1gzx4+rlFrv/sccUpz0gIXVBwUx3H7fM= github.com/bytedance/gopkg v0.1.1/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= github.com/bytedance/gopkg v0.1.2 h1:8o2feYuxknDpN+O7kPwvSXfMEKfYvJYiA2K7aonoMEQ= github.com/bytedance/gopkg v0.1.2/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= github.com/bytedance/mockey v1.2.12 h1:aeszOmGw8CPX8CRx1DZ/Glzb1yXvhjDh6jdFBNZjsU4= github.com/bytedance/mockey v1.2.12/go.mod h1:3ZA4MQasmqC87Tw0w7Ygdy7eHIc2xgpZ8Pona5rsYIk= -github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= -github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= +github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= @@ -84,6 +84,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/wjqserver/modembed v0.0.1 h1:8ZDz7t9M5DLrUFlYgBUUmrMzxWsZPmHvOazkr/T2jEs= +github.com/wjqserver/modembed v0.0.1/go.mod h1:sYbQJMAjSBsdYQrUsuHY380XXE1CuRh8g9yyCztTXOQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU= golang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= diff --git a/main.go b/main.go index 2cbc5db..a441752 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "github.com/WJQSERVER-STUDIO/logger" "github.com/hertz-contrib/http2/factory" + "github.com/wjqserver/modembed" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/middlewares/server/recovery" @@ -198,25 +199,26 @@ func InitReq(cfg *config.Config) { // loadEmbeddedPages 加载嵌入式页面资源 func loadEmbeddedPages(cfg *config.Config) (fs.FS, fs.FS, error) { + pageFS := modembed.NewModTimeFS(pagesFS, time.Now()) var pages fs.FS var err error switch cfg.Pages.Theme { case "bootstrap": - pages, err = fs.Sub(pagesFS, "pages/bootstrap") + pages, err = fs.Sub(pageFS, "pages/bootstrap") case "nebula": - pages, err = fs.Sub(pagesFS, "pages/nebula") + pages, err = fs.Sub(pageFS, "pages/nebula") case "design": - pages, err = fs.Sub(pagesFS, "pages/design") + pages, err = fs.Sub(pageFS, "pages/design") case "metro": - pages, err = fs.Sub(pagesFS, "pages/metro") + pages, err = fs.Sub(pageFS, "pages/metro") case "classic": - pages, err = fs.Sub(pagesFS, "pages/classic") + pages, err = fs.Sub(pageFS, "pages/classic") case "mino": - pages, err = fs.Sub(pagesFS, "pages/mino") + pages, err = fs.Sub(pageFS, "pages/mino") case "hub": - pages, err = fs.Sub(pagesFS, "pages/hub") + pages, err = fs.Sub(pageFS, "pages/hub") default: - pages, err = fs.Sub(pagesFS, "pages/design") // 默认主题 + pages, err = fs.Sub(pageFS, "pages/design") // 默认主题 logWarning("Invalid Pages Theme: %s, using default theme 'design'", cfg.Pages.Theme) } @@ -225,13 +227,16 @@ func loadEmbeddedPages(cfg *config.Config) (fs.FS, fs.FS, error) { } // 初始化errPagesFs - errPagesInitErr := proxy.InitErrPagesFS(pagesFS) + errPagesInitErr := proxy.InitErrPagesFS(pageFS) if errPagesInitErr != nil { logWarning("errPagesInitErr: %s", errPagesInitErr) } var assets fs.FS - assets, err = fs.Sub(pagesFS, "pages/assets") + assets, err = fs.Sub(pageFS, "pages/assets") + if err != nil { + return nil, nil, fmt.Errorf("failed to load embedded assets: %w", err) + } return pages, assets, nil } @@ -277,6 +282,12 @@ func setupPages(cfg *config.Config, r *server.Hertz) { } } +func pageCacheHeader() func(ctx context.Context, c *app.RequestContext) { + return func(ctx context.Context, c *app.RequestContext) { + c.Header("Cache-Control", "public, max-age=3600, must-revalidate") + } +} + func setInternalRoute(cfg *config.Config, r *server.Hertz) error { // 加载嵌入式资源 @@ -285,61 +296,69 @@ func setInternalRoute(cfg *config.Config, r *server.Hertz) error { logError("Failed when processing pages: %s", err) return err } - // 设置嵌入式资源路由 - r.GET("/", func(ctx context.Context, c *app.RequestContext) { - staticServer := http.FileServer(http.FS(pages)) - req, err := adaptor.GetCompatRequest(&c.Request) - if err != nil { - logError("%s", err) - return - } - staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) - }) - r.GET("/favicon.ico", func(ctx context.Context, c *app.RequestContext) { - staticServer := http.FileServer(http.FS(assets)) - req, err := adaptor.GetCompatRequest(&c.Request) - if err != nil { - logError("%s", err) - return - } - staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) - }) - r.GET("/script.js", func(ctx context.Context, c *app.RequestContext) { - staticServer := http.FileServer(http.FS(pages)) - req, err := adaptor.GetCompatRequest(&c.Request) - if err != nil { - logError("%s", err) - return - } - staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) - }) - r.GET("/style.css", func(ctx context.Context, c *app.RequestContext) { - staticServer := http.FileServer(http.FS(pages)) - req, err := adaptor.GetCompatRequest(&c.Request) - if err != nil { - logError("%s", err) - return - } - staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) - }) - r.GET("/bootstrap.min.css", func(ctx context.Context, c *app.RequestContext) { - staticServer := http.FileServer(http.FS(assets)) - req, err := adaptor.GetCompatRequest(&c.Request) - if err != nil { - logError("%s", err) - return - } - staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) - }) - r.GET("/bootstrap.bundle.min.js", func(ctx context.Context, c *app.RequestContext) { - staticServer := http.FileServer(http.FS(assets)) - req, err := adaptor.GetCompatRequest(&c.Request) - if err != nil { - logError("%s", err) - return - } - staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) - }) + /* + // 设置嵌入式资源路由 + r.GET("/", func(ctx context.Context, c *app.RequestContext) { + staticServer := http.FileServer(http.FS(pages)) + req, err := adaptor.GetCompatRequest(&c.Request) + if err != nil { + logError("%s", err) + return + } + staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) + }) + r.GET("/favicon.ico", func(ctx context.Context, c *app.RequestContext) { + staticServer := http.FileServer(http.FS(assets)) + req, err := adaptor.GetCompatRequest(&c.Request) + if err != nil { + logError("%s", err) + return + } + staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) + }) + r.GET("/script.js", func(ctx context.Context, c *app.RequestContext) { + staticServer := http.FileServer(http.FS(pages)) + req, err := adaptor.GetCompatRequest(&c.Request) + if err != nil { + logError("%s", err) + return + } + staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) + }) + r.GET("/style.css", func(ctx context.Context, c *app.RequestContext) { + staticServer := http.FileServer(http.FS(pages)) + req, err := adaptor.GetCompatRequest(&c.Request) + if err != nil { + logError("%s", err) + return + } + staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) + }) + r.GET("/bootstrap.min.css", func(ctx context.Context, c *app.RequestContext) { + staticServer := http.FileServer(http.FS(assets)) + req, err := adaptor.GetCompatRequest(&c.Request) + if err != nil { + logError("%s", err) + return + } + staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) + }) + r.GET("/bootstrap.bundle.min.js", func(ctx context.Context, c *app.RequestContext) { + staticServer := http.FileServer(http.FS(assets)) + req, err := adaptor.GetCompatRequest(&c.Request) + if err != nil { + logError("%s", err) + return + } + staticServer.ServeHTTP(adaptor.GetCompatResponseWriter(&c.Response), req) + }) + */ + r.GET("/", pageCacheHeader(), adaptor.HertzHandler(http.FileServer(http.FS(pages)))) + r.GET("/favicon.ico", pageCacheHeader(), adaptor.HertzHandler(http.FileServer(http.FS(assets)))) + r.GET("/script.js", pageCacheHeader(), adaptor.HertzHandler(http.FileServer(http.FS(pages)))) + r.GET("/style.css", pageCacheHeader(), adaptor.HertzHandler(http.FileServer(http.FS(pages)))) + r.GET("/bootstrap.min.css", pageCacheHeader(), adaptor.HertzHandler(http.FileServer(http.FS(assets)))) + r.GET("/bootstrap.bundle.min.js", pageCacheHeader(), adaptor.HertzHandler(http.FileServer(http.FS(assets)))) return nil } From 1370617f5ba91dbba72e738abba8a826db8178a1 Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:29:18 +0800 Subject: [PATCH 2/2] 3.4.3 --- CHANGELOG.md | 6 ++++++ VERSION | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49187fe..92b291b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # 更新日志 +3.4.3 - 2025-06-05 +--- +- CHANGE: 弃用`adaptor.GetCompatRequest`, 切换到`adaptor.HertzHandler` +- CHANGE: 为`embedFS`使用包装器, 使其支持`Last-Modified` +- CHANGE: 为静态资源增加`Cache-Control: public, max-age=3600, must-revalidate` + 25w43a - 2025-06-05 --- - PRE-RELEASE: 此版本是v3.4.3预发布版本,请勿在生产环境中使用; diff --git a/VERSION b/VERSION index a423d42..8a0feb9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.4.2 \ No newline at end of file +3.4.3 \ No newline at end of file