github.com/kelleygo/clashcore@v1.0.2/transport/v2ray-plugin/websocket.go (about) 1 package obfs 2 3 import ( 4 "context" 5 "crypto/tls" 6 "net" 7 "net/http" 8 9 "github.com/kelleygo/clashcore/component/ca" 10 "github.com/kelleygo/clashcore/transport/vmess" 11 ) 12 13 // Option is options of websocket obfs 14 type Option struct { 15 Host string 16 Port string 17 Path string 18 Headers map[string]string 19 TLS bool 20 SkipCertVerify bool 21 Fingerprint string 22 Mux bool 23 V2rayHttpUpgrade bool 24 V2rayHttpUpgradeFastOpen bool 25 } 26 27 // NewV2rayObfs return a HTTPObfs 28 func NewV2rayObfs(ctx context.Context, conn net.Conn, option *Option) (net.Conn, error) { 29 header := http.Header{} 30 for k, v := range option.Headers { 31 header.Add(k, v) 32 } 33 34 config := &vmess.WebsocketConfig{ 35 Host: option.Host, 36 Port: option.Port, 37 Path: option.Path, 38 V2rayHttpUpgrade: option.V2rayHttpUpgrade, 39 V2rayHttpUpgradeFastOpen: option.V2rayHttpUpgradeFastOpen, 40 Headers: header, 41 } 42 43 if option.TLS { 44 config.TLS = true 45 tlsConfig := &tls.Config{ 46 ServerName: option.Host, 47 InsecureSkipVerify: option.SkipCertVerify, 48 NextProtos: []string{"http/1.1"}, 49 } 50 var err error 51 config.TLSConfig, err = ca.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint) 52 if err != nil { 53 return nil, err 54 } 55 56 if host := config.Headers.Get("Host"); host != "" { 57 config.TLSConfig.ServerName = host 58 } 59 } 60 61 var err error 62 conn, err = vmess.StreamWebsocketConn(ctx, conn, config) 63 if err != nil { 64 return nil, err 65 } 66 67 if option.Mux { 68 conn = NewMux(conn, MuxOption{ 69 ID: [2]byte{0, 0}, 70 Host: "127.0.0.1", 71 Port: 0, 72 }) 73 } 74 return conn, nil 75 }