github.com/metacubex/mihomo@v1.18.5/listener/http/upgrade.go (about) 1 package http 2 3 import ( 4 "context" 5 "crypto/tls" 6 "net" 7 "net/http" 8 "strings" 9 10 "github.com/metacubex/mihomo/adapter/inbound" 11 N "github.com/metacubex/mihomo/common/net" 12 C "github.com/metacubex/mihomo/constant" 13 "github.com/metacubex/mihomo/transport/socks5" 14 ) 15 16 func isUpgradeRequest(req *http.Request) bool { 17 for _, header := range req.Header["Connection"] { 18 for _, elm := range strings.Split(header, ",") { 19 if strings.EqualFold(strings.TrimSpace(elm), "Upgrade") { 20 return true 21 } 22 } 23 } 24 25 return false 26 } 27 28 func handleUpgrade(conn net.Conn, request *http.Request, tunnel C.Tunnel, additions ...inbound.Addition) { 29 defer conn.Close() 30 31 removeProxyHeaders(request.Header) 32 removeExtraHTTPHostPort(request) 33 34 address := request.Host 35 if _, _, err := net.SplitHostPort(address); err != nil { 36 address = net.JoinHostPort(address, "80") 37 } 38 39 dstAddr := socks5.ParseAddr(address) 40 if dstAddr == nil { 41 return 42 } 43 44 left, right := N.Pipe() 45 46 go tunnel.HandleTCPConn(inbound.NewHTTP(dstAddr, conn, right, additions...)) 47 48 var bufferedLeft *N.BufferedConn 49 if request.TLS != nil { 50 tlsConn := tls.Client(left, &tls.Config{ 51 ServerName: request.URL.Hostname(), 52 }) 53 54 ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) 55 defer cancel() 56 if tlsConn.HandshakeContext(ctx) != nil { 57 _ = left.Close() 58 return 59 } 60 61 bufferedLeft = N.NewBufferedConn(tlsConn) 62 } else { 63 bufferedLeft = N.NewBufferedConn(left) 64 } 65 defer func() { 66 _ = bufferedLeft.Close() 67 }() 68 69 err := request.Write(bufferedLeft) 70 if err != nil { 71 return 72 } 73 74 resp, err := http.ReadResponse(bufferedLeft.Reader(), request) 75 if err != nil { 76 return 77 } 78 79 removeProxyHeaders(resp.Header) 80 81 err = resp.Write(conn) 82 if err != nil { 83 return 84 } 85 86 if resp.StatusCode == http.StatusSwitchingProtocols { 87 N.Relay(bufferedLeft, conn) 88 } 89 }