mirror of
https://github.com/gospider007/requests.git
synced 2025-12-24 13:57:52 +08:00
sync
This commit is contained in:
3
conn.go
3
conn.go
@@ -8,7 +8,6 @@ import (
|
||||
"iter"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -110,7 +109,7 @@ type connecotr struct {
|
||||
|
||||
Conn Conn
|
||||
c net.Conn
|
||||
proxys []*url.URL
|
||||
proxys []Address
|
||||
}
|
||||
|
||||
func (obj *connecotr) withCancel(forceCtx context.Context, safeCtx context.Context) {
|
||||
|
||||
89
dial.go
89
dial.go
@@ -146,7 +146,7 @@ func (obj *Dialer) ProxyDialContext(ctx context.Context, ctxData *RequestOption,
|
||||
return obj.dialContext(ctx, ctxData, network, addr, true)
|
||||
}
|
||||
|
||||
func (obj *Dialer) DialProxyContext(ctx context.Context, ctxData *RequestOption, network string, proxyTlsConfig *tls.Config, proxyUrls ...*url.URL) (net.Conn, error) {
|
||||
func (obj *Dialer) DialProxyContext(ctx context.Context, ctxData *RequestOption, network string, proxyTlsConfig *tls.Config, proxyUrls ...Address) (net.Conn, error) {
|
||||
proxyLen := len(proxyUrls)
|
||||
if proxyLen < 2 {
|
||||
return nil, errors.New("proxyUrls is nil")
|
||||
@@ -166,41 +166,35 @@ func (obj *Dialer) DialProxyContext(ctx context.Context, ctxData *RequestOption,
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
func getProxyAddr(proxyUrl *url.URL) (addr string, err error) {
|
||||
if proxyUrl.Port() == "" {
|
||||
switch proxyUrl.Scheme {
|
||||
case "http":
|
||||
addr = net.JoinHostPort(proxyUrl.Hostname(), "80")
|
||||
case "https":
|
||||
addr = net.JoinHostPort(proxyUrl.Hostname(), "443")
|
||||
case "socks5":
|
||||
addr = net.JoinHostPort(proxyUrl.Hostname(), "1080")
|
||||
default:
|
||||
return "", errors.New("not support scheme")
|
||||
}
|
||||
} else {
|
||||
addr = net.JoinHostPort(proxyUrl.Hostname(), proxyUrl.Port())
|
||||
}
|
||||
return
|
||||
}
|
||||
func (obj *Dialer) dialProxyContext(ctx context.Context, ctxData *RequestOption, network string, proxyUrl *url.URL) (net.Conn, error) {
|
||||
if proxyUrl == nil {
|
||||
return nil, errors.New("proxyUrl is nil")
|
||||
}
|
||||
|
||||
// func getProxyAddr(proxyUrl *url.URL) (addr string, err error) {
|
||||
// if proxyUrl.Port() == "" {
|
||||
// switch proxyUrl.Scheme {
|
||||
// case "http":
|
||||
// addr = net.JoinHostPort(proxyUrl.Hostname(), "80")
|
||||
// case "https":
|
||||
// addr = net.JoinHostPort(proxyUrl.Hostname(), "443")
|
||||
// case "socks5":
|
||||
// addr = net.JoinHostPort(proxyUrl.Hostname(), "1080")
|
||||
// default:
|
||||
// return "", errors.New("not support scheme")
|
||||
// }
|
||||
// } else {
|
||||
// addr = net.JoinHostPort(proxyUrl.Hostname(), proxyUrl.Port())
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
func (obj *Dialer) dialProxyContext(ctx context.Context, ctxData *RequestOption, network string, proxyUrl Address) (net.Conn, error) {
|
||||
if ctxData == nil {
|
||||
ctxData = &RequestOption{}
|
||||
}
|
||||
addr, err := GetAddressWithUrl(proxyUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.ProxyDialContext(ctx, ctxData, network, addr)
|
||||
return obj.ProxyDialContext(ctx, ctxData, network, proxyUrl)
|
||||
}
|
||||
|
||||
func (obj *Dialer) verifyProxyToRemote(ctx context.Context, option *RequestOption, conn net.Conn, proxyTlsConfig *tls.Config, proxyUrl *url.URL, remoteUrl *url.URL) (net.Conn, error) {
|
||||
func (obj *Dialer) verifyProxyToRemote(ctx context.Context, option *RequestOption, conn net.Conn, proxyTlsConfig *tls.Config, proxyAddress Address, remoteAddress Address) (net.Conn, error) {
|
||||
var err error
|
||||
if proxyUrl.Scheme == "https" {
|
||||
if conn, err = obj.addTls(ctx, conn, proxyUrl.Host, true, proxyTlsConfig); err != nil {
|
||||
if proxyAddress.Scheme == "https" {
|
||||
if conn, err = obj.addTls(ctx, conn, proxyAddress.Host, true, proxyTlsConfig); err != nil {
|
||||
return conn, err
|
||||
}
|
||||
if option.Logger != nil {
|
||||
@@ -208,39 +202,31 @@ func (obj *Dialer) verifyProxyToRemote(ctx context.Context, option *RequestOptio
|
||||
Id: option.requestId,
|
||||
Time: time.Now(),
|
||||
Type: LogType_ProxyTLSHandshake,
|
||||
Msg: proxyUrl.String(),
|
||||
Msg: proxyAddress.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
switch proxyUrl.Scheme {
|
||||
switch proxyAddress.Scheme {
|
||||
case "http", "https":
|
||||
err = obj.clientVerifyHttps(ctx, conn, proxyUrl, remoteUrl)
|
||||
err = obj.clientVerifyHttps(ctx, conn, proxyAddress, remoteAddress)
|
||||
if option.Logger != nil {
|
||||
option.Logger(Log{
|
||||
Id: option.requestId,
|
||||
Time: time.Now(),
|
||||
Type: LogType_ProxyConnectRemote,
|
||||
Msg: remoteUrl.String(),
|
||||
Msg: remoteAddress.String(),
|
||||
})
|
||||
}
|
||||
case "socks5":
|
||||
var proxyAddress Address
|
||||
var remoteAddress Address
|
||||
if proxyAddress, err = GetAddressWithUrl(proxyUrl); err != nil {
|
||||
return
|
||||
}
|
||||
if remoteAddress, err = GetAddressWithUrl(remoteUrl); err != nil {
|
||||
return
|
||||
}
|
||||
err = obj.verifyTCPSocks5(conn, proxyAddress, remoteAddress)
|
||||
if option.Logger != nil {
|
||||
option.Logger(Log{
|
||||
Id: option.requestId,
|
||||
Time: time.Now(),
|
||||
Type: LogType_ProxyTCPConnect,
|
||||
Msg: remoteUrl.String(),
|
||||
Msg: remoteAddress.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -495,25 +481,18 @@ func (obj *Dialer) Socks5UdpProxy(ctx context.Context, ctxData *RequestOption, p
|
||||
return
|
||||
}
|
||||
}
|
||||
func (obj *Dialer) clientVerifyHttps(ctx context.Context, conn net.Conn, proxyUrl *url.URL, remoteUrl *url.URL) (err error) {
|
||||
func (obj *Dialer) clientVerifyHttps(ctx context.Context, conn net.Conn, proxyAddress Address, remoteAddress Address) (err error) {
|
||||
hdr := make(http.Header)
|
||||
hdr.Set("User-Agent", tools.UserAgent)
|
||||
if proxyUrl.User != nil {
|
||||
if password, ok := proxyUrl.User.Password(); ok {
|
||||
hdr.Set("Proxy-Authorization", "Basic "+tools.Base64Encode(proxyUrl.User.Username()+":"+password))
|
||||
}
|
||||
if proxyAddress.User != "" && proxyAddress.Password != "" {
|
||||
hdr.Set("Proxy-Authorization", "Basic "+tools.Base64Encode(proxyAddress.User+":"+proxyAddress.Password))
|
||||
}
|
||||
addr, err := getProxyAddr(remoteUrl)
|
||||
connectReq, err := NewRequestWithContext(ctx, http.MethodConnect, &url.URL{Opaque: remoteAddress.String()}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
connectReq, err := NewRequestWithContext(ctx, http.MethodConnect, &url.URL{Opaque: addr}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
connectReq.Header = hdr
|
||||
connectReq.Host = remoteUrl.Host
|
||||
connectReq.Host = remoteAddress.Host
|
||||
if err = connectReq.Write(conn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ func (obj *Response) IsNewConn() bool {
|
||||
}
|
||||
|
||||
// conn proxy
|
||||
func (obj *Response) Proxys() []*url.URL {
|
||||
func (obj *Response) Proxys() []Address {
|
||||
if obj.rawConn != nil {
|
||||
return obj.rawConn.Proxys()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"net/http"
|
||||
@@ -91,25 +90,20 @@ func (obj *roundTripper) newConnecotr() *connecotr {
|
||||
return conne
|
||||
}
|
||||
|
||||
func (obj *roundTripper) http3Dial(ctx context.Context, option *RequestOption, proxyUrl *url.URL, remtoeAddress Address) (udpConn net.PacketConn, err error) {
|
||||
if proxyUrl != nil {
|
||||
if proxyUrl.Scheme != "socks5" {
|
||||
func (obj *roundTripper) http3Dial(ctx context.Context, option *RequestOption, proxyAddress Address, remtoeAddress Address) (udpConn net.PacketConn, err error) {
|
||||
if !proxyAddress.Nil() {
|
||||
if proxyAddress.Scheme != "socks5" {
|
||||
err = errors.New("http3 only socks5 proxy supported")
|
||||
return
|
||||
}
|
||||
var proxyAddress Address
|
||||
proxyAddress, err = GetAddressWithUrl(proxyUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
udpConn, err = obj.dialer.Socks5UdpProxy(ctx, option, proxyAddress, remtoeAddress)
|
||||
} else {
|
||||
udpConn, err = net.ListenUDP("udp", nil)
|
||||
}
|
||||
return
|
||||
}
|
||||
func (obj *roundTripper) ghttp3Dial(ctx context.Context, option *RequestOption, proxyUrl *url.URL, remoteAddress Address) (conn *connecotr, err error) {
|
||||
udpConn, err := obj.http3Dial(ctx, option, proxyUrl, remoteAddress)
|
||||
func (obj *roundTripper) ghttp3Dial(ctx context.Context, option *RequestOption, proxyAddress Address, remoteAddress Address) (conn *connecotr, err error) {
|
||||
udpConn, err := obj.http3Dial(ctx, option, proxyAddress, remoteAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -130,8 +124,8 @@ func (obj *roundTripper) ghttp3Dial(ctx context.Context, option *RequestOption,
|
||||
return
|
||||
}
|
||||
|
||||
func (obj *roundTripper) uhttp3Dial(ctx context.Context, option *RequestOption, proxyUrl *url.URL, remoteAddress Address) (conn *connecotr, err error) {
|
||||
udpConn, err := obj.http3Dial(ctx, option, proxyUrl, remoteAddress)
|
||||
func (obj *roundTripper) uhttp3Dial(ctx context.Context, option *RequestOption, proxyAddress Address, remoteAddress Address) (conn *connecotr, err error) {
|
||||
udpConn, err := obj.http3Dial(ctx, option, proxyAddress, remoteAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -157,15 +151,15 @@ func (obj *roundTripper) dial(option *RequestOption, req *http.Request) (conn *c
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
remoteAddress, err := GetAddressWithUrl(req.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if option.H3 {
|
||||
var proxyUrl *url.URL
|
||||
var proxyUrl Address
|
||||
if len(proxys) > 0 {
|
||||
proxyUrl = proxys[0]
|
||||
}
|
||||
remoteAddress, err := GetAddressWithUrl(req.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if option.Ja3Spec.IsSet() {
|
||||
return obj.uhttp3Dial(req.Context(), option, proxyUrl, remoteAddress)
|
||||
} else {
|
||||
@@ -174,7 +168,7 @@ func (obj *roundTripper) dial(option *RequestOption, req *http.Request) (conn *c
|
||||
}
|
||||
var netConn net.Conn
|
||||
if len(proxys) > 0 {
|
||||
netConn, err = obj.dialer.DialProxyContext(req.Context(), option, "tcp", option.TlsConfig.Clone(), append(proxys, cloneUrl(req.URL))...)
|
||||
netConn, err = obj.dialer.DialProxyContext(req.Context(), option, "tcp", option.TlsConfig.Clone(), append(proxys, remoteAddress)...)
|
||||
} else {
|
||||
var remoteAddress Address
|
||||
remoteAddress, err = GetAddressWithUrl(req.URL)
|
||||
@@ -249,18 +243,26 @@ func (obj *roundTripper) dialAddTls(option *RequestOption, req *http.Request, ne
|
||||
}
|
||||
}
|
||||
}
|
||||
func (obj *roundTripper) initProxys(option *RequestOption, req *http.Request) ([]*url.URL, error) {
|
||||
var proxys []*url.URL
|
||||
func (obj *roundTripper) initProxys(option *RequestOption, req *http.Request) ([]Address, error) {
|
||||
var proxys []Address
|
||||
if option.DisProxy {
|
||||
return nil, nil
|
||||
}
|
||||
if option.proxy != nil {
|
||||
proxys = []*url.URL{cloneUrl(option.proxy)}
|
||||
proxyAddress, err := GetAddressWithUrl(option.proxy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxys = []Address{proxyAddress}
|
||||
}
|
||||
if len(proxys) == 0 && len(option.proxys) > 0 {
|
||||
proxys = make([]*url.URL, len(option.proxys))
|
||||
proxys = make([]Address, len(option.proxys))
|
||||
for i, proxy := range option.proxys {
|
||||
proxys[i] = cloneUrl(proxy)
|
||||
proxyAddress, err := GetAddressWithUrl(proxy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxys[i] = proxyAddress
|
||||
}
|
||||
}
|
||||
if len(proxys) == 0 && option.GetProxy != nil {
|
||||
@@ -273,7 +275,11 @@ func (obj *roundTripper) initProxys(option *RequestOption, req *http.Request) ([
|
||||
if err != nil {
|
||||
return proxys, err
|
||||
}
|
||||
proxys = []*url.URL{proxy}
|
||||
proxyAddress, err := GetAddressWithUrl(proxy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxys = []Address{proxyAddress}
|
||||
}
|
||||
}
|
||||
if len(proxys) == 0 && option.GetProxys != nil {
|
||||
@@ -282,13 +288,17 @@ func (obj *roundTripper) initProxys(option *RequestOption, req *http.Request) ([
|
||||
return proxys, err
|
||||
}
|
||||
if l := len(proxyStrs); l > 0 {
|
||||
proxys = make([]*url.URL, l)
|
||||
proxys = make([]Address, l)
|
||||
for i, proxyStr := range proxyStrs {
|
||||
proxy, err := gtls.VerifyProxy(proxyStr)
|
||||
if err != nil {
|
||||
return proxys, err
|
||||
}
|
||||
proxys[i] = proxy
|
||||
proxyAddress, err := GetAddressWithUrl(proxy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxys[i] = proxyAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
rw.go
9
rw.go
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type readWriteCloser struct {
|
||||
@@ -22,13 +21,7 @@ func (obj *readWriteCloser) Read(p []byte) (n int, err error) {
|
||||
}
|
||||
return i, err
|
||||
}
|
||||
func (obj *readWriteCloser) Proxys() []*url.URL {
|
||||
if l := len(obj.conn.proxys); l > 0 {
|
||||
proxys := make([]*url.URL, l)
|
||||
for i, proxy := range obj.conn.proxys {
|
||||
proxys[i] = cloneUrl(proxy)
|
||||
}
|
||||
}
|
||||
func (obj *readWriteCloser) Proxys() []Address {
|
||||
return obj.conn.proxys
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ type Address struct {
|
||||
IP net.IP
|
||||
Port int
|
||||
NetWork string
|
||||
Scheme string
|
||||
}
|
||||
|
||||
func (a Address) String() string {
|
||||
@@ -93,6 +94,9 @@ func (a Address) String() string {
|
||||
func (a Address) Network() string {
|
||||
return a.NetWork
|
||||
}
|
||||
func (a Address) Nil() bool {
|
||||
return a.IP == nil && a.Name == ""
|
||||
}
|
||||
|
||||
func ReadUdpAddr(r io.Reader) (Address, error) {
|
||||
UdpAddress := Address{}
|
||||
|
||||
22
tools.go
22
tools.go
@@ -57,32 +57,30 @@ func GetAddressWithUrl(uurl *url.URL) (addr Address, err error) {
|
||||
if uurl == nil {
|
||||
return Address{}, errors.New("url is nil")
|
||||
}
|
||||
var port int
|
||||
addr = Address{
|
||||
Name: uurl.Hostname(),
|
||||
Host: uurl.Host,
|
||||
}
|
||||
portStr := uurl.Port()
|
||||
addr.Scheme = uurl.Scheme
|
||||
if portStr == "" {
|
||||
switch uurl.Scheme {
|
||||
case "http":
|
||||
port = 80
|
||||
addr.Port = 80
|
||||
case "https":
|
||||
port = 443
|
||||
addr.Port = 443
|
||||
case "socks5":
|
||||
port = 1080
|
||||
addr.Port = 1080
|
||||
default:
|
||||
return Address{}, errors.New("unknown scheme")
|
||||
}
|
||||
} else {
|
||||
port, err = strconv.Atoi(portStr)
|
||||
addr.Port, err = strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return Address{}, err
|
||||
}
|
||||
}
|
||||
ip, _ := gtls.ParseHost(uurl.Hostname())
|
||||
addr = Address{
|
||||
Name: uurl.Hostname(),
|
||||
Host: uurl.Host,
|
||||
IP: ip,
|
||||
Port: port,
|
||||
}
|
||||
addr.IP, _ = gtls.ParseHost(uurl.Hostname())
|
||||
if uurl.User != nil {
|
||||
addr.User = uurl.User.Username()
|
||||
addr.Password, _ = uurl.User.Password()
|
||||
|
||||
Reference in New Issue
Block a user