mirror of https://github.com/Xhofe/alist
				
				
				
			feat: static file router
							parent
							
								
									e5480b99be
								
							
						
					
					
						commit
						d267c43556
					
				| 
						 | 
				
			
			@ -21,12 +21,8 @@ dist/
 | 
			
		|||
# Dependency directories (remove the comment below to include it)
 | 
			
		||||
# vendor/
 | 
			
		||||
bin/*
 | 
			
		||||
/alist
 | 
			
		||||
/alist.exe
 | 
			
		||||
*.json
 | 
			
		||||
public/*.html
 | 
			
		||||
public/assets/
 | 
			
		||||
public/public/
 | 
			
		||||
/data
 | 
			
		||||
data/
 | 
			
		||||
log/
 | 
			
		||||
lang/
 | 
			
		||||
lang/
 | 
			
		||||
public/dist/
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ type Config struct {
 | 
			
		|||
	Port      int    `json:"port" env:"PORT"`
 | 
			
		||||
	JwtSecret string `json:"jwt_secret" env:"JWT_SECRET"`
 | 
			
		||||
	// CaCheExpiration int       `json:"cache_expiration" env:"CACHE_EXPIRATION"`
 | 
			
		||||
	Assets   string    `json:"assets" env:"ASSETS"`
 | 
			
		||||
	Cdn      string    `json:"cdn" env:"CDN"`
 | 
			
		||||
	Database Database  `json:"database"`
 | 
			
		||||
	Scheme   Scheme    `json:"scheme"`
 | 
			
		||||
	TempDir  string    `json:"temp_dir" env:"TEMP_DIR"`
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ func DefaultConfig() *Config {
 | 
			
		|||
		Address:   "0.0.0.0",
 | 
			
		||||
		Port:      5244,
 | 
			
		||||
		JwtSecret: random.String(16),
 | 
			
		||||
		Assets:    "https://npm.elemecdn.com/alist-web@$version/dist",
 | 
			
		||||
		Cdn:       "",
 | 
			
		||||
		TempDir:   "data/temp",
 | 
			
		||||
		Database: Database{
 | 
			
		||||
			Type:        "sqlite3",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,3 +22,8 @@ var (
 | 
			
		|||
	// StoragesLoaded loaded success if empty
 | 
			
		||||
	StoragesLoaded = false
 | 
			
		||||
)
 | 
			
		||||
var (
 | 
			
		||||
	RawIndexHtml string
 | 
			
		||||
	ManageHtml   string
 | 
			
		||||
	IndexHtml    string
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
package public
 | 
			
		||||
 | 
			
		||||
import "embed"
 | 
			
		||||
 | 
			
		||||
//go:embed dist
 | 
			
		||||
var Public embed.FS
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ import (
 | 
			
		|||
	"github.com/alist-org/alist/v3/internal/sign"
 | 
			
		||||
	"github.com/alist-org/alist/v3/pkg/utils/random"
 | 
			
		||||
	"github.com/alist-org/alist/v3/server/common"
 | 
			
		||||
	"github.com/alist-org/alist/v3/server/static"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +55,7 @@ func SaveSettings(c *gin.Context) {
 | 
			
		|||
		common.ErrorResp(c, err, 500)
 | 
			
		||||
	} else {
 | 
			
		||||
		common.SuccessResp(c)
 | 
			
		||||
		static.UpdateIndex()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import (
 | 
			
		|||
	"github.com/alist-org/alist/v3/server/common"
 | 
			
		||||
	"github.com/alist-org/alist/v3/server/handles"
 | 
			
		||||
	"github.com/alist-org/alist/v3/server/middlewares"
 | 
			
		||||
	"github.com/alist-org/alist/v3/server/static"
 | 
			
		||||
	"github.com/gin-contrib/cors"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -35,11 +36,12 @@ func Init(r *gin.Engine) {
 | 
			
		|||
	public := api.Group("/public")
 | 
			
		||||
	public.Any("/settings", handles.PublicSettings)
 | 
			
		||||
 | 
			
		||||
	fs(auth.Group("/fs"))
 | 
			
		||||
	_fs(auth.Group("/fs"))
 | 
			
		||||
	admin(auth.Group("/admin", middlewares.AuthAdmin))
 | 
			
		||||
	if flags.Dev {
 | 
			
		||||
		dev(r.Group("/dev"))
 | 
			
		||||
	}
 | 
			
		||||
	static.Static(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func admin(g *gin.RouterGroup) {
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +109,7 @@ func admin(g *gin.RouterGroup) {
 | 
			
		|||
	ms.POST("/send", message.HttpInstance.SendHandle)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fs(g *gin.RouterGroup) {
 | 
			
		||||
func _fs(g *gin.RouterGroup) {
 | 
			
		||||
	g.Any("/list", handles.FsList)
 | 
			
		||||
	g.Any("/get", handles.FsGet)
 | 
			
		||||
	g.Any("/dirs", handles.FsDirs)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
package static
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/pprof"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/alist-org/alist/v3/cmd/flags"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/conf"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/setting"
 | 
			
		||||
	"github.com/alist-org/alist/v3/public"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func InitIndex() {
 | 
			
		||||
	index, err := public.Public.ReadFile("dist/index.html")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("failed to read index.html: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	conf.RawIndexHtml = string(index)
 | 
			
		||||
	UpdateIndex()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UpdateIndex() {
 | 
			
		||||
	cdn := conf.Conf.Cdn
 | 
			
		||||
	basePath := setting.GetByKey(conf.BasePath)
 | 
			
		||||
	apiUrl := setting.GetByKey(conf.ApiUrl)
 | 
			
		||||
	favicon := setting.GetByKey(conf.Favicon)
 | 
			
		||||
	title := setting.GetByKey(conf.SiteTitle)
 | 
			
		||||
	customizeHead := setting.GetByKey(conf.CustomizeHead)
 | 
			
		||||
	customizeBody := setting.GetByKey(conf.CustomizeBody)
 | 
			
		||||
	conf.ManageHtml = conf.RawIndexHtml
 | 
			
		||||
	replaceMap1 := map[string]string{
 | 
			
		||||
		"https://jsd.nn.ci/gh/alist-org/logo@main/logo.svg": favicon,
 | 
			
		||||
		"Loading...":           title,
 | 
			
		||||
		"cdn: undefined":       fmt.Sprintf("cdn: '%s'", cdn),
 | 
			
		||||
		"base_path: undefined": fmt.Sprintf("base_path: '%s'", basePath),
 | 
			
		||||
		"api: undefined":       fmt.Sprintf("api: '%s'", apiUrl),
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range replaceMap1 {
 | 
			
		||||
		conf.ManageHtml = strings.Replace(conf.ManageHtml, k, v, 1)
 | 
			
		||||
	}
 | 
			
		||||
	conf.IndexHtml = conf.ManageHtml
 | 
			
		||||
	replaceMap2 := map[string]string{
 | 
			
		||||
		"<!-- customize head -->": customizeHead,
 | 
			
		||||
		"<!-- customize body -->": customizeBody,
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range replaceMap2 {
 | 
			
		||||
		conf.IndexHtml = strings.Replace(conf.IndexHtml, k, v, 1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Static(r *gin.Engine) {
 | 
			
		||||
	InitIndex()
 | 
			
		||||
	folders := []string{"assets", "images", "streamer"}
 | 
			
		||||
	for i, folder := range folders {
 | 
			
		||||
		folder = "dist/" + folder
 | 
			
		||||
		sub, err := fs.Sub(public.Public, folder)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalf("can't find folder: %s", folder)
 | 
			
		||||
		}
 | 
			
		||||
		r.StaticFS(fmt.Sprintf("/%s/", folders[i]), http.FS(sub))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.NoRoute(func(c *gin.Context) {
 | 
			
		||||
		c.Header("Content-Type", "text/html")
 | 
			
		||||
		c.Status(200)
 | 
			
		||||
		if strings.HasPrefix(c.Request.URL.Path, "/@manage") {
 | 
			
		||||
			_, _ = c.Writer.WriteString(conf.ManageHtml)
 | 
			
		||||
		} else if strings.HasPrefix(c.Request.URL.Path, "/debug/pprof") && flags.Debug {
 | 
			
		||||
			pprof.Index(c.Writer, c.Request)
 | 
			
		||||
		} else {
 | 
			
		||||
			_, _ = c.Writer.WriteString(conf.IndexHtml)
 | 
			
		||||
		}
 | 
			
		||||
		c.Writer.Flush()
 | 
			
		||||
		c.Writer.WriteHeaderNow()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue