mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
Merge pull request #760 from kirileec/master
add a SetProxy function and a chaining function Proxy for ghttp.Clien…
This commit is contained in:
1
go.mod
1
go.mod
@ -15,6 +15,7 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.1
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
)
|
||||
|
||||
@ -135,3 +135,17 @@ func (c *Client) Retry(retryCount int, retryInterval time.Duration) *Client {
|
||||
newClient.SetRetry(retryCount, retryInterval)
|
||||
return c
|
||||
}
|
||||
|
||||
// Proxy is a chaining function,
|
||||
// which sets proxy for next request.
|
||||
// Make sure you pass the correct `proxyURL`.
|
||||
// The correct pattern is like `http://USER:PASSWORD@IP:PORT` or `socks5://USER:PASSWORD@IP:PORT`.
|
||||
// Only `http` and `socks5` proxies are supported currently.
|
||||
func (c *Client) Proxy(proxyURL string) *Client {
|
||||
newClient := c
|
||||
if c.parent == nil {
|
||||
newClient = c.Clone()
|
||||
}
|
||||
newClient.SetProxy(proxyURL)
|
||||
return c
|
||||
}
|
||||
|
||||
@ -10,7 +10,11 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"golang.org/x/net/proxy"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
@ -158,3 +162,54 @@ func (c *Client) SetRedirectLimit(redirectLimit int) *Client {
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// SetProxy set proxy for the client.
|
||||
// This func will do nothing when the parameter `proxyURL` is empty or in wrong pattern.
|
||||
// The correct pattern is like `http://USER:PASSWORD@IP:PORT` or `socks5://USER:PASSWORD@IP:PORT`.
|
||||
// Only `http` and `socks5` proxies are supported currently.
|
||||
func (c *Client) SetProxy(proxyURL string) {
|
||||
if strings.TrimSpace(proxyURL) == "" {
|
||||
return
|
||||
}
|
||||
_proxy, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _proxy.Scheme == "http" {
|
||||
if _, ok := c.Transport.(*http.Transport); ok {
|
||||
c.Transport.(*http.Transport).Proxy = http.ProxyURL(_proxy)
|
||||
}
|
||||
} else {
|
||||
var auth = &proxy.Auth{}
|
||||
user := _proxy.User.Username()
|
||||
|
||||
if user != "" {
|
||||
auth.User = user
|
||||
password, hasPassword := _proxy.User.Password()
|
||||
if hasPassword && password != "" {
|
||||
auth.Password = password
|
||||
}
|
||||
} else {
|
||||
auth = nil
|
||||
}
|
||||
// refer to the source code, error is always nil
|
||||
dialer, err := proxy.SOCKS5(
|
||||
"tcp",
|
||||
_proxy.Host,
|
||||
auth,
|
||||
&net.Dialer{
|
||||
Timeout: c.Client.Timeout,
|
||||
KeepAlive: c.Client.Timeout,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, ok := c.Transport.(*http.Transport); ok {
|
||||
c.Transport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (conn net.Conn, e error) {
|
||||
return dialer.Dial(network, addr)
|
||||
}
|
||||
}
|
||||
//c.SetTimeout(10*time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,8 +7,10 @@
|
||||
package ghttp_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/net/ghttp"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ExampleGetServer() {
|
||||
@ -27,3 +29,78 @@ func ExampleClientResponse_RawDump() {
|
||||
}
|
||||
response.RawDump()
|
||||
}
|
||||
|
||||
// ExampleClient_SetProxy a example for `ghttp.Client.SetProxy` method.
|
||||
// please prepare two proxy server before running this example.
|
||||
// http proxy server listening on `127.0.0.1:1081`
|
||||
// socks5 proxy server listening on `127.0.0.1:1080`
|
||||
func ExampleClient_SetProxy() {
|
||||
// connect to a http proxy server
|
||||
client := ghttp.NewClient()
|
||||
client.SetProxy("http://127.0.0.1:1081")
|
||||
client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout
|
||||
response, err := client.Get("https://api.ip.sb/ip")
|
||||
if err != nil {
|
||||
// err is not nil when your proxy server is down.
|
||||
// eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused
|
||||
fmt.Println(err)
|
||||
}
|
||||
response.RawDump()
|
||||
// connect to a http proxy server which needs auth
|
||||
client.SetProxy("http://user:password:127.0.0.1:1081")
|
||||
client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout
|
||||
response, err = client.Get("https://api.ip.sb/ip")
|
||||
if err != nil {
|
||||
// err is not nil when your proxy server is down.
|
||||
// eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused
|
||||
fmt.Println(err)
|
||||
}
|
||||
response.RawDump()
|
||||
|
||||
// connect to a socks5 proxy server
|
||||
client.SetProxy("socks5://127.0.0.1:1080")
|
||||
client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout
|
||||
response, err = client.Get("https://api.ip.sb/ip")
|
||||
if err != nil {
|
||||
// err is not nil when your proxy server is down.
|
||||
// eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(response.RawResponse())
|
||||
|
||||
// connect to a socks5 proxy server which needs auth
|
||||
client.SetProxy("socks5://user:password@127.0.0.1:1080")
|
||||
client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout
|
||||
response, err = client.Get("https://api.ip.sb/ip")
|
||||
if err != nil {
|
||||
// err is not nil when your proxy server is down.
|
||||
// eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(response.RawResponse())
|
||||
}
|
||||
|
||||
// ExampleClientChain_Proxy a chain version of example for `ghttp.Client.Proxy` method.
|
||||
// please prepare two proxy server before running this example.
|
||||
// http proxy server listening on `127.0.0.1:1081`
|
||||
// socks5 proxy server listening on `127.0.0.1:1080`
|
||||
// for more details, please refer to ExampleClient_SetProxy
|
||||
func ExampleClientChain_Proxy() {
|
||||
client := ghttp.NewClient()
|
||||
response, err := client.Proxy("http://127.0.0.1:1081").Get("https://api.ip.sb/ip")
|
||||
if err != nil {
|
||||
// err is not nil when your proxy server is down.
|
||||
// eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(response.RawResponse())
|
||||
|
||||
client2 := ghttp.NewClient()
|
||||
response, err = client2.Proxy("socks5://127.0.0.1:1080").Get("https://api.ip.sb/ip")
|
||||
if err != nil {
|
||||
// err is not nil when your proxy server is down.
|
||||
// eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println(response.RawResponse())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user