@@ -15,40 +15,44 @@ import (
15
15
"os"
16
16
"strings"
17
17
"sync"
18
- "time"
19
18
)
20
19
21
20
type ProxyConfig struct {
22
21
proxyURL * url.URL
22
+ isDirect bool // Indicates if this is a direct connection
23
23
}
24
24
25
25
type ProxyManager struct {
26
26
proxies []* ProxyConfig
27
27
currentIdx int
28
28
mu sync.Mutex
29
29
enableEdge bool
30
- lastUsed time.Time
31
30
}
32
31
33
32
func NewProxyManager (enableEdge bool ) * ProxyManager {
34
- return & ProxyManager {
33
+ pm := & ProxyManager {
35
34
proxies : make ([]* ProxyConfig , 0 ),
36
35
enableEdge : enableEdge ,
37
- lastUsed : time .Now (),
38
36
}
37
+
38
+ // If edge mode is enabled, add direct connection as first proxy
39
+ if enableEdge {
40
+ pm .proxies = append (pm .proxies , & ProxyConfig {isDirect : true })
41
+ }
42
+
43
+ return pm
39
44
}
40
45
41
46
func (pm * ProxyManager ) LoadProxies (filename string ) error {
42
47
file , err := os .Open (filename )
43
48
if err != nil {
44
49
if pm .enableEdge {
50
+ // If edge mode is enabled and no proxy file, that's okay - we still have direct
45
51
return nil
46
52
}
47
53
return err
48
54
}
49
- defer func (file * os.File ) {
50
- _ = file .Close ()
51
- }(file )
55
+ defer file .Close ()
52
56
53
57
scanner := bufio .NewScanner (file )
54
58
for scanner .Scan () {
@@ -62,7 +66,10 @@ func (pm *ProxyManager) LoadProxies(filename string) error {
62
66
return fmt .Errorf ("invalid proxy URL: %s" , err )
63
67
}
64
68
65
- pm .proxies = append (pm .proxies , & ProxyConfig {proxyURL : proxyURL })
69
+ pm .proxies = append (pm .proxies , & ProxyConfig {
70
+ proxyURL : proxyURL ,
71
+ isDirect : false ,
72
+ })
66
73
}
67
74
68
75
if err := scanner .Err (); err != nil {
@@ -84,73 +91,29 @@ func (pm *ProxyManager) GetNextProxy() (*ProxyConfig, error) {
84
91
return nil , fmt .Errorf ("no proxies available" )
85
92
}
86
93
87
- // Always increment the index
88
94
proxy := pm .proxies [pm .currentIdx ]
89
95
pm .currentIdx = (pm .currentIdx + 1 ) % len (pm .proxies )
90
96
91
- // Update last used time
92
- pm .lastUsed = time .Now ()
93
-
94
97
return proxy , nil
95
98
}
96
99
97
- func (pm * ProxyManager ) ShouldUseDirect () bool {
98
- pm .mu .Lock ()
99
- defer pm .mu .Unlock ()
100
-
101
- if ! pm .enableEdge {
102
- return false
103
- }
104
-
105
- // If we have no proxies, always use direct
106
- if len (pm .proxies ) == 0 {
107
- return true
108
- }
109
-
110
- // In edge mode with proxies, use direct connection periodically
111
- // This ensures we rotate through direct connection as well
112
- return time .Since (pm .lastUsed ) > 5 * time .Second
113
- }
114
-
115
100
type ProxyDialer struct {
116
101
manager * ProxyManager
117
102
}
118
103
119
104
func (d * ProxyDialer ) Dial (ctx context.Context , network , addr string ) (net.Conn , error ) {
120
- var lastError error
121
-
122
- // Check if we should try direct connection first
123
- if d .manager .ShouldUseDirect () {
124
- conn , err := net .Dial (network , addr )
125
- if err == nil {
126
- return conn , nil
127
- }
128
- lastError = err
105
+ proxy , err := d .manager .GetNextProxy ()
106
+ if err != nil {
107
+ return nil , err
129
108
}
130
109
131
- // If we have proxies, try them
132
- if len (d .manager .proxies ) > 0 {
133
- proxy , err := d .manager .GetNextProxy ()
134
- if err != nil {
135
- if lastError != nil {
136
- return nil , fmt .Errorf ("direct connection failed: %v, proxy error: %v" , lastError , err )
137
- }
138
- return nil , err
139
- }
140
-
141
- conn , err := d .dialWithProxy (proxy , network , addr )
142
- if err == nil {
143
- return conn , nil
144
- }
145
- lastError = err
146
- } else if ! d .manager .enableEdge {
147
- return nil , fmt .Errorf ("no proxies available and edge mode is disabled" )
110
+ // Handle direct connection
111
+ if proxy .isDirect {
112
+ return net .Dial (network , addr )
148
113
}
149
114
150
- if lastError != nil {
151
- return nil , fmt .Errorf ("all connection attempts failed, last error: %v" , lastError )
152
- }
153
- return nil , fmt .Errorf ("no connection methods available" )
115
+ // Handle proxy connection
116
+ return d .dialWithProxy (proxy , network , addr )
154
117
}
155
118
156
119
func (d * ProxyDialer ) dialWithProxy (proxy * ProxyConfig , network , addr string ) (net.Conn , error ) {
0 commit comments