fix: replace sing-box with mihomo for egress probe (xhttp support)
mihomo (Clash Meta) natively supports xhttp and all Clash transports. Build minimal mihomo YAML config directly from the proxy node instead of converting to sing-box JSON format.
This commit is contained in:
@@ -17,9 +17,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/peterqiu0516/sub-store/internal/model"
|
||||
"github.com/peterqiu0516/sub-store/internal/render"
|
||||
"github.com/peterqiu0516/sub-store/internal/util"
|
||||
)
|
||||
|
||||
@@ -134,37 +134,35 @@ func buildEgressProbeConfig(node model.ProxyNode, port int) ([]byte, error) {
|
||||
}
|
||||
probeNode["name"] = "PROXY"
|
||||
|
||||
outbound := render.ToSingBoxOutbound(probeNode)
|
||||
if outbound == nil {
|
||||
return nil, fmt.Errorf("Unsupported proxy node for egress probe")
|
||||
// Build a minimal mihomo (Clash Meta) config with the probe node as the
|
||||
// only proxy. mihomo natively supports xhttp and other Clash transports.
|
||||
proxyYaml, err := yaml.Marshal(probeNode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal proxy node: %w", err)
|
||||
}
|
||||
doc := map[string]any{
|
||||
"log": map[string]any{"level": "warn"},
|
||||
"inbounds": []any{
|
||||
map[string]any{
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": port,
|
||||
},
|
||||
},
|
||||
"outbounds": []any{
|
||||
outbound,
|
||||
map[string]any{"type": "direct", "tag": "DIRECT"},
|
||||
},
|
||||
"route": map[string]any{
|
||||
"auto_detect_interface": true,
|
||||
"final": "PROXY",
|
||||
"rules": []any{map[string]any{"action": "sniff"}},
|
||||
},
|
||||
}
|
||||
return json.Marshal(doc)
|
||||
|
||||
config := fmt.Sprintf(`mixed-port: %d
|
||||
allow-lan: false
|
||||
mode: direct
|
||||
log-level: warning
|
||||
proxies:
|
||||
- %s
|
||||
proxy-groups:
|
||||
- name: PROXY
|
||||
type: select
|
||||
proxies:
|
||||
- PROXY
|
||||
rules:
|
||||
- MATCH,PROXY
|
||||
`, port, strings.ReplaceAll(strings.TrimSuffix(string(proxyYaml), "\n"), "\n", "\n "))
|
||||
|
||||
return []byte(config), nil
|
||||
}
|
||||
|
||||
func runEgressProbe(configData []byte, port int) (fiber.Map, error) {
|
||||
singBox, err := exec.LookPath("sing-box")
|
||||
mihomo, err := exec.LookPath("mihomo")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("sing-box executable not found")
|
||||
return nil, fmt.Errorf("mihomo executable not found")
|
||||
}
|
||||
dir, err := os.MkdirTemp("", "sub-store-egress-*")
|
||||
if err != nil {
|
||||
@@ -172,14 +170,14 @@ func runEgressProbe(configData []byte, port int) (fiber.Map, error) {
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
configPath := filepath.Join(dir, "config.json")
|
||||
configPath := filepath.Join(dir, "config.yaml")
|
||||
if err := os.WriteFile(configPath, configData, 0o600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, singBox, "run", "-c", configPath)
|
||||
cmd := exec.CommandContext(ctx, mihomo, "-f", configPath)
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stderr = &stderr
|
||||
if err := cmd.Start(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user