|
@@ -1,7 +1,9 @@
|
|
|
package server
|
|
|
|
|
|
import (
|
|
|
- "github.com/SongZihuan/huan-proxy/src/config"
|
|
|
+ "github.com/SongZihuan/huan-proxy/src/config/rulescompile"
|
|
|
+ "github.com/SongZihuan/huan-proxy/src/config/rulescompile/actioncompile/rewritecompile"
|
|
|
+ "github.com/SongZihuan/huan-proxy/src/config/rulescompile/matchcompile"
|
|
|
"github.com/SongZihuan/huan-proxy/src/utils"
|
|
|
"github.com/gabriel-vasile/mimetype"
|
|
|
"net/http"
|
|
@@ -13,62 +15,61 @@ import (
|
|
|
const IndexMaxDeep = 5
|
|
|
const DefaultIgnoreFileMap = 20
|
|
|
|
|
|
-func (s *HTTPServer) dirServer(ruleIndex int, rule *config.ProxyConfig, w http.ResponseWriter, r *http.Request) {
|
|
|
+func (s *HTTPServer) dirServer(rule *rulescompile.RuleCompileConfig, w http.ResponseWriter, r *http.Request) {
|
|
|
+ if !s.cors(rule.File.Cors, w, r) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
if r.Method != http.MethodGet {
|
|
|
s.abortMethodNotAllowed(w)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- dirBasePath := rule.Dir
|
|
|
- fileBase := ""
|
|
|
- filePath := ""
|
|
|
+ dirBasePath := rule.Dir.Dir // 根部目录
|
|
|
+ fileAccess := "" // 访问目录
|
|
|
+ filePath := "" // 根部目录+访问目录=实际目录
|
|
|
|
|
|
url := utils.ProcessPath(r.URL.Path)
|
|
|
- if url == rule.BasePath {
|
|
|
- filePath = dirBasePath
|
|
|
- fileBase = ""
|
|
|
- } else if strings.HasPrefix(url, rule.BasePath+"/") {
|
|
|
- fileBase = url[len(rule.BasePath+"/"):]
|
|
|
- filePath = path.Join(dirBasePath, fileBase)
|
|
|
+ if rule.MatchType == matchcompile.RegexMatch {
|
|
|
+ fileAccess = s.rewrite("", rule.Dir.AddPrefixPath, rule.Dir.SubPrefixPath, rule.Dir.Rewrite)
|
|
|
+ filePath = path.Join(dirBasePath, fileAccess)
|
|
|
} else {
|
|
|
- s.abortNotFound(w)
|
|
|
- return
|
|
|
+ if url == rule.MatchPath {
|
|
|
+ fileAccess = s.rewrite("", rule.Dir.AddPrefixPath, rule.Dir.SubPrefixPath, rule.Dir.Rewrite)
|
|
|
+ filePath = path.Join(dirBasePath, fileAccess)
|
|
|
+ } else if strings.HasPrefix(url, rule.MatchPath+"/") {
|
|
|
+ fileAccess = s.rewrite(url[len(rule.MatchPath+"/"):], rule.Dir.AddPrefixPath, rule.Dir.SubPrefixPath, rule.Dir.Rewrite)
|
|
|
+ filePath = path.Join(dirBasePath, fileAccess)
|
|
|
+ } else {
|
|
|
+ s.abortNotFound(w)
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if filePath == "" {
|
|
|
- s.abortNotFound(w)
|
|
|
+ s.abortNotFound(w) // 正常清空不会走到这个流程
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- if !utils.IsFile(filePath) {
|
|
|
- filePath = s.getIndexFile(ruleIndex, filePath)
|
|
|
- fileBase = filePath[len(rule.BasePath+"/"):len(filePath)]
|
|
|
- } else if fileBase != "" {
|
|
|
- ignore, err := s.cfg.IgnoreFile.ForEach(ruleIndex, func(file *config.IgnoreFileCompile) (any, error) {
|
|
|
- if file.CheckName(fileBase) {
|
|
|
- return true, nil
|
|
|
+ if utils.IsFile(filePath) {
|
|
|
+ // 判断这个文件是否被ignore,因为ignore是从dirBasePath写起,也可以是完整路径,因此filePath和fileAccess都要判断
|
|
|
+ for _, ignore := range rule.Dir.IgnoreFile {
|
|
|
+ if ignore.CheckName(fileAccess) || ignore.CheckName(filePath) {
|
|
|
+ s.abortNotFound(w)
|
|
|
+ return
|
|
|
}
|
|
|
- return nil, nil
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ filePath = s.getIndexFile(rule, filePath)
|
|
|
+ if filePath == "" || !utils.IsFile(filePath) {
|
|
|
s.abortNotFound(w)
|
|
|
return
|
|
|
- } else if ig, ok := ignore.(bool); ok && ig {
|
|
|
- filePath = s.getIndexFile(ruleIndex, filePath)
|
|
|
- fileBase = filePath[len(rule.BasePath+"/"):len(filePath)]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 接下来的部分不在使用fileBase
|
|
|
-
|
|
|
- if filePath == "" || !utils.IsFile(filePath) {
|
|
|
- s.abortNotFound(w)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
file, err := os.ReadFile(filePath)
|
|
|
if err != nil {
|
|
|
- s.abortServerError(w)
|
|
|
+ s.abortNotFound(w)
|
|
|
return
|
|
|
}
|
|
|
|
|
@@ -88,11 +89,29 @@ func (s *HTTPServer) dirServer(ruleIndex int, rule *config.ProxyConfig, w http.R
|
|
|
s.statusOK(w)
|
|
|
}
|
|
|
|
|
|
-func (s *HTTPServer) getIndexFile(ruleIndex int, dir string) string {
|
|
|
- return s._getIndexFile(ruleIndex, dir, "", IndexMaxDeep)
|
|
|
+func (s *HTTPServer) rewrite(srcpath string, prefix string, suffix string, rewrite *rewritecompile.RewriteCompileConfig) string {
|
|
|
+ srcpath = utils.ProcessPath(srcpath)
|
|
|
+ prefix = utils.ProcessPath(prefix)
|
|
|
+ suffix = utils.ProcessPath(suffix)
|
|
|
+
|
|
|
+ if strings.HasPrefix(srcpath, suffix) {
|
|
|
+ srcpath = srcpath[len(suffix):]
|
|
|
+ }
|
|
|
+
|
|
|
+ srcpath = prefix + srcpath
|
|
|
+
|
|
|
+ if rewrite.Use && rewrite.Regex != nil {
|
|
|
+ rewrite.Regex.ReplaceAllString(srcpath, rewrite.Target)
|
|
|
+ }
|
|
|
+
|
|
|
+ return srcpath
|
|
|
}
|
|
|
|
|
|
-func (s *HTTPServer) _getIndexFile(ruleIndex int, baseDir string, nextDir string, deep int) string {
|
|
|
+func (s *HTTPServer) getIndexFile(rule *rulescompile.RuleCompileConfig, dir string) string {
|
|
|
+ return s._getIndexFile(rule, dir, "", IndexMaxDeep)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *HTTPServer) _getIndexFile(rule *rulescompile.RuleCompileConfig, baseDir string, nextDir string, deep int) string {
|
|
|
if deep == 0 {
|
|
|
return ""
|
|
|
}
|
|
@@ -102,24 +121,19 @@ func (s *HTTPServer) _getIndexFile(ruleIndex int, baseDir string, nextDir string
|
|
|
return ""
|
|
|
}
|
|
|
|
|
|
- lst, err := os.ReadDir(dir)
|
|
|
+ fileList, err := os.ReadDir(dir)
|
|
|
if err != nil {
|
|
|
return ""
|
|
|
}
|
|
|
|
|
|
var ignoreFileMap = make(map[string]bool, DefaultIgnoreFileMap)
|
|
|
-
|
|
|
- _, err = s.cfg.IgnoreFile.ForEach(ruleIndex, func(file *config.IgnoreFileCompile) (any, error) {
|
|
|
- for _, i := range lst {
|
|
|
- fileName := path.Join(nextDir, i.Name())
|
|
|
- if file.CheckName(fileName) {
|
|
|
+ for _, ignore := range rule.Dir.IgnoreFile {
|
|
|
+ for _, file := range fileList {
|
|
|
+ fileName := path.Join(nextDir, file.Name())
|
|
|
+ if ignore.CheckName(fileName) {
|
|
|
ignoreFileMap[fileName] = true
|
|
|
}
|
|
|
}
|
|
|
- return nil, nil
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return ""
|
|
|
}
|
|
|
|
|
|
var indexDirNum = -1
|
|
@@ -128,38 +142,34 @@ func (s *HTTPServer) _getIndexFile(ruleIndex int, baseDir string, nextDir string
|
|
|
var indexFileNum = -1
|
|
|
var indexFile os.DirEntry = nil
|
|
|
|
|
|
- _, err = s.cfg.IndexFile.ForEach(ruleIndex, func(file *config.IndexFileCompile) (any, error) {
|
|
|
- for _, i := range lst {
|
|
|
- fileName := path.Join(nextDir, i.Name())
|
|
|
+ for indexID, index := range rule.Dir.IndexFile {
|
|
|
+ for _, file := range fileList {
|
|
|
+ fileName := path.Join(nextDir, file.Name())
|
|
|
|
|
|
if _, ok := ignoreFileMap[fileName]; ok {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
- if file.CheckDirEntry(i) {
|
|
|
- if i.IsDir() {
|
|
|
- if indexDirNum == -1 || file.Index < indexDirNum {
|
|
|
- indexDirNum = file.Index
|
|
|
- indexDir = i
|
|
|
+ if index.CheckName(file.Name()) {
|
|
|
+ if file.IsDir() {
|
|
|
+ if indexDirNum == -1 || indexID < indexDirNum {
|
|
|
+ indexDirNum = indexID
|
|
|
+ indexDir = file
|
|
|
}
|
|
|
} else {
|
|
|
- if indexFileNum == -1 || file.Index < indexFileNum {
|
|
|
- indexFileNum = file.Index
|
|
|
- indexFile = i
|
|
|
+ if indexFileNum == -1 || indexID < indexFileNum {
|
|
|
+ indexFileNum = indexID
|
|
|
+ indexFile = file
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return nil, nil
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return ""
|
|
|
}
|
|
|
|
|
|
if indexFile != nil {
|
|
|
return path.Join(dir, indexFile.Name())
|
|
|
} else if indexDir != nil {
|
|
|
- return s._getIndexFile(ruleIndex, dir, indexDir.Name(), deep-1)
|
|
|
+ return s._getIndexFile(rule, dir, indexDir.Name(), deep-1)
|
|
|
} else {
|
|
|
return ""
|
|
|
}
|