Unverified Commit 7e34bb94 authored by luxiang's avatar luxiang
Browse files

fix(proxy): encode special chars in proxy credentials

parent f42c8f2a
package service package service
import ( import (
"fmt" "net"
"net/url"
"strconv"
"time" "time"
) )
...@@ -23,10 +25,14 @@ func (p *Proxy) IsActive() bool { ...@@ -23,10 +25,14 @@ func (p *Proxy) IsActive() bool {
} }
func (p *Proxy) URL() string { func (p *Proxy) URL() string {
u := &url.URL{
Scheme: p.Protocol,
Host: net.JoinHostPort(p.Host, strconv.Itoa(p.Port)),
}
if p.Username != "" && p.Password != "" { if p.Username != "" && p.Password != "" {
return fmt.Sprintf("%s://%s:%s@%s:%d", p.Protocol, p.Username, p.Password, p.Host, p.Port) u.User = url.UserPassword(p.Username, p.Password)
} }
return fmt.Sprintf("%s://%s:%d", p.Protocol, p.Host, p.Port) return u.String()
} }
type ProxyWithAccountCount struct { type ProxyWithAccountCount struct {
......
package service
import (
"net/url"
"testing"
)
func TestProxyURL(t *testing.T) {
t.Parallel()
tests := []struct {
name string
proxy Proxy
want string
}{
{
name: "without auth",
proxy: Proxy{
Protocol: "http",
Host: "proxy.example.com",
Port: 8080,
},
want: "http://proxy.example.com:8080",
},
{
name: "with auth",
proxy: Proxy{
Protocol: "socks5",
Host: "socks.example.com",
Port: 1080,
Username: "user",
Password: "pass",
},
want: "socks5://user:pass@socks.example.com:1080",
},
{
name: "username only keeps no auth for compatibility",
proxy: Proxy{
Protocol: "http",
Host: "proxy.example.com",
Port: 8080,
Username: "user-only",
},
want: "http://proxy.example.com:8080",
},
{
name: "with special characters in credentials",
proxy: Proxy{
Protocol: "http",
Host: "proxy.example.com",
Port: 3128,
Username: "first last@corp",
Password: "p@ ss:#word",
},
want: "http://first%20last%40corp:p%40%20ss%3A%23word@proxy.example.com:3128",
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
if got := tc.proxy.URL(); got != tc.want {
t.Fatalf("Proxy.URL() mismatch: got=%q want=%q", got, tc.want)
}
})
}
}
func TestProxyURL_SpecialCharactersRoundTrip(t *testing.T) {
t.Parallel()
proxy := Proxy{
Protocol: "http",
Host: "proxy.example.com",
Port: 3128,
Username: "first last@corp",
Password: "p@ ss:#word",
}
parsed, err := url.Parse(proxy.URL())
if err != nil {
t.Fatalf("parse proxy URL failed: %v", err)
}
if got := parsed.User.Username(); got != proxy.Username {
t.Fatalf("username mismatch after parse: got=%q want=%q", got, proxy.Username)
}
pass, ok := parsed.User.Password()
if !ok {
t.Fatal("password missing after parse")
}
if pass != proxy.Password {
t.Fatalf("password mismatch after parse: got=%q want=%q", pass, proxy.Password)
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment