Compare commits

...

2 Commits

Author SHA1 Message Date
weeping af5f206bd8 fix socks5 proxy 2025-12-08 15:28:43 +08:00
weeping 5c6eb77b42 support IdleTimeout 2025-10-13 11:43:22 +08:00
4 changed files with 58 additions and 3 deletions
+7 -2
View File
@@ -94,6 +94,7 @@ type RuntimeObject struct {
IgnoreSSL *bool `json:"ignoreSSL" xml:"ignoreSSL"`
ReadTimeout *int `json:"readTimeout" xml:"readTimeout"`
ConnectTimeout *int `json:"connectTimeout" xml:"connectTimeout"`
IdleTimeout *int `json:"idleTimeout" xml:"idleTimeout"`
LocalAddr *string `json:"localAddr" xml:"localAddr"`
HttpProxy *string `json:"httpProxy" xml:"httpProxy"`
HttpsProxy *string `json:"httpsProxy" xml:"httpsProxy"`
@@ -114,7 +115,7 @@ type RuntimeObject struct {
func (r *RuntimeObject) getClientTag(domain string) string {
return strconv.FormatBool(BoolValue(r.IgnoreSSL)) + strconv.Itoa(IntValue(r.ReadTimeout)) +
strconv.Itoa(IntValue(r.ConnectTimeout)) + StringValue(r.LocalAddr) + StringValue(r.HttpProxy) +
strconv.Itoa(IntValue(r.ConnectTimeout)) + strconv.Itoa(IntValue(r.IdleTimeout)) + StringValue(r.LocalAddr) + StringValue(r.HttpProxy) +
StringValue(r.HttpsProxy) + StringValue(r.NoProxy) + StringValue(r.Socks5Proxy) + StringValue(r.Socks5NetWork) + domain
}
@@ -128,6 +129,7 @@ func NewRuntimeObject(runtime map[string]interface{}) *RuntimeObject {
IgnoreSSL: TransInterfaceToBool(runtime["ignoreSSL"]),
ReadTimeout: TransInterfaceToInt(runtime["readTimeout"]),
ConnectTimeout: TransInterfaceToInt(runtime["connectTimeout"]),
IdleTimeout: TransInterfaceToInt(runtime["idleTimeout"]),
LocalAddr: TransInterfaceToString(runtime["localAddr"]),
HttpProxy: TransInterfaceToString(runtime["httpProxy"]),
HttpsProxy: TransInterfaceToString(runtime["httpsProxy"]),
@@ -555,7 +557,7 @@ func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, er
Password: password,
}
}
dialer, err := proxy.SOCKS5(strings.ToLower(StringValue(runtime.Socks5NetWork)), socks5Proxy.String(), auth,
dialer, err := proxy.SOCKS5(strings.ToLower(StringValue(runtime.Socks5NetWork)), socks5Proxy.Host, auth,
&net.Dialer{
Timeout: time.Duration(IntValue(runtime.ConnectTimeout)) * time.Millisecond,
DualStack: true,
@@ -573,6 +575,9 @@ func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, er
trans.MaxIdleConns = IntValue(runtime.MaxIdleConns)
trans.MaxIdleConnsPerHost = IntValue(runtime.MaxIdleConns)
}
if runtime.IdleTimeout != nil && *runtime.IdleTimeout > 0 {
trans.IdleConnTimeout = time.Duration(IntValue(runtime.IdleTimeout)) * time.Millisecond
}
return trans, nil
}
+25
View File
@@ -732,12 +732,37 @@ func Test_DoRequest(t *testing.T) {
return mockResponse(200, ``, nil)
}
}
// Test socks5 proxy with user:password@host format
runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com"
runtimeObj["localAddr"] = "127.0.0.1"
resp, err = DoRequest(request, NewRuntimeObject(runtimeObj))
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy with explicit port
runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com:1080"
resp, err = DoRequest(request, NewRuntimeObject(runtimeObj))
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy without authentication
runtimeObj["socks5Proxy"] = "socks5://proxy.example.com:1080"
resp, err = DoRequest(request, NewRuntimeObject(runtimeObj))
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy with IPv6 address
runtimeObj["socks5Proxy"] = "socks5://[::1]:1080"
resp, err = DoRequest(request, NewRuntimeObject(runtimeObj))
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy with IPv6 and authentication
runtimeObj["socks5Proxy"] = "socks5://user:pass@[2001:db8::1]:1080"
resp, err = DoRequest(request, NewRuntimeObject(runtimeObj))
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
runtimeObj["key"] = "private rsa key"
runtimeObj["cert"] = "private certification"
runtimeObj["ca"] = "private ca"
+1 -1
View File
@@ -495,7 +495,7 @@ func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, er
Password: password,
}
}
dialer, err := proxy.SOCKS5(strings.ToLower(StringValue(runtime.Socks5NetWork)), socks5Proxy.String(), auth,
dialer, err := proxy.SOCKS5(strings.ToLower(StringValue(runtime.Socks5NetWork)), socks5Proxy.Host, auth,
&net.Dialer{
Timeout: time.Duration(IntValue(runtime.ConnectTimeout)) * time.Millisecond,
DualStack: true,
+25
View File
@@ -560,12 +560,37 @@ func Test_DoRequest(t *testing.T) {
return mockResponse(200, ``, nil)
}
}
// Test socks5 proxy with user:password@host format
runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com"
runtimeObj["localAddr"] = "127.0.0.1"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy with explicit port
runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com:1080"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy without authentication
runtimeObj["socks5Proxy"] = "socks5://proxy.example.com:1080"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy with IPv6 address
runtimeObj["socks5Proxy"] = "socks5://[::1]:1080"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
// Test socks5 proxy with IPv6 and authentication
runtimeObj["socks5Proxy"] = "socks5://user:pass@[2001:db8::1]:1080"
resp, err = DoRequest(request, runtimeObj)
utils.AssertNil(t, err)
utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"]))
runtimeObj["key"] = "private rsa key"
runtimeObj["cert"] = "private certification"
runtimeObj["ca"] = "private ca"