github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/middleware/frontend.go (about)

     1  package middleware
     2  
     3  import (
     4  	"github.com/cloudreve/Cloudreve/v3/bootstrap"
     5  	model "github.com/cloudreve/Cloudreve/v3/models"
     6  	"github.com/cloudreve/Cloudreve/v3/pkg/util"
     7  	"github.com/gin-gonic/gin"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"strings"
    11  )
    12  
    13  // FrontendFileHandler 前端静态文件处理
    14  func FrontendFileHandler() gin.HandlerFunc {
    15  	ignoreFunc := func(c *gin.Context) {
    16  		c.Next()
    17  	}
    18  
    19  	if bootstrap.StaticFS == nil {
    20  		return ignoreFunc
    21  	}
    22  
    23  	// 读取index.html
    24  	file, err := bootstrap.StaticFS.Open("/index.html")
    25  	if err != nil {
    26  		util.Log().Warning("Static file \"index.html\" does not exist, it might affect the display of the homepage.")
    27  		return ignoreFunc
    28  	}
    29  
    30  	fileContentBytes, err := ioutil.ReadAll(file)
    31  	if err != nil {
    32  		util.Log().Warning("Cannot read static file \"index.html\", it might affect the display of the homepage.")
    33  		return ignoreFunc
    34  	}
    35  	fileContent := string(fileContentBytes)
    36  
    37  	fileServer := http.FileServer(bootstrap.StaticFS)
    38  	return func(c *gin.Context) {
    39  		path := c.Request.URL.Path
    40  
    41  		// API 跳过
    42  		if strings.HasPrefix(path, "/api") ||
    43  			strings.HasPrefix(path, "/custom") ||
    44  			strings.HasPrefix(path, "/dav") ||
    45  			strings.HasPrefix(path, "/f") ||
    46  			path == "/manifest.json" {
    47  			c.Next()
    48  			return
    49  		}
    50  
    51  		// 不存在的路径和index.html均返回index.html
    52  		if (path == "/index.html") || (path == "/") || !bootstrap.StaticFS.Exists("/", path) {
    53  			// 读取、替换站点设置
    54  			options := model.GetSettingByNames("siteName", "siteKeywords", "siteScript",
    55  				"pwa_small_icon")
    56  			finalHTML := util.Replace(map[string]string{
    57  				"{siteName}":       options["siteName"],
    58  				"{siteDes}":        options["siteDes"],
    59  				"{siteScript}":     options["siteScript"],
    60  				"{pwa_small_icon}": options["pwa_small_icon"],
    61  			}, fileContent)
    62  
    63  			c.Header("Content-Type", "text/html")
    64  			c.String(200, finalHTML)
    65  			c.Abort()
    66  			return
    67  		}
    68  
    69  		if path == "/service-worker.js" {
    70  			c.Header("Cache-Control", "public, no-cache")
    71  		}
    72  
    73  		// 存在的静态文件
    74  		fileServer.ServeHTTP(c.Writer, c.Request)
    75  		c.Abort()
    76  	}
    77  }