Skip to content

Commit 77dfd64

Browse files
committed
Cache javascripts in browser
1 parent 7d6b979 commit 77dfd64

File tree

5 files changed

+117
-81
lines changed

5 files changed

+117
-81
lines changed

.air.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tmp_dir = "tmp"
77

88
[build]
99
# Just plain old shell command. You could use `make` as well.
10-
cmd = "go build -o ./tmp/main ."
10+
cmd = "go build -ldflags=\"-X 'github.com/0xJacky/Nginx-UI/server/settings.BuildTime=$(date +%Y.%m.%d.%H%M%S)'\" -o ./tmp/main ."
1111
# Binary file yields from `cmd`.
1212
bin = "tmp/main"
1313
# Customize binary.
@@ -50,4 +50,4 @@ runner = "green"
5050

5151
[misc]
5252
# Delete tmp directory on exit
53-
clean_on_exit = true
53+
clean_on_exit = true

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ jobs:
151151
- name: Build
152152
run: |
153153
mkdir -p dist
154-
go build -ldflags "$LD_FLAGS" -o dist/nginx-ui -v main.go
154+
go build -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/server/settings.BuildTime=$(date +%Y.%m.%d.%H%M%S)'" -o dist/nginx-ui -v main.go
155155
156156
- name: Archive backend artifacts
157157
uses: actions/upload-artifact@v2

server/router/middleware.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,29 @@ import (
44
"encoding/base64"
55
"github.com/0xJacky/Nginx-UI/frontend"
66
"github.com/0xJacky/Nginx-UI/server/model"
7+
"github.com/0xJacky/Nginx-UI/server/settings"
78
"github.com/gin-contrib/static"
89
"github.com/gin-gonic/gin"
910
"io/fs"
1011
"log"
1112
"net/http"
1213
"path"
14+
"strings"
15+
"time"
1316
)
1417

