github.com/yaling888/clash@v1.53.0/listener/mitm/client.go (about) 1 package mitm 2 3 import ( 4 "context" 5 "crypto/tls" 6 "net" 7 "net/http" 8 9 "github.com/yaling888/clash/adapter/inbound" 10 N "github.com/yaling888/clash/common/net" 11 C "github.com/yaling888/clash/constant" 12 "github.com/yaling888/clash/transport/socks5" 13 ) 14 15 func getServerConn(serverConn *N.BufferedConn, request *http.Request, srcAddr net.Addr, originTarget net.Addr, in chan<- C.ConnContext) (*N.BufferedConn, error) { 16 if serverConn != nil { 17 return serverConn, nil 18 } 19 20 address := request.URL.Host 21 if _, _, err := net.SplitHostPort(address); err != nil { 22 port := "80" 23 if request.TLS != nil { 24 port = "443" 25 } 26 address = net.JoinHostPort(address, port) 27 } 28 29 dstAddr := socks5.ParseAddr(address) 30 if dstAddr == nil { 31 return nil, socks5.ErrAddressNotSupported 32 } 33 34 specialProxy := request.Header.Get("Origin-Request-Special-Proxy") 35 request.Header.Del("Origin-Request-Special-Proxy") 36 37 left, right := net.Pipe() 38 39 in <- inbound.NewMitm(dstAddr, srcAddr, originTarget, request.Header.Get("User-Agent"), specialProxy, right) 40 41 if request.TLS != nil { 42 tlsConn := tls.Client(left, &tls.Config{ 43 ServerName: request.TLS.ServerName, 44 }) 45 46 ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) 47 defer cancel() 48 if err := tlsConn.HandshakeContext(ctx); err != nil { 49 return nil, err 50 } 51 52 serverConn = N.NewBufferedConn(tlsConn) 53 } else { 54 serverConn = N.NewBufferedConn(left) 55 } 56 57 return serverConn, nil 58 }