feat: 【frontend-gray】添加 skipedRoutes以及skipedByHeaders 配置 (#1409)

Co-authored-by: Kent Dong <ch3cho@qq.com>
This commit is contained in:
mamba
2024-10-23 09:34:00 +08:00
committed by GitHub
parent b8f5826a32
commit bb6c43c767
6 changed files with 101 additions and 45 deletions

View File

@@ -47,7 +47,39 @@ func GetRealIpFromXff(xff string) string {
return ""
}
func IsGrayEnabled(grayConfig config.GrayConfig) bool {
func IsRequestSkippedByHeaders(grayConfig config.GrayConfig) bool {
secFetchMode, _ := proxywasm.GetHttpRequestHeader("sec-fetch-mode")
upgrade, _ := proxywasm.GetHttpRequestHeader("upgrade")
if len(grayConfig.SkippedByHeaders) == 0 {
// 默认不走插件逻辑的header
return secFetchMode == "cors" || upgrade == "websocket"
}
for headerKey, headerValue := range grayConfig.SkippedByHeaders {
requestHeader, _ := proxywasm.GetHttpRequestHeader(headerKey)
if requestHeader == headerValue {
return true
}
}
return false
}
func IsGrayEnabled(grayConfig config.GrayConfig, requestPath string) bool {
// 当前路径中前缀为 SkipedRoute则不走插件逻辑
for _, prefix := range grayConfig.SkippedPathPrefixes {
if strings.HasPrefix(requestPath, prefix) {
return false
}
}
// 如果是首页,进入插件逻辑
if IsPageRequest(requestPath) {
return true
}
// 检查header标识判断是否需要跳过
if IsRequestSkippedByHeaders(grayConfig) {
return false
}
// 检查是否存在重写主机
if grayConfig.Rewrite != nil && grayConfig.Rewrite.Host != "" {
return true
@@ -132,29 +164,35 @@ var indexSuffixes = []string{
".html", ".htm", ".jsp", ".php", ".asp", ".aspx", ".erb", ".ejs", ".twig",
}
func IsPageRequest(fetchMode string, myPath string) bool {
if fetchMode == "cors" {
return false
func IsPageRequest(requestPath string) bool {
if requestPath == "/" || requestPath == "" {
return true
}
ext := path.Ext(myPath)
ext := path.Ext(requestPath)
return ext == "" || ContainsValue(indexSuffixes, ext)
}
// 首页Rewrite
func IndexRewrite(path, version string, matchRules map[string]string) string {
// Create a slice of keys in matchRules and sort them by length in descending order
// SortKeysByLengthAndLexicographically 按长度降序和字典序排序键
func SortKeysByLengthAndLexicographically(matchRules map[string]string) []string {
keys := make([]string, 0, len(matchRules))
for prefix := range matchRules {
keys = append(keys, prefix)
}
sort.Slice(keys, func(i, j int) bool {
if len(keys[i]) != len(keys[j]) {
return len(keys[i]) > len(keys[j]) // Sort by length
return len(keys[i]) > len(keys[j]) // 按长度排序
}
return keys[i] < keys[j] // Sort lexicographically
return keys[i] < keys[j] // 按字典序排序
})
return keys
}
// Iterate over sorted keys to find the longest match
// 首页Rewrite
func IndexRewrite(path, version string, matchRules map[string]string) string {
// 使用新的排序函数
keys := SortKeysByLengthAndLexicographically(matchRules)
// 遍历排序后的键以找到最长匹配
for _, prefix := range keys {
if strings.HasPrefix(path, prefix) {
rewrite := matchRules[prefix]
@@ -166,18 +204,21 @@ func IndexRewrite(path, version string, matchRules map[string]string) string {
}
func PrefixFileRewrite(path, version string, matchRules map[string]string) string {
var matchedPrefix, replacement string
for prefix, template := range matchRules {
// 对规则的键进行排序
sortedKeys := SortKeysByLengthAndLexicographically(matchRules)
// 遍历排序后的键
for _, prefix := range sortedKeys {
if strings.HasPrefix(path, prefix) {
if len(prefix) > len(matchedPrefix) { // 找到更长的前缀
matchedPrefix = prefix
replacement = strings.Replace(template, "{version}", version, 1)
}
// 找到第一个匹配的前缀就停止,因为它是最长的匹配
replacement := strings.Replace(matchRules[prefix], "{version}", version, 1)
newPath := strings.Replace(path, prefix, replacement+"/", 1)
return filepath.Clean(newPath)
}
}
// 将path 中的前缀部分用 replacement 替换掉
newPath := strings.Replace(path, matchedPrefix, replacement+"/", 1)
return filepath.Clean(newPath)
// 如果没有匹配,返回原始路径
return path
}
func GetVersion(grayConfig config.GrayConfig, deployment *config.Deployment, xPreHigressVersion string, isPageRequest bool) *config.Deployment {