From fdb7cb1f580dffc510ee52b0ebcae3ac53200118 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Wed, 3 Dec 2025 00:05:09 +0800 Subject: [PATCH] chore: allow setting DialerForAPI in adapter.ParseProxy for library user --- adapter/outbound/reject.go | 1 + adapter/parser.go | 65 ++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/adapter/outbound/reject.go b/adapter/outbound/reject.go index 9e0bb022..97bcdd5a 100644 --- a/adapter/outbound/reject.go +++ b/adapter/outbound/reject.go @@ -17,6 +17,7 @@ type Reject struct { } type RejectOption struct { + BasicOption Name string `proxy:"name"` } diff --git a/adapter/parser.go b/adapter/parser.go index af93ebf4..0ad45ca9 100644 --- a/adapter/parser.go +++ b/adapter/parser.go @@ -8,146 +8,151 @@ import ( C "github.com/metacubex/mihomo/constant" ) -func ParseProxy(mapping map[string]any) (C.Proxy, error) { +func ParseProxy(mapping map[string]any, options ...ProxyOption) (C.Proxy, error) { decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true, KeyReplacer: structure.DefaultKeyReplacer}) proxyType, existType := mapping["type"].(string) if !existType { return nil, fmt.Errorf("missing type") } + opt := applyProxyOptions(options...) + basicOption := outbound.BasicOption{ + DialerForAPI: opt.DialerForAPI, + } + var ( proxy outbound.ProxyAdapter err error ) switch proxyType { case "ss": - ssOption := &outbound.ShadowSocksOption{} + ssOption := &outbound.ShadowSocksOption{BasicOption: basicOption} err = decoder.Decode(mapping, ssOption) if err != nil { break } proxy, err = outbound.NewShadowSocks(*ssOption) case "ssr": - ssrOption := &outbound.ShadowSocksROption{} + ssrOption := &outbound.ShadowSocksROption{BasicOption: basicOption} err = decoder.Decode(mapping, ssrOption) if err != nil { break } proxy, err = outbound.NewShadowSocksR(*ssrOption) case "socks5": - socksOption := &outbound.Socks5Option{} + socksOption := &outbound.Socks5Option{BasicOption: basicOption} err = decoder.Decode(mapping, socksOption) if err != nil { break } proxy, err = outbound.NewSocks5(*socksOption) case "http": - httpOption := &outbound.HttpOption{} + httpOption := &outbound.HttpOption{BasicOption: basicOption} err = decoder.Decode(mapping, httpOption) if err != nil { break } proxy, err = outbound.NewHttp(*httpOption) case "vmess": - vmessOption := &outbound.VmessOption{} + vmessOption := &outbound.VmessOption{BasicOption: basicOption} err = decoder.Decode(mapping, vmessOption) if err != nil { break } proxy, err = outbound.NewVmess(*vmessOption) case "vless": - vlessOption := &outbound.VlessOption{} + vlessOption := &outbound.VlessOption{BasicOption: basicOption} err = decoder.Decode(mapping, vlessOption) if err != nil { break } proxy, err = outbound.NewVless(*vlessOption) case "snell": - snellOption := &outbound.SnellOption{} + snellOption := &outbound.SnellOption{BasicOption: basicOption} err = decoder.Decode(mapping, snellOption) if err != nil { break } proxy, err = outbound.NewSnell(*snellOption) case "trojan": - trojanOption := &outbound.TrojanOption{} + trojanOption := &outbound.TrojanOption{BasicOption: basicOption} err = decoder.Decode(mapping, trojanOption) if err != nil { break } proxy, err = outbound.NewTrojan(*trojanOption) case "hysteria": - hyOption := &outbound.HysteriaOption{} + hyOption := &outbound.HysteriaOption{BasicOption: basicOption} err = decoder.Decode(mapping, hyOption) if err != nil { break } proxy, err = outbound.NewHysteria(*hyOption) case "hysteria2": - hyOption := &outbound.Hysteria2Option{} + hyOption := &outbound.Hysteria2Option{BasicOption: basicOption} err = decoder.Decode(mapping, hyOption) if err != nil { break } proxy, err = outbound.NewHysteria2(*hyOption) case "wireguard": - wgOption := &outbound.WireGuardOption{} + wgOption := &outbound.WireGuardOption{BasicOption: basicOption} err = decoder.Decode(mapping, wgOption) if err != nil { break } proxy, err = outbound.NewWireGuard(*wgOption) case "tuic": - tuicOption := &outbound.TuicOption{} + tuicOption := &outbound.TuicOption{BasicOption: basicOption} err = decoder.Decode(mapping, tuicOption) if err != nil { break } proxy, err = outbound.NewTuic(*tuicOption) case "direct": - directOption := &outbound.DirectOption{} + directOption := &outbound.DirectOption{BasicOption: basicOption} err = decoder.Decode(mapping, directOption) if err != nil { break } proxy = outbound.NewDirectWithOption(*directOption) case "dns": - dnsOptions := &outbound.DnsOption{} + dnsOptions := &outbound.DnsOption{BasicOption: basicOption} err = decoder.Decode(mapping, dnsOptions) if err != nil { break } proxy = outbound.NewDnsWithOption(*dnsOptions) case "reject": - rejectOption := &outbound.RejectOption{} + rejectOption := &outbound.RejectOption{BasicOption: basicOption} err = decoder.Decode(mapping, rejectOption) if err != nil { break } proxy = outbound.NewRejectWithOption(*rejectOption) case "ssh": - sshOption := &outbound.SshOption{} + sshOption := &outbound.SshOption{BasicOption: basicOption} err = decoder.Decode(mapping, sshOption) if err != nil { break } proxy, err = outbound.NewSsh(*sshOption) case "mieru": - mieruOption := &outbound.MieruOption{} + mieruOption := &outbound.MieruOption{BasicOption: basicOption} err = decoder.Decode(mapping, mieruOption) if err != nil { break } proxy, err = outbound.NewMieru(*mieruOption) case "anytls": - anytlsOption := &outbound.AnyTLSOption{} + anytlsOption := &outbound.AnyTLSOption{BasicOption: basicOption} err = decoder.Decode(mapping, anytlsOption) if err != nil { break } proxy, err = outbound.NewAnyTLS(*anytlsOption) case "sudoku": - sudokuOption := &outbound.SudokuOption{} + sudokuOption := &outbound.SudokuOption{BasicOption: basicOption} err = decoder.Decode(mapping, sudokuOption) if err != nil { break @@ -178,3 +183,23 @@ func ParseProxy(mapping map[string]any) (C.Proxy, error) { proxy = outbound.NewAutoCloseProxyAdapter(proxy) return NewProxy(proxy), nil } + +type proxyOption struct { + DialerForAPI C.Dialer +} + +func applyProxyOptions(options ...ProxyOption) proxyOption { + opt := proxyOption{} + for _, o := range options { + o(&opt) + } + return opt +} + +type ProxyOption func(opt *proxyOption) + +func WithDialerForAPI(dialer C.Dialer) ProxyOption { + return func(opt *proxyOption) { + opt.DialerForAPI = dialer + } +}