add user-agent option for http/http2

This commit is contained in:
ginuerzh 2019-06-20 15:19:42 +08:00
parent bea815ec9a
commit e996e7c35b
6 changed files with 33 additions and 11 deletions

View File

@ -150,7 +150,8 @@ func (c *Chain) dialWithOptions(addr string, options *ChainOptions) (net.Conn, e
return nil, err return nil, err
} }
cc, err := route.LastNode().Client.Connect(conn, ipAddr, AddrConnectOption(addr)) cOpts := append([]ConnectOption{AddrConnectOption(addr)}, route.LastNode().ConnectOptions...)
cc, err := route.LastNode().Client.Connect(conn, ipAddr, cOpts...)
if err != nil { if err != nil {
conn.Close() conn.Close()
return nil, err return nil, err
@ -233,7 +234,7 @@ func (c *Chain) getConn() (conn net.Conn, err error) {
preNode := node preNode := node
for _, node := range nodes[1:] { for _, node := range nodes[1:] {
var cc net.Conn var cc net.Conn
cc, err = preNode.Client.Connect(cn, node.Addr) cc, err = preNode.Client.Connect(cn, node.Addr, preNode.ConnectOptions...)
if err != nil { if err != nil {
cn.Close() cn.Close()
node.MarkDead() node.MarkDead()

View File

@ -238,10 +238,11 @@ func QUICConfigHandshakeOption(config *QUICConfig) HandshakeOption {
// ConnectOptions describes the options for Connector.Connect. // ConnectOptions describes the options for Connector.Connect.
type ConnectOptions struct { type ConnectOptions struct {
Addr string Addr string
Timeout time.Duration Timeout time.Duration
User *url.Userinfo User *url.Userinfo
Selector gosocks5.Selector Selector gosocks5.Selector
UserAgent string
} }
// ConnectOption allows a common way to set ConnectOptions. // ConnectOption allows a common way to set ConnectOptions.
@ -274,3 +275,10 @@ func SelectorConnectOption(s gosocks5.Selector) ConnectOption {
opts.Selector = s opts.Selector = s
} }
} }
// UserAgentConnectOption specifies the HTTP user-agent header.
func UserAgentConnectOption(ua string) ConnectOption {
return func(opts *ConnectOptions) {
opts.UserAgent = ua
}
}

View File

@ -209,6 +209,10 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
gost.TimeoutDialOption(time.Duration(timeout)*time.Second), gost.TimeoutDialOption(time.Duration(timeout)*time.Second),
) )
node.ConnectOptions = []gost.ConnectOption{
gost.UserAgentConnectOption(node.Get("agent")),
}
if host == "" { if host == "" {
host = node.Host host = node.Host
} }

View File

@ -37,6 +37,10 @@ func (c *httpConnector) Connect(conn net.Conn, addr string, options ...ConnectOp
if timeout <= 0 { if timeout <= 0 {
timeout = ConnectTimeout timeout = ConnectTimeout
} }
ua := opts.UserAgent
if ua == "" {
ua = DefaultUserAgent
}
conn.SetDeadline(time.Now().Add(timeout)) conn.SetDeadline(time.Now().Add(timeout))
defer conn.SetDeadline(time.Time{}) defer conn.SetDeadline(time.Time{})
@ -49,7 +53,7 @@ func (c *httpConnector) Connect(conn net.Conn, addr string, options ...ConnectOp
ProtoMinor: 1, ProtoMinor: 1,
Header: make(http.Header), Header: make(http.Header),
} }
req.Header.Set("User-Agent", DefaultUserAgent) req.Header.Set("User-Agent", ua)
req.Header.Set("Proxy-Connection", "keep-alive") req.Header.Set("Proxy-Connection", "keep-alive")
user := opts.User user := opts.User

View File

@ -38,6 +38,10 @@ func (c *http2Connector) Connect(conn net.Conn, addr string, options ...ConnectO
for _, option := range options { for _, option := range options {
option(opts) option(opts)
} }
ua := opts.UserAgent
if ua == "" {
ua = DefaultUserAgent
}
cc, ok := conn.(*http2ClientConn) cc, ok := conn.(*http2ClientConn)
if !ok { if !ok {
@ -56,8 +60,7 @@ func (c *http2Connector) Connect(conn net.Conn, addr string, options ...ConnectO
Host: addr, Host: addr,
ContentLength: -1, ContentLength: -1,
} }
// DEPRECATED req.Header.Set("User-Agent", ua)
//req.Header.Set("Gost-Target", addr)
user := opts.User user := opts.User
if user == nil { if user == nil {

View File

@ -28,6 +28,7 @@ type Node struct {
Values url.Values Values url.Values
DialOptions []DialOption DialOptions []DialOption
HandshakeOptions []HandshakeOption HandshakeOptions []HandshakeOption
ConnectOptions []ConnectOption
Client *Client Client *Client
marker *failMarker marker *failMarker
Bypass *Bypass Bypass *Bypass
@ -129,18 +130,19 @@ func (node *Node) Get(key string) string {
return node.Values.Get(key) return node.Values.Get(key)
} }
// GetBool likes Get, but convert parameter value to bool. // GetBool converts node parameter value to bool.
func (node *Node) GetBool(key string) bool { func (node *Node) GetBool(key string) bool {
b, _ := strconv.ParseBool(node.Values.Get(key)) b, _ := strconv.ParseBool(node.Values.Get(key))
return b return b
} }
// GetInt likes Get, but convert parameter value to int. // GetInt converts node parameter value to int.
func (node *Node) GetInt(key string) int { func (node *Node) GetInt(key string) int {
n, _ := strconv.Atoi(node.Values.Get(key)) n, _ := strconv.Atoi(node.Values.Get(key))
return n return n
} }
// GetDuration converts node parameter value to time.Duration.
func (node *Node) GetDuration(key string) time.Duration { func (node *Node) GetDuration(key string) time.Duration {
d, _ := time.ParseDuration(node.Values.Get(key)) d, _ := time.ParseDuration(node.Values.Get(key))
return d return d