Skip to content

Commit 7d0de17

Browse files
authored
feat(static): fetch index.html from cdn for beta (#372)
* refactor(static): simplify folder iteration in Static function * feat(static): disable local static when `cdn` is set * feat(static): fetch index.html from cdn for beta * refactor(static): use RestyClient for better retrying * fix(static): add Accept header when fetching index.html from CDN * refactor(static): optimize HTML replacement * chore(static): add logging to static file system initialization * feat(static): ensure static file redirected to CDN
1 parent bba4fb2 commit 7d0de17

File tree

1 file changed

+76
-36
lines changed

1 file changed

+76
-36
lines changed

server/static/static.go

Lines changed: 76 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"strings"
1111

12+
"github.com/OpenListTeam/OpenList/v4/drivers/base"
1213
"github.com/OpenListTeam/OpenList/v4/internal/conf"
1314
"github.com/OpenListTeam/OpenList/v4/internal/setting"
1415
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
@@ -19,88 +20,127 @@ import (
1920
var static fs.FS
2021

2122
func initStatic() {
23+
utils.Log.Debug("Initializing static file system...")
2224
if conf.Conf.DistDir == "" {
2325
dist, err := fs.Sub(public.Public, "dist")
2426
if err != nil {
25-
utils.Log.Fatalf("failed to read dist dir")
27+
utils.Log.Fatalf("failed to read dist dir: %v", err)
2628
}
2729
static = dist
30+
utils.Log.Debug("Using embedded dist directory")
2831
return
2932
}
3033
static = os.DirFS(conf.Conf.DistDir)
34+
utils.Log.Infof("Using custom dist directory: %s", conf.Conf.DistDir)
35+
}
36+
37+
func replaceStrings(content string, replacements map[string]string) string {
38+
for old, new := range replacements {
39+
content = strings.Replace(content, old, new, 1)
40+
}
41+
return content
3142
}
3243

3344
func initIndex() {
34-
indexFile, err := static.Open("index.html")
35-
if err != nil {
36-
if errors.Is(err, fs.ErrNotExist) {
37-
utils.Log.Fatalf("index.html not exist, you may forget to put dist of frontend to public/dist")
45+
utils.Log.Debug("Initializing index.html...")
46+
siteConfig := getSiteConfig()
47+
if conf.Conf.DistDir != "" || (conf.Conf.Cdn != "" && (conf.WebVersion == "" || conf.WebVersion == "beta" || conf.WebVersion == "dev")) {
48+
utils.Log.Infof("Fetching index.html from CDN: %s/index.html...", conf.Conf.Cdn)
49+
resp, err := base.RestyClient.R().
50+
SetHeader("Accept", "text/html").
51+
Get(fmt.Sprintf("%s/index.html", siteConfig.Cdn))
52+
if err != nil {
53+
utils.Log.Fatalf("failed to fetch index.html from CDN: %v", err)
3854
}
39-
utils.Log.Fatalf("failed to read index.html: %v", err)
40-
}
41-
defer func() {
42-
_ = indexFile.Close()
43-
}()
44-
index, err := io.ReadAll(indexFile)
45-
if err != nil {
46-
utils.Log.Fatalf("failed to read dist/index.html")
55+
if resp.StatusCode() != http.StatusOK {
56+
utils.Log.Fatalf("failed to fetch index.html from CDN, status code: %d", resp.StatusCode())
57+
}
58+
conf.RawIndexHtml = string(resp.Body())
59+
utils.Log.Info("Successfully fetched index.html from CDN")
60+
} else {
61+
utils.Log.Debug("Reading index.html from static files system...")
62+
indexFile, err := static.Open("index.html")
63+
if err != nil {
64+
if errors.Is(err, fs.ErrNotExist) {
65+
utils.Log.Fatalf("index.html not exist, you may forget to put dist of frontend to public/dist")
66+
}
67+
utils.Log.Fatalf("failed to read index.html: %v", err)
68+
}
69+
defer func() {
70+
_ = indexFile.Close()
71+
}()
72+
index, err := io.ReadAll(indexFile)
73+
if err != nil {
74+
utils.Log.Fatalf("failed to read dist/index.html")
75+
}
76+
conf.RawIndexHtml = string(index)
77+
utils.Log.Debug("Successfully read index.html from static files system")
4778
}
48-
conf.RawIndexHtml = string(index)
49-
siteConfig := getSiteConfig()
79+
utils.Log.Debug("Replacing placeholders in index.html...")
5080
replaceMap := map[string]string{
5181
"cdn: undefined": fmt.Sprintf("cdn: '%s'", siteConfig.Cdn),
5282
"base_path: undefined": fmt.Sprintf("base_path: '%s'", siteConfig.BasePath),
5383
}
54-
for k, v := range replaceMap {
55-
conf.RawIndexHtml = strings.Replace(conf.RawIndexHtml, k, v, 1)
56-
}
84+
conf.RawIndexHtml = replaceStrings(conf.RawIndexHtml, replaceMap)
5785
UpdateIndex()
5886
}
5987

6088
func UpdateIndex() {
89+
utils.Log.Debug("Updating index.html with settings...")
6190
favicon := setting.GetStr(conf.Favicon)
6291
title := setting.GetStr(conf.SiteTitle)
6392
customizeHead := setting.GetStr(conf.CustomizeHead)
6493
customizeBody := setting.GetStr(conf.CustomizeBody)
6594
mainColor := setting.GetStr(conf.MainColor)
66-
conf.ManageHtml = conf.RawIndexHtml
95+
utils.Log.Debug("Applying replacements for default pages...")
6796
replaceMap1 := map[string]string{
6897
"https://cdn.oplist.org/gh/OpenListTeam/Logo@main/logo.svg": favicon,
6998
"Loading...": title,
7099
"main_color: undefined": fmt.Sprintf("main_color: '%s'", mainColor),
71100
}
72-
for k, v := range replaceMap1 {
73-
conf.ManageHtml = strings.Replace(conf.ManageHtml, k, v, 1)
74-
}
75-
conf.IndexHtml = conf.ManageHtml
101+
conf.ManageHtml = replaceStrings(conf.RawIndexHtml, replaceMap1)
102+
utils.Log.Debug("Applying replacements for manage pages...")
76103
replaceMap2 := map[string]string{
77104
"<!-- customize head -->": customizeHead,
78105
"<!-- customize body -->": customizeBody,
79106
}
80-
for k, v := range replaceMap2 {
81-
conf.IndexHtml = strings.Replace(conf.IndexHtml, k, v, 1)
82-
}
107+
conf.IndexHtml = replaceStrings(conf.ManageHtml, replaceMap2)
108+
utils.Log.Debug("Index.html update completed")
83109
}
84110

85111
func Static(r *gin.RouterGroup, noRoute func(handlers ...gin.HandlerFunc)) {
112+
utils.Log.Debug("Setting up static routes...")
86113
initStatic()
87114
initIndex()
88115
folders := []string{"assets", "images", "streamer", "static"}
89-
r.Use(func(c *gin.Context) {
90-
for i := range folders {
91-
if strings.HasPrefix(c.Request.RequestURI, fmt.Sprintf("/%s/", folders[i])) {
92-
c.Header("Cache-Control", "public, max-age=15552000")
116+
if conf.Conf.Cdn == "" {
117+
utils.Log.Debug("Setting up static file serving...")
118+
r.Use(func(c *gin.Context) {
119+
for _, folder := range folders {
120+
if strings.HasPrefix(c.Request.RequestURI, fmt.Sprintf("/%s/", folder)) {
121+
c.Header("Cache-Control", "public, max-age=15552000")
122+
}
123+
}
124+
})
125+
for _, folder := range folders {
126+
sub, err := fs.Sub(static, folder)
127+
if err != nil {
128+
utils.Log.Fatalf("can't find folder: %s", folder)
93129
}
130+
utils.Log.Debugf("Setting up route for folder: %s", folder)
131+
r.StaticFS(fmt.Sprintf("/%s/", folder), http.FS(sub))
94132
}
95-
})
96-
for i, folder := range folders {
97-
sub, err := fs.Sub(static, folder)
98-
if err != nil {
99-
utils.Log.Fatalf("can't find folder: %s", folder)
133+
} else {
134+
// Ensure static file redirected to CDN
135+
for _, folder := range folders {
136+
r.GET(fmt.Sprintf("/%s/*filepath", folder), func(c *gin.Context) {
137+
filepath := c.Param("filepath")
138+
c.Redirect(http.StatusFound, fmt.Sprintf("%s/%s%s", conf.Conf.Cdn, folder, filepath))
139+
})
100140
}
101-
r.StaticFS(fmt.Sprintf("/%s/", folders[i]), http.FS(sub))
102141
}
103142

143+
utils.Log.Debug("Setting up catch-all route...")
104144
noRoute(func(c *gin.Context) {
105145
if c.Request.Method != "GET" && c.Request.Method != "POST" {
106146
c.Status(405)

0 commit comments

Comments
 (0)