diff --git a/common/convert/converter.go b/common/convert/converter.go index 809aa94fda..222dd9fa82 100644 --- a/common/convert/converter.go +++ b/common/convert/converter.go @@ -330,7 +330,7 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { vmess["h2-opts"] = h2Opts - case "ws": + case "ws", "httpupgrade": headers := make(map[string]any) wsOpts := make(map[string]any) wsOpts["path"] = []string{"/"} @@ -338,7 +338,30 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { headers["Host"] = host.(string) } if path, ok := values["path"]; ok && path != "" { - wsOpts["path"] = path.(string) + path := path.(string) + pathURL, err := url.Parse(path) + if err == nil { + query := pathURL.Query() + if earlyData := query.Get("ed"); earlyData != "" { + med, err := strconv.Atoi(earlyData) + if err == nil { + switch network { + case "ws": + wsOpts["max-early-data"] = med + wsOpts["early-data-header-name"] = "Sec-WebSocket-Protocol" + case "httpupgrade": + wsOpts["v2ray-http-upgrade-fast-open"] = true + } + query.Del("ed") + pathURL.RawQuery = query.Encode() + path = pathURL.String() + } + } + if earlyDataHeader := query.Get("eh"); earlyDataHeader != "" { + wsOpts["early-data-header-name"] = earlyDataHeader + } + } + wsOpts["path"] = path } wsOpts["headers"] = headers vmess["ws-opts"] = wsOpts diff --git a/common/convert/v.go b/common/convert/v.go index 2d8cf73209..4102ab75e4 100644 --- a/common/convert/v.go +++ b/common/convert/v.go @@ -100,7 +100,7 @@ func handleVShareLink(names map[string]int, url *url.URL, scheme string, proxy m h2Opts["headers"] = headers proxy["h2-opts"] = h2Opts - case "ws": + case "ws", "httpupgrade": headers := make(map[string]any) wsOpts := make(map[string]any) headers["User-Agent"] = RandUserAgent() @@ -113,7 +113,13 @@ func handleVShareLink(names map[string]int, url *url.URL, scheme string, proxy m if err != nil { return fmt.Errorf("bad WebSocket max early data size: %v", err) } - wsOpts["max-early-data"] = med + switch network { + case "ws": + wsOpts["max-early-data"] = med + wsOpts["early-data-header-name"] = "Sec-WebSocket-Protocol" + case "httpupgrade": + wsOpts["v2ray-http-upgrade-fast-open"] = true + } } if earlyDataHeader := query.Get("eh"); earlyDataHeader != "" { wsOpts["early-data-header-name"] = earlyDataHeader diff --git a/docs/config.yaml b/docs/config.yaml index 4d0e995e5d..6aa0686223 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -383,6 +383,7 @@ proxies: # socks5 # headers: # custom: value # v2ray-http-upgrade: false + # v2ray-http-upgrade-fast-open: false - name: "ss4-shadow-tls" type: ss @@ -461,6 +462,7 @@ proxies: # socks5 # max-early-data: 2048 # early-data-header-name: Sec-WebSocket-Protocol # v2ray-http-upgrade: false + # v2ray-http-upgrade-fast-open: false - name: "vmess-h2" type: vmess @@ -589,6 +591,7 @@ proxies: # socks5 headers: Host: example.com # v2ray-http-upgrade: false + # v2ray-http-upgrade-fast-open: false # Trojan - name: "trojan" @@ -633,6 +636,7 @@ proxies: # socks5 # headers: # Host: example.com # v2ray-http-upgrade: false + # v2ray-http-upgrade-fast-open: false - name: "trojan-xtls" type: trojan