18+
func recovery() gin.HandlerFunc {
19+
return func(c *gin.Context) {
20+
defer func() {
21+
if err := recover(); err != nil {
22+
log.Println(err)
23+
}
24+
}()
25+
26+
c.Next()
27+
}
28+
}
29+
1530
func authRequired() gin.HandlerFunc {
1631
return func(c *gin.Context) {
1732
token := c.GetHeader("Authorization")
@@ -64,3 +79,18 @@ func mustFS(dir string) (serverFileSystem static.ServeFileSystem) {
6479

6580
return
6681
}
82+
83+
func cacheJs() gin.HandlerFunc {
84+
return func(c *gin.Context) {
85+
if strings.Contains(c.Request.URL.String(), "js") {
86+
c.Header("Cache-Control", "max-age: 1296000")
87+
t, _ := time.Parse("2006.01.02.150405", settings.BuildTime)
88+
t = t.Add(-8 * time.Hour)
89+
lastModified := strings.ReplaceAll(t.Format(time.RFC1123), "UTC", "GMT")
90+
if c.Request.Header.Get("If-Modified-Since") == lastModified {
91+
c.AbortWithStatus(http.StatusNotModified)
92+
}
93+
c.Header("Last-Modified", lastModified)
94+
}
95+
}
96+
}

server/router/routers.go

Lines changed: 80 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,87 @@
11
package router
22

33
import (
4-
"bufio"
5-
"github.com/0xJacky/Nginx-UI/server/api"
6-
"github.com/0xJacky/Nginx-UI/server/settings"
7-
"github.com/gin-contrib/static"
8-
"github.com/gin-gonic/gin"
9-
"net/http"
10-
"strings"
4+
"bufio"
5+
"github.com/0xJacky/Nginx-UI/server/api"
6+
"github.com/0xJacky/Nginx-UI/server/settings"
7+
"github.com/gin-contrib/static"
8+
"github.com/gin-gonic/gin"
9+
"net/http"
10+
"strings"
1111
)
1212

1313
func InitRouter() *gin.Engine {
14-
r := gin.New()
15-
r.Use(gin.Logger())
16-
17-
r.Use(gin.Recovery())
18-
19-
r.Use(static.Serve("/", mustFS("")))
20-
21-
r.NoRoute(func(c *gin.Context) {
22-
accept := c.Request.Header.Get("Accept")
23-
if strings.Contains(accept, "text/html") {
24-
file, _ := mustFS("").Open("index.html")
25-
stat, _ := file.Stat()
26-
c.DataFromReader(http.StatusOK, stat.Size(), "text/html",
27-
bufio.NewReader(file), nil)
28-
}
29-
})
30-
31-
g := r.Group("/api")
32-
{
33-
34-
g.GET("settings", func(c *gin.Context) {
35-
c.JSON(http.StatusOK, gin.H{
36-
"demo": settings.ServerSettings.Demo,
37-
})
38-
})
39-
40-
g.GET("install", api.InstallLockCheck)
41-
g.POST("install", api.InstallNginxUI)
42-
43-
g.POST("/login", api.Login)
44-
g.DELETE("/logout", api.Logout)
45-
46-
g := g.Group("/", authRequired())
47-
{
48-
g.GET("/analytic", api.Analytic)
49-
g.GET("/analytic/init", api.GetAnalyticInit)
50-
51-
g.GET("/users", api.GetUsers)
52-
g.GET("/user/:id", api.GetUser)
53-
g.POST("/user", api.AddUser)
54-
g.POST("/user/:id", api.EditUser)
55-
g.DELETE("/user/:id", api.DeleteUser)
56-
57-
g.GET("domains", api.GetDomains)
58-
g.GET("domain/:name", api.GetDomain)
59-
g.POST("domain/:name", api.EditDomain)
60-
g.POST("domain/:name/enable", api.EnableDomain)
61-
g.POST("domain/:name/disable", api.DisableDomain)
62-
g.DELETE("domain/:name", api.DeleteDomain)
63-
64-
g.GET("configs", api.GetConfigs)
65-
g.GET("config/:name", api.GetConfig)
66-
g.POST("config", api.AddConfig)
67-
g.POST("config/:name", api.EditConfig)
68-
69-
g.GET("backups", api.GetFileBackupList)
70-
g.GET("backup/:id", api.GetFileBackup)
71-
72-
g.GET("template/:name", api.GetTemplate)
73-
74-
g.GET("cert/issue/:domain", api.IssueCert)
75-
g.GET("cert/:domain/info", api.CertInfo)
76-
77-
// 添加域名到自动续期列表
78-
g.POST("cert/:domain", api.AddDomainToAutoCert)
79-
// 从自动续期列表中删除域名
80-
g.DELETE("cert/:domain", api.RemoveDomainFromAutoCert)
81-
}
82-
}
83-
84-
return r
14+
r := gin.New()
15+
r.Use(gin.Logger())
16+
17+
r.Use(recovery())
18+
19+
r.Use(cacheJs())
20+
21+
r.Use(static.Serve("/", mustFS("")))
22+
23+
r.NoRoute(func(c *gin.Context) {
24+
accept := c.Request.Header.Get("Accept")
25+
if strings.Contains(accept, "text/html") {
26+
file, _ := mustFS("").Open("index.html")
27+
stat, _ := file.Stat()
28+
c.DataFromReader(http.StatusOK, stat.Size(), "text/html",
29+
bufio.NewReader(file), nil)
30+
}
31+
})
32+
33+
g := r.Group("/api")
34+
{
35+
36+
g.GET("settings", func(c *gin.Context) {
37+
c.JSON(http.StatusOK, gin.H{
38+
"demo": settings.ServerSettings.Demo,
39+
})
40+
})
41+
42+
g.GET("install", api.InstallLockCheck)
43+
g.POST("install", api.InstallNginxUI)
44+
45+
g.POST("/login", api.Login)
46+
g.DELETE("/logout", api.Logout)
47+
48+
g := g.Group("/", authRequired())
49+
{
50+
g.GET("/analytic", api.Analytic)
51+
g.GET("/analytic/init", api.GetAnalyticInit)
52+
53+
g.GET("/users", api.GetUsers)
54+
g.GET("/user/:id", api.GetUser)
55+
g.POST("/user", api.AddUser)
56+
g.POST("/user/:id", api.EditUser)
57+
g.DELETE("/user/:id", api.DeleteUser)
58+
59+
g.GET("domains", api.GetDomains)
60+
g.GET("domain/:name", api.GetDomain)
61+
g.POST("domain/:name", api.EditDomain)
62+
g.POST("domain/:name/enable", api.EnableDomain)
63+
g.POST("domain/:name/disable", api.DisableDomain)
64+
g.DELETE("domain/:name", api.DeleteDomain)
65+
66+
g.GET("configs", api.GetConfigs)
67+
g.GET("config/:name", api.GetConfig)
68+
g.POST("config", api.AddConfig)
69+
g.POST("config/:name", api.EditConfig)
70+
71+
g.GET("backups", api.GetFileBackupList)
72+
g.GET("backup/:id", api.GetFileBackup)
73+
74+
g.GET("template/:name", api.GetTemplate)
75+
76+
g.GET("cert/issue/:domain", api.IssueCert)
77+
g.GET("cert/:domain/info", api.CertInfo)
78+
79+
// 添加域名到自动续期列表
80+
g.POST("cert/:domain", api.AddDomainToAutoCert)
81+
// 从自动续期列表中删除域名
82+
g.DELETE("cert/:domain", api.RemoveDomainFromAutoCert)
83+
}
84+
}
85+
86+
return r
8587
}

server/settings/settings.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import (
77

88
var Conf *ini.File
99

10+
var (
11+
BuildTime string
12+
)
13+
1014
type Server struct {
1115
HttpPort string
1216
RunMode string

0 commit comments

Comments
 (0)