- Introduce a new `RewriteRule` type and associated functions for managing URL rewrite rules in `service/static.go`. - Add `GetRewriteRules` and `ResolveRoute` functions to facilitate the retrieval and application of rewrite rules. - Update the `sui/api/run.go` to utilize the new route resolver for handling dynamic routes when the config file is not found. - Define `RouteResolver` in `sui/core/interfaces.go` to allow for dynamic route resolution across the application.
114 lines
2.6 KiB
Go
114 lines
2.6 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/yaoapp/kun/log"
|
|
"github.com/yaoapp/yao/data"
|
|
"github.com/yaoapp/yao/service/fs"
|
|
"github.com/yaoapp/yao/share"
|
|
"github.com/yaoapp/yao/sui/core"
|
|
)
|
|
|
|
// AppFileServer static file server
|
|
var AppFileServer http.Handler
|
|
|
|
// CUIFileServerV1 CUI v1.0
|
|
var CUIFileServerV1 http.Handler = http.FileServer(data.CuiV1())
|
|
|
|
// AdminRoot cache
|
|
var AdminRoot = ""
|
|
|
|
// AdminRootLen cache
|
|
var AdminRootLen = 0
|
|
|
|
var rewriteRules = []RewriteRule{}
|
|
|
|
// RewriteRule is a URL rewrite rule defined in app.yao
|
|
type RewriteRule struct {
|
|
Pattern *regexp.Regexp
|
|
Replacement string
|
|
}
|
|
|
|
// GetRewriteRules returns the loaded rewrite rules for use by other packages (e.g., sui/api)
|
|
func GetRewriteRules() []RewriteRule {
|
|
return rewriteRules
|
|
}
|
|
|
|
// ResolveRoute applies rewrite rules to the given route path.
|
|
// Returns the rewritten path (with .sui suffix removed) and matched parameter values, or empty string if no rule matches.
|
|
func ResolveRoute(route string) (string, []string) {
|
|
for _, rule := range rewriteRules {
|
|
if matches := rule.Pattern.FindStringSubmatch(route); matches != nil {
|
|
rewritten := rule.Pattern.ReplaceAllString(route, rule.Replacement)
|
|
rewritten = strings.TrimSuffix(rewritten, ".sui")
|
|
return rewritten, matches
|
|
}
|
|
}
|
|
return "", nil
|
|
}
|
|
|
|
// SetupStatic setup static file server
|
|
func SetupStatic() error {
|
|
setupAdminRoot()
|
|
setupRewrite()
|
|
|
|
// Disable gzip compression for static files
|
|
if share.App.Static.DisableGzip {
|
|
AppFileServer = http.FileServer(fs.Dir("public"))
|
|
return nil
|
|
}
|
|
|
|
AppFileServer = gzipHandler(http.FileServer(fs.Dir("public")))
|
|
return nil
|
|
}
|
|
|
|
func setupRewrite() {
|
|
if share.App.Static.Rewrite != nil {
|
|
for _, rule := range share.App.Static.Rewrite {
|
|
|
|
pattern := ""
|
|
replacement := ""
|
|
for key, value := range rule {
|
|
pattern = key
|
|
replacement = value
|
|
break
|
|
}
|
|
|
|
re, err := regexp.Compile(pattern)
|
|
if err != nil {
|
|
log.Error("Invalid rewrite rule: %s", pattern)
|
|
continue
|
|
}
|
|
|
|
rewriteRules = append(rewriteRules, RewriteRule{
|
|
Pattern: re,
|
|
Replacement: replacement,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Register the route resolver for $Backend().Call() dynamic route support
|
|
core.RouteResolver = ResolveRoute
|
|
}
|
|
|
|
// rewrite path
|
|
func setupAdminRoot() (string, int) {
|
|
if AdminRoot != "" {
|
|
return AdminRoot, AdminRootLen
|
|
}
|
|
|
|
adminRoot := "/yao/"
|
|
if share.App.AdminRoot != "" {
|
|
root := strings.TrimPrefix(share.App.AdminRoot, "/")
|
|
root = strings.TrimSuffix(root, "/")
|
|
adminRoot = fmt.Sprintf("/%s/", root)
|
|
}
|
|
adminRootLen := len(adminRoot)
|
|
AdminRoot = adminRoot
|
|
AdminRootLen = adminRootLen
|
|
return AdminRoot, AdminRootLen
|
|
}
|