summaryrefslogtreecommitdiff
path: root/internal/engine/httpclient.go
diff options
context:
space:
mode:
authorsergei <sergei@em-sysadmin.xyz>2026-04-14 06:23:55 +0400
committersergei <sergei@em-sysadmin.xyz>2026-04-14 06:23:55 +0400
commit3d51aa455006903345f554a2dd90034993796114 (patch)
tree62a7be2faf047f5eb7886feebc3b815556f03d7f /internal/engine/httpclient.go
downloadvpnem-3d51aa455006903345f554a2dd90034993796114.tar.gz
vpnem-3d51aa455006903345f554a2dd90034993796114.tar.bz2
vpnem-3d51aa455006903345f554a2dd90034993796114.zip
vpnem: VPN infrastructure with load-balanced multi-protocol nodesHEADmain
- Multi-protocol VPS nodes (VLESS-REALITY + Hysteria2 + SOCKS5) - Smart load balancing via recommendation API - Windows/Linux client (Go + Wails + sing-box) - Server API with RealIP detection and connection tracking - Auto-deployment via vpnui control plane - Silent Windows installer with UAC elevation - Load-based server recommendation (no sticky sessions) - Best Server one-click connection workflow
Diffstat (limited to 'internal/engine/httpclient.go')
-rw-r--r--internal/engine/httpclient.go45
1 files changed, 45 insertions, 0 deletions
diff --git a/internal/engine/httpclient.go b/internal/engine/httpclient.go
new file mode 100644
index 0000000..e491cf5
--- /dev/null
+++ b/internal/engine/httpclient.go
@@ -0,0 +1,45 @@
+package engine
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/http"
+ "time"
+
+ "golang.org/x/net/proxy"
+)
+
+func HTTPClientViaSOCKS5(host string, port int, timeout time.Duration) (*http.Client, error) {
+ if host == "" || port <= 0 {
+ return nil, fmt.Errorf("invalid local socks5 endpoint")
+ }
+
+ addr := fmt.Sprintf("%s:%d", host, port)
+ dialer, err := proxy.SOCKS5("tcp", addr, nil, proxy.Direct)
+ if err != nil {
+ return nil, err
+ }
+
+ contextDialer, ok := dialer.(proxy.ContextDialer)
+ if !ok {
+ return nil, fmt.Errorf("socks5 dialer does not implement context dialing")
+ }
+
+ transport := &http.Transport{
+ DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
+ return contextDialer.DialContext(ctx, network, address)
+ },
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 10,
+ IdleConnTimeout: 30 * time.Second,
+ TLSHandshakeTimeout: timeout,
+ ResponseHeaderTimeout: timeout,
+ ExpectContinueTimeout: time.Second,
+ }
+
+ return &http.Client{
+ Timeout: timeout,
+ Transport: transport,
+ }, nil
+}