This commit is contained in:
2023-09-13 13:47:22 +08:00
parent 6e5e999937
commit 2c8e4f7b56
26 changed files with 508 additions and 196 deletions

View File

@ -1,36 +1,30 @@
package controller
import (
"net/http"
"strings"
"sub2clash/config"
"sub2clash/validator"
"github.com/gin-gonic/gin"
"gopkg.in/yaml.v3"
"net/http"
"sub2clash/config"
"sub2clash/validator"
)
func SubmodHandler(c *gin.Context) {
// 从请求中获取参数
var query validator.SubQuery
if err := c.ShouldBind(&query); err != nil {
c.String(http.StatusBadRequest, "参数错误: "+err.Error())
query, err := validator.ParseQuery(c)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
// 混合订阅和模板节点
sub, err := MixinSubsAndTemplate(
strings.Split(query.Sub, ","), query.Refresh, config.Default.ClashTemplate,
)
sub, err := BuildSub(query, config.Default.ClashTemplate)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
return
}
// 添加自定义节点、规则
// 输出
bytes, err := yaml.Marshal(sub)
marshal, err := yaml.Marshal(sub)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
c.String(http.StatusInternalServerError, "YAML序列化失败: "+err.Error())
return
}
c.String(http.StatusOK, string(bytes))
c.String(http.StatusOK, string(marshal))
}

View File

@ -1,42 +1,47 @@
package controller
import (
"crypto/md5"
"encoding/hex"
"errors"
"gopkg.in/yaml.v3"
"net/url"
"regexp"
"strings"
"sub2clash/model"
"sub2clash/parser"
"sub2clash/utils"
"sub2clash/validator"
)
func MixinSubsAndTemplate(subs []string, refresh bool, template string) (
func BuildSub(query validator.SubQuery, template string) (
*model.Subscription, error,
) {
// 定义变量
var externalTemplate = query.Template != ""
var temp *model.Subscription
var sub *model.Subscription
var err error
var templateBytes []byte
// 加载模板
template, err := utils.LoadTemplate(template)
if err != nil {
return nil, errors.New("加载模板失败: " + err.Error())
if !externalTemplate {
templateBytes, err = utils.LoadTemplate(template)
if err != nil {
return nil, errors.New("加载模板失败: " + err.Error())
}
} else {
templateBytes, err = utils.LoadSubscription(template, query.Refresh)
if err != nil {
return nil, errors.New("加载模板失败: " + err.Error())
}
}
// 解析模板
err = yaml.Unmarshal([]byte(template), &temp)
err = yaml.Unmarshal(templateBytes, &temp)
if err != nil {
return nil, errors.New("解析模板失败: " + err.Error())
}
var proxies []model.Proxy
// 加载订阅
for i := range subs {
subs[i], _ = url.QueryUnescape(subs[i])
if _, err := url.ParseRequestURI(subs[i]); err != nil {
return nil, errors.New("订阅地址错误: " + err.Error())
}
data, err := utils.LoadSubscription(
subs[i],
refresh,
)
for i := range query.Subs {
data, err := utils.LoadSubscription(query.Subs[i], query.Refresh)
if err != nil {
return nil, errors.New("加载订阅失败: " + err.Error())
}
@ -44,18 +49,52 @@ func MixinSubsAndTemplate(subs []string, refresh bool, template string) (
var proxyList []model.Proxy
err = yaml.Unmarshal(data, &sub)
if err != nil {
// 如果无法直接解析尝试Base64解码
base64, err := parser.DecodeBase64(string(data))
if err != nil {
return nil, errors.New("加载订阅失败: " + err.Error())
reg, _ := regexp.Compile("(ssr|ss|vmess|trojan|http|https)://")
if reg.Match(data) {
proxyList = utils.ParseProxy(strings.Split(string(data), "\n")...)
} else {
// 如果无法直接解析尝试Base64解码
base64, err := parser.DecodeBase64(string(data))
if err != nil {
return nil, errors.New("加载订阅失败: " + err.Error())
}
proxyList = utils.ParseProxy(strings.Split(base64, "\n")...)
}
proxyList = utils.ParseProxy(strings.Split(base64, "\n")...)
} else {
proxyList = sub.Proxies
}
proxies = append(proxies, proxyList...)
utils.AddProxy(temp, query.AutoTest, query.Lazy, proxyList...)
}
// 处理自定义代理
utils.AddProxy(temp, query.AutoTest, query.Lazy, utils.ParseProxy(query.Proxies...)...)
// 处理自定义规则
for _, v := range query.Rules {
if v.Prepend {
utils.PrependRules(temp, v.Rule)
} else {
utils.AppendRules(temp, v.Rule)
}
}
// 处理自定义 ruleProvider
for _, v := range query.RuleProviders {
hash := md5.Sum([]byte(v.Url))
name := hex.EncodeToString(hash[:])
provider := model.RuleProvider{
Type: "http",
Behavior: v.Behavior,
Url: v.Url,
Path: "./" + name + ".yaml",
Interval: 3600,
}
if v.Prepend {
utils.PrependRuleProvider(
temp, name, v.Group, provider,
)
} else {
utils.AppenddRuleProvider(
temp, name, v.Group, provider,
)
}
}
// 添加节点
utils.AddProxy(temp, proxies...)
return temp, nil
}

View File

@ -2,31 +2,25 @@ package controller
import (
_ "embed"
"net/http"
"strings"
"sub2clash/config"
"sub2clash/validator"
"github.com/gin-gonic/gin"
"gopkg.in/yaml.v3"
"net/http"
"sub2clash/config"
"sub2clash/validator"
)
func SubHandler(c *gin.Context) {
// 从请求中获取参数
var query validator.SubQuery
if err := c.ShouldBind(&query); err != nil {
c.String(http.StatusBadRequest, "参数错误: "+err.Error())
query, err := validator.ParseQuery(c)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
// 混合订阅和模板节点
sub, err := MixinSubsAndTemplate(
strings.Split(query.Sub, ","), query.Refresh, config.Default.MetaTemplate,
)
sub, err := BuildSub(query, config.Default.MetaTemplate)
if err != nil {
c.String(http.StatusInternalServerError, err.Error())
return
}
// 添加自定义节点、规则
// 输出
marshal, err := yaml.Marshal(sub)
if err != nil